gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog gui/Player.cpp gui/gui.cpp gui/...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog gui/Player.cpp gui/gui.cpp gui/...
Date: Wed, 06 Dec 2006 10:21:33 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  06/12/06 10:21:33

Modified files:
        .              : ChangeLog 
        gui            : Player.cpp gui.cpp gui.h 
        server         : Makefile.am button_character_instance.cpp 
                         character.cpp character.h 
                         edit_text_character.cpp impl.cpp impl.h 
                         movie_instance.cpp movie_instance.h 
                         movie_root.cpp movie_root.h sprite_instance.cpp 
                         sprite_instance.h 
        server/asobj   : Key.cpp 
        server/parser  : movie_def_impl.cpp movie_def_impl.h 
                         movie_definition.h 
        server/vm      : ASHandlers.cpp VM.cpp VM.h action.cpp 
        testsuite      : MovieTester.cpp 
        testsuite/server: Makefile.am PropertyListTest.cpp 
        utilities      : processor.cpp 
Added files:
        server         : drag_state.h 
        testsuite      : DummyMovieDefinition.h 

Log message:
                * server/Makefile.am, server/drag_state.h, gui/Player.cpp,
                  gui/gui.cpp, gui/gui.h, server/button_character_instance.cpp,
                  server/character.cpp, server/character.h,
                  server/edit_text_character.cpp, server/impl.cpp, 
server/impl.h,
                  server/movie_instance.cpp, server/movie_instance.h,
                  server/movie_root.cpp, server/movie_root.h,
                  server/sprite_instance.cpp, server/sprite_instance.h,
                  server/asobj/Key.cpp, server/parser/movie_def_impl.cpp,
                  server/parser/movie_def_impl.h,
                  server/parser/movie_definition.h,
                  server/vm/ASHandlers.cpp, server/vm/VM.cpp, server/vm/VM.h,
                  server/vm/action.cpp, utilities/processor.cpp:
                  Redesigned movie_root so that it doesn't derive from 
sprite_instance
                  anymore, but it is rather a wrapper around the *single* 
*absolute*
                  root movie for a specific run. Changed VM to return that 
single
                  movie_root by ref using the getRoot() method;
                  Sorry if this changelog is too short, but was a lot of work, 
and
                  tried my best at keeping doxygen comments in sync.
                  Also, note that invalidated bounds seems broken now,
                  movie_root::get_invalidated_bounds() always return the WORLD 
rect
                  as a quick fix, but we have to fix that.
                * testsuite/MovieTester.cpp, 
testsuite/server/PropertyListTest.cpp,
                  testsuite/server/Makefile.am, 
testsuite/DummyMovieDefinition.h:
                  Added a dummy movie definition for use in unit tests,
                  PropertyListTest still fails because we handle case 
sensitiveness
                  in as_object, not in PropertyList..

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.1865&r2=1.1866
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/Player.cpp?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gui.cpp?cvsroot=gnash&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gui.h?cvsroot=gnash&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.95&r2=1.96
http://cvs.savannah.gnu.org/viewcvs/gnash/server/button_character_instance.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.cpp?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/gnash/server/edit_text_character.cpp?cvsroot=gnash&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.cpp?cvsroot=gnash&r1=1.83&r2=1.84
http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.h?cvsroot=gnash&r1=1.40&r2=1.41
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_instance.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_instance.h?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.30&r2=1.31
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.94&r2=1.95
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/gnash/server/drag_state.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Key.cpp?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_def_impl.cpp?cvsroot=gnash&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_def_impl.h?cvsroot=gnash&r1=1.26&r2=1.27
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/movie_definition.h?cvsroot=gnash&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/ASHandlers.cpp?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.h?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/action.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/MovieTester.cpp?cvsroot=gnash&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/DummyMovieDefinition.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/server/Makefile.am?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/server/PropertyListTest.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/processor.cpp?cvsroot=gnash&r1=1.40&r2=1.41

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.1865
retrieving revision 1.1866
diff -u -b -r1.1865 -r1.1866
--- ChangeLog   6 Dec 2006 09:30:40 -0000       1.1865
+++ ChangeLog   6 Dec 2006 10:21:32 -0000       1.1866
@@ -1,11 +1,42 @@
 2006-12-06 Sandro Santilli <address@hidden>
 
+       * server/Makefile.am, server/drag_state.h, gui/Player.cpp,
+         gui/gui.cpp, gui/gui.h, server/button_character_instance.cpp,
+         server/character.cpp, server/character.h,
+         server/edit_text_character.cpp, server/impl.cpp, server/impl.h,
+         server/movie_instance.cpp, server/movie_instance.h,
+         server/movie_root.cpp, server/movie_root.h,
+         server/sprite_instance.cpp, server/sprite_instance.h,
+         server/asobj/Key.cpp, server/parser/movie_def_impl.cpp,
+         server/parser/movie_def_impl.h,
+         server/parser/movie_definition.h,
+         server/vm/ASHandlers.cpp, server/vm/VM.cpp, server/vm/VM.h,
+         server/vm/action.cpp, utilities/processor.cpp:
+         Redesigned movie_root so that it doesn't derive from sprite_instance
+         anymore, but it is rather a wrapper around the *single* *absolute*
+         root movie for a specific run. Changed VM to return that single
+         movie_root by ref using the getRoot() method; 
+         Sorry if this changelog is too short, but was a lot of work, and
+         tried my best at keeping doxygen comments in sync.
+         Also, note that invalidated bounds seems broken now,
+         movie_root::get_invalidated_bounds() always return the WORLD rect
+         as a quick fix, but we have to fix that.
+       * testsuite/MovieTester.cpp, testsuite/server/PropertyListTest.cpp, 
+         testsuite/server/Makefile.am, testsuite/DummyMovieDefinition.h:
+         Added a dummy movie definition for use in unit tests,
+         PropertyListTest still fails because we handle case sensitiveness
+         in as_object, not in PropertyList..
+
+
+2006-12-06 Sandro Santilli <address@hidden>
+
        * server/movie_root.h (get_invalidated_bounds): use rect::set_world()
          rather then using a custom value for big bounds.
        * testsuite/MovieTester.{cpp,h}: add getInvalidatedBounds function.
        * libgeometry/Range2d.h (Intersect): removed spurious code.
        * server/rect.h: added getRange() method.
 
+
 2006-12-05 Sandro Santilli <address@hidden>
 
        * server/rect.cpp (expand_to_rect): handled world rects.

Index: gui/Player.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/Player.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- gui/Player.cpp      28 Nov 2006 16:53:26 -0000      1.35
+++ gui/Player.cpp      6 Dec 2006 10:21:32 -0000       1.36
@@ -309,9 +309,8 @@
     // Now that we know about movie size, create gui window.
     _gui->createWindow(infile, width, height);
 
-    gnash::sprite_instance* m = VM::init(*_movie_def).getRoot();
-    //gnash::sprite_instance *m = create_library_movie_inst(_movie_def);
-    assert(m);
+    movie_root& root = VM::init(*_movie_def).getRoot();
+    sprite_instance* m = root.get_root_movie();
 
     // Start loader thread
     _movie_def->completeLoad();
@@ -333,12 +332,8 @@
     }
 
 
-    assert(m == VM::get().getRoot());
-
-    movie_root* root = dynamic_cast<movie_root*>(m);
-    assert(root);
-    root->set_display_viewport(0, 0, width, height);
-    root->set_background_alpha(background ? 1.0f : 0.05f);
+    root.set_display_viewport(0, 0, width, height);
+    root.set_background_alpha(background ? 1.0f : 0.05f);
 
     if (!delay) {
       delay = (unsigned int) (1000 / movie_fps) ; // milliseconds per frame

Index: gui/gui.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gui.cpp,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- gui/gui.cpp 2 Dec 2006 21:03:50 -0000       1.52
+++ gui/gui.cpp 6 Dec 2006 10:21:32 -0000       1.53
@@ -35,7 +35,7 @@
 /// In the future, enabling this might actually use a runtime flag
 /// as an additional conditional.
 ///
-//#define ENABLE_REGION_UPDATES_DEBUGGING 1
+#define ENABLE_REGION_UPDATES_DEBUGGING 1
 
 #ifdef ENABLE_REGION_UPDATES_DEBUGGING
 // a runtime check would make the { x; } block conditionally executed
@@ -100,17 +100,14 @@
        if ( VM::isInitialized() )
        {
 
-               sprite_instance* m_sp = VM::get().getRoot();
-
-               movie_root* m = dynamic_cast<movie_root*>(m_sp);
-               assert(m);
+               movie_root& m = VM::get().getRoot();
 
+               movie_definition* md = m.get_movie_definition();
 
-               movie_definition* md = m->get_movie_definition();
                float swfwidth = md->get_width_pixels();
                float swfheight = md->get_height_pixels();
 
-               m->set_display_viewport(0, 0, width, height);
+               m.set_display_viewport(0, 0, width, height);
 
                // set new scale value
                _xscale = width / swfwidth;
@@ -159,7 +156,7 @@
 {
 //    GNASH_REPORT_FUNCTION;
 
-    sprite_instance* m = get_current_root();
+    movie_root* m = get_current_root();
     if (m->get_play_state() == gnash::sprite_instance::STOP) {
       m->set_play_state(gnash::sprite_instance::PLAY);
     } else {
@@ -179,7 +176,7 @@
 Gui::menu_step_forward()
 {
 //    GNASH_REPORT_FUNCTION;
-    sprite_instance* m = get_current_root();
+       movie_root* m = get_current_root();
     m->goto_frame(m->get_current_frame()+1);
 }
 
@@ -187,7 +184,8 @@
 Gui::menu_step_backward()
 {
 //    GNASH_REPORT_FUNCTION;
-    sprite_instance* m = get_current_root();
+
+       movie_root* m = get_current_root();
     m->goto_frame(m->get_current_frame()-1);
 }
 
@@ -195,7 +193,8 @@
 Gui::menu_jump_forward()
 {
 //    GNASH_REPORT_FUNCTION;
-    sprite_instance* m = get_current_root();
+
+       movie_root* m = get_current_root();
     m->goto_frame(m->get_current_frame()+10);
 }
 
@@ -203,15 +202,15 @@
 Gui::menu_jump_backward()
 {
 //    GNASH_REPORT_FUNCTION;
-    sprite_instance* m = get_current_root();
+
+       movie_root* m = get_current_root();
     m->goto_frame(m->get_current_frame()-10);
 }
 
 void
 Gui::notify_mouse_moved(int x, int y) 
 {
-       movie_root* m = dynamic_cast<movie_root*>(get_current_root());
-       assert(m);
+       movie_root* m = get_current_root();
 
        if ( m->notify_mouse_moved(x, y) )
        {
@@ -231,7 +230,7 @@
 void
 Gui::notify_mouse_clicked(bool mouse_pressed, int mask) 
 {
-       movie_root* m = dynamic_cast<movie_root*>(get_current_root());
+       movie_root* m = get_current_root();
        assert(m);
 
        if ( m->notify_mouse_clicked(mouse_pressed, mask) )
@@ -243,8 +242,9 @@
 }
 
 bool
-Gui::display(gnash::sprite_instance* m)
+Gui::display(movie_root* m)
 {
+
        rect changed_bounds;  // area of the stage that must be updated 
        bool redraw_flag;
 
@@ -258,18 +258,19 @@
        // have been updated. This just checks what region of the stage has 
changed
        // due to ActionScript code, the timeline or user events. The GUI can 
still
   // choose to render a different part of the stage. 
+       //
+       // TODO: is it needed to call get_invalidated_bounds even when 
redraw_flag is true ??
+       //
        m->get_invalidated_bounds(&changed_bounds, false);
 
        if (redraw_flag)     // TODO: Remove this and want_redraw to avoid 
confusion!?
        {
-               // TODO: use more meaningful ordinate values ?
-               changed_bounds = rect(-1e10f, -1e10f, +1e10f, +1e10f);
+               changed_bounds.set_world();
        }
   
-  
        // Avoid drawing of stopped movies
 
-       if ( ! changed_bounds.is_null() )
+       if ( ! changed_bounds.is_null() ) // use 'else'?
        {
                // Tell the GUI(!) that we only need to update this region. 
Note the GUI can
                // do whatever it wants with this information. It may simply 
ignore the 
@@ -286,6 +287,8 @@
                // show invalidated region using a red rectangle
                // (Flash debug style)
                IF_DEBUG_REGION_UPDATES (
+               if ( ! changed_bounds.is_world() )
+               {
                        point corners[4];
                        float xmin = changed_bounds.get_x_min();
                        float xmax = changed_bounds.get_x_max();
@@ -304,6 +307,7 @@
                        gnash::render::set_matrix(dummy); // reset matrix
                        gnash::render::draw_poly(&corners[0], 4,
                                rgba(0,0,0,0), rgba(255,0,0,255));
+               }
                );
 
                // show frame on screen
@@ -321,7 +325,7 @@
   
 //     GNASH_REPORT_FUNCTION;
 
-       gnash::sprite_instance* m = gnash::get_current_root();
+       gnash::movie_root* m = gnash::get_current_root();
 
        // Advance movie by one frame
        m->advance(1.0);

Index: gui/gui.h
===================================================================
RCS file: /sources/gnash/gnash/gui/gui.h,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- gui/gui.h   2 Dec 2006 21:03:50 -0000       1.39
+++ gui/gui.h   6 Dec 2006 10:21:32 -0000       1.40
@@ -33,7 +33,7 @@
 namespace gnash
 {
        class render_handler;
-       class sprite_instance;
+       class movie_root;
 }
 
 namespace gnash
@@ -230,7 +230,7 @@
 
 private:
 
-    bool display(gnash::sprite_instance* m);
+    bool display(movie_root* m);
 
 };
 

Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.95
retrieving revision 1.96
diff -u -b -r1.95 -r1.96
--- server/Makefile.am  5 Dec 2006 14:26:09 -0000       1.95
+++ server/Makefile.am  6 Dec 2006 10:21:32 -0000       1.96
@@ -18,7 +18,7 @@
 # 
 #
 
-# $Id: Makefile.am,v 1.95 2006/12/05 14:26:09 tgc Exp $
+# $Id: Makefile.am,v 1.96 2006/12/06 10:21:32 strk Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -102,6 +102,7 @@
        button_character_instance.h \
        character.h \
        dlist.h \
+       drag_state.h \
        edit_text_character.h \
        event_id.h \
        execute_tag.h \

Index: server/button_character_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/button_character_instance.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/button_character_instance.cpp        28 Nov 2006 15:59:30 -0000      
1.19
+++ server/button_character_instance.cpp        6 Dec 2006 10:21:32 -0000       
1.20
@@ -5,6 +5,10 @@
 
 // SWF buttons.  Mouse-sensitive update/display, actions, etc.
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 
 #include "button_character_instance.h"
 #include "button_character_def.h"
@@ -13,6 +17,7 @@
 #include "ActionExec.h"
 #include "sprite_instance.h"
 #include "movie_root.h"
+#include "VM.h"
 
 /** \page buttons Buttons and mouse behaviour
 
@@ -178,7 +183,7 @@
        {
                if (m_def->m_button_actions[i].m_conditions & 0xFE00)   // 
check up on CondKeyPress: UB[7]
                {
-                       get_root()->add_keypress_listener(this);
+                       _vm.getRoot().add_keypress_listener(this);
                        break;
                }
        }
@@ -187,7 +192,7 @@
 
 button_character_instance::~button_character_instance()
 {
-       get_root()->remove_keypress_listener(this);
+       _vm.getRoot().remove_keypress_listener(this);
 }
 
 // called from keypress listener only

Index: server/character.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/character.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- server/character.cpp        28 Nov 2006 16:20:27 -0000      1.12
+++ server/character.cpp        6 Dec 2006 10:21:32 -0000       1.13
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: character.cpp,v 1.12 2006/11/28 16:20:27 strk Exp $ */
+/* $Id: character.cpp,v 1.13 2006/12/06 10:21:32 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -26,15 +26,18 @@
 
 #include "character.h"
 #include "sprite_instance.h"
+#include "drag_state.h" // for do_mouse_drag (to be moved in movie_root)
+#include "VM.h" // for do_mouse_drag (to be moved in movie_root)
 
 namespace gnash
 {
 
+// TODO: this should likely go in movie_root instead !
 void
 character::do_mouse_drag()
 {
        drag_state st;
-       get_drag_state(st);
+       _vm.getRoot().get_drag_state(st);
        if ( this == st.getCharacter() )
        {
                // We're being dragged!
@@ -110,14 +113,6 @@
        return m;
 }
 
-void
-character::get_drag_state(drag_state& st)
-{
-       assert(m_parent != NULL);
-       assert(m_parent->get_ref_count() > 0);
-       m_parent->get_drag_state(st);
-}
-
 sprite_instance*
 character::get_root_movie()
 {

Index: server/character.h
===================================================================
RCS file: /sources/gnash/gnash/server/character.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- server/character.h  28 Nov 2006 16:20:27 -0000      1.31
+++ server/character.h  6 Dec 2006 10:21:32 -0000       1.32
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: character.h,v 1.31 2006/11/28 16:20:27 strk Exp $ */
+/* $Id: character.h,v 1.32 2006/12/06 10:21:32 strk Exp $ */
 
 #ifndef GNASH_CHARACTER_H
 #define GNASH_CHARACTER_H
@@ -43,11 +43,13 @@
 #include <cassert>
 #include <typeinfo>
 
+// Forward declarations
 namespace gnash {
+       class sprite_instance;
+       class movie_instance;
+}
 
-// Forward declarations
-class sprite_instance;
-class movie_root;
+namespace gnash {
 
 /// Character is a live, stateful instance of a character_def.
 //
@@ -61,90 +63,6 @@
 
        typedef std::map<event_id, as_value> Events;
 
-       class drag_state
-       {
-
-               bool _hasbounds;
-
-               /// Boundaries to constraint the drag into.
-               /// Coordinates in TWIPS.
-               rect _bounds;
-
-               boost::intrusive_ptr<character> _character;
-
-               bool    _lock_centered;
-
-       public:
-
-               bool isLockCentered() const {
-                       return _lock_centered;
-               }
-
-               void setLockCentered(bool lock) {
-                       _lock_centered = lock;
-               }
-
-               bool hasBounds() const {
-                       return _hasbounds;
-               }
-
-               /// \brief
-               /// Get the boundaries to constraint
-               /// the drag into.
-               //
-               /// Coordinates of the rectangle are
-               /// expected in TWIPS.
-               ///
-               /// Note that if hasBounds() is false
-               /// the returned rectangle is the NULL
-               /// rectangle - see rect::is_null().
-               ///
-               const rect& getBounds() const {
-                       return _bounds;
-               }
-
-               /// \brief
-               /// Set the boundaries to constraint
-               /// the drag into.
-               //
-               /// Coordinates of the rectangle are
-               /// expected in TWIPS.
-               ///
-               void setBounds(const rect& bounds) {
-                       _bounds = bounds;
-                       _hasbounds = true;
-               }
-
-               /// May return NULL !!
-               character* getCharacter() {
-                       return _character.get();
-               }
-
-               /// Stores character in an intrusive pointer
-               void setCharacter(character* ch) {
-                       _character = ch;
-               }
-
-               /// Reset drag state to its initial condition
-               void reset()
-               {
-                       _character = NULL;
-                       _hasbounds = false;
-                       _bounds.set_null();
-                       _lock_centered = false;
-               }
-
-               drag_state()
-                       :
-                       _hasbounds(false),
-                       _bounds(),
-                       _character(0),
-                       _lock_centered(false)
-               {
-               }
-       };
-
-
 private:
 
        int             m_id;
@@ -176,7 +94,7 @@
        character* get_relative_target_common(const std::string& name);
 
        /// \brief
-       /// Set when the visual aspect this particular character or movie
+       /// Set when the visual aspect of this particular character or movie
        /// has been changed and redrawing is necessary.  
        bool m_invalidated;
 
@@ -203,6 +121,7 @@
        {
            assert((parent == NULL && m_id == -1)
                   || (parent != NULL && m_id >= 0));
+           assert(m_old_invalidated_bounds.is_null());
        }
 
        /// Return a reference to the variable scope of this character.
@@ -322,9 +241,22 @@
                return 0;
        }
 
+       /// Return the "relative" root of this character
+       //
+       /// The "relative" is the movie_instance created by
+       /// the same SWF definition that contained the
+       /// definition of this character.
+       ///
+       /// TODO: what about programmatically created characters ?
+       ///       which would their "relative" root be ?
+       ///
+       /// The default implementation is to invoke get_root_movie
+       /// against this character's parent.
+       ///
        virtual sprite_instance* get_root_movie();
 
-       virtual movie_root* get_root() {
+       /// By default call get_root on the parent
+       virtual movie_instance* get_root() {
                return get_parent()->get_root();
        }
 
@@ -364,12 +296,6 @@
 
     virtual bool       get_accept_anim_moves() const { return true; }
 
-       /// The default implementation calls get_drag_state against
-       /// the character's parent. The final parent (a sprite_instance)
-       /// will delegate the call to it's associated movie_root, which
-       /// does all the work.
-       virtual void    get_drag_state(drag_state& st);
-
     virtual void       set_visible(bool visible) {
       if (m_visible!=visible) set_invalidated();  
       m_visible = visible;      

Index: server/edit_text_character.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/edit_text_character.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- server/edit_text_character.cpp      30 Nov 2006 13:43:26 -0000      1.38
+++ server/edit_text_character.cpp      6 Dec 2006 10:21:32 -0000       1.39
@@ -15,7 +15,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 
-/* $Id: edit_text_character.cpp,v 1.38 2006/11/30 13:43:26 strk Exp $ */
+/* $Id: edit_text_character.cpp,v 1.39 2006/12/06 10:21:32 strk Exp $ */
 
 #include "utf8.h"
 #include "log.h"
@@ -271,7 +271,7 @@
                {
                        if (m_has_focus == false)
                        {
-                               get_root()->add_keypress_listener(this);
+                               _vm.getRoot().add_keypress_listener(this);
                                m_has_focus = true;
                                m_cursor = _text.size();
                                format_text();
@@ -283,8 +283,9 @@
                {
                        if (m_has_focus == true)
                        {
-                               get_root()->set_active_entity(NULL);
-                               get_root()->remove_keypress_listener(this);
+                               movie_root& root = _vm.getRoot();
+                               root.set_active_entity(NULL);
+                               root.remove_keypress_listener(this);
                                m_has_focus = false;
                                format_text();
                        }

Index: server/impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/impl.cpp,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -b -r1.83 -r1.84
--- server/impl.cpp     28 Nov 2006 12:30:42 -0000      1.83
+++ server/impl.cpp     6 Dec 2006 10:21:32 -0000       1.84
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: impl.cpp,v 1.83 2006/11/28 12:30:42 strk Exp $ */
+/* $Id: impl.cpp,v 1.84 2006/12/06 10:21:32 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -586,9 +586,6 @@
 static hash< movie_definition*, boost::intrusive_ptr<sprite_instance> >        
s_movie_library_inst;
 static std::vector<sprite_instance*> s_extern_sprites;
 
-// FIXME: use a smart pointer here
-static sprite_instance* s_current_root;
-
 static std::string s_workdir;
 
 void save_extern_movie(sprite_instance* m)
@@ -615,32 +612,10 @@
 }
 //#endif // 0
 
-sprite_instance* get_current_root()
-{
-//    assert(s_current_root != NULL);
-       return VM::get().getRoot();
-}
-
-// Obsoleted !
-void set_current_root(sprite_instance* m)
+movie_root*
+get_current_root()
 {
-       log_error("set_current_root is obsolete! Use 
VM::init(movie_definition&) instead");
-       assert(0);
-
-    assert(m != NULL);
-
-    // We don't want to change root, do we ?
-    // The rationale is that the "root" movie
-    // drives the whole runtime environment, as
-    // it dictates the "target" compatibility
-    // version.
-    // When this whole crap will be cleaned up
-    // (ie: allow multiple run environment rather
-    // then polluting the global namespace) we
-    // will have better experiences in this reguard.
-    assert(s_current_root == NULL);
-
-    s_current_root = m;
+       return &(VM::get().getRoot());
 }
 
 const char* get_workdir()

Index: server/impl.h
===================================================================
RCS file: /sources/gnash/gnash/server/impl.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -b -r1.40 -r1.41
--- server/impl.h       28 Nov 2006 12:30:42 -0000      1.40
+++ server/impl.h       6 Dec 2006 10:21:32 -0000       1.41
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: impl.h,v 1.40 2006/11/28 12:30:42 strk Exp $ */
+/* $Id: impl.h,v 1.41 2006/12/06 10:21:32 strk Exp $ */
 
 #ifndef GNASH_IMPL_H
 #define GNASH_IMPL_H
@@ -66,10 +66,10 @@
 
 // for extern movies
 
+// TODO: return movie_instance !
 DSOEXPORT sprite_instance *create_library_movie_inst(movie_definition* md);
 
-DSOEXPORT sprite_instance *get_current_root();
-DSOEXPORT void set_current_root(sprite_instance* m);
+DSOEXPORT movie_root* get_current_root();
 DSOEXPORT const char* get_workdir();
 DSOEXPORT void set_workdir(const char* dir);
 DSOEXPORT void delete_unused_root();

Index: server/movie_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_instance.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/movie_instance.cpp   1 Dec 2006 10:22:58 -0000       1.6
+++ server/movie_instance.cpp   6 Dec 2006 10:21:32 -0000       1.7
@@ -28,14 +28,10 @@
 #include <pthread.h>
 #endif
 
-//#include "action.h" 
-//#include "gnash.h"
 #include "movie_instance.h"
 #include "movie_definition.h"
-#include "movie_def_impl.h"
 #include "movie_root.h"
 #include "tu_random.h"
-//#include "log.h" 
 
 #include <vector>
 #include <string>
@@ -48,10 +44,9 @@
 
 namespace gnash {
 
-movie_instance::movie_instance(movie_def_impl* def,
-               movie_root* r, character* parent)
+movie_instance::movie_instance(movie_definition* def, character* parent)
        :
-       sprite_instance(def, r, parent, -1),
+       sprite_instance(def, this, parent, -1),
        _def(def)
 {
 }

Index: server/movie_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_instance.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/movie_instance.h     29 Oct 2006 18:34:11 -0000      1.2
+++ server/movie_instance.h     6 Dec 2006 10:21:32 -0000       1.3
@@ -30,6 +30,8 @@
 #include <vector>
 
 #include "sprite_instance.h" // for inheritance
+#include "smart_ptr.h" // for composition
+#include "movie_definition.h" // for dtor visibility by smart ptr
 
 // Forward declarations
 namespace gnash {
@@ -47,16 +49,29 @@
 
 public:
 
-       movie_instance(movie_def_impl* def,
-               movie_root* r, character* parent);
+       // We take a generic movie_definition to allow
+       // for subclasses for other then SWF movies
+       movie_instance(movie_definition* def, character* parent);
 
        virtual ~movie_instance() {}
 
        virtual void advance(float delta_time);
 
+       // Could be implemented in sprite_instance too,
+       // returning m_root like it is done for get_root_movie...
+       virtual movie_instance* get_root()
+       {
+               return this;
+       }
+
+       //virtual sprite_instance* get_root_movie()
+       //{
+               //return this;
+       //}
+
 private:
 
-       movie_def_impl* _def;
+       boost::intrusive_ptr<movie_definition> _def;
 };
 
 

Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -b -r1.30 -r1.31
--- server/movie_root.cpp       29 Nov 2006 08:23:44 -0000      1.30
+++ server/movie_root.cpp       6 Dec 2006 10:21:32 -0000       1.31
@@ -26,7 +26,9 @@
 #include "movie_root.h"
 #include "log.h"
 #include "sprite_instance.h"
+#include "movie_instance.h" // for implicit upcast to sprite_instance
 #include "render.h"
+#include "VM.h"
 
 #include <cassert>
 
@@ -43,16 +45,14 @@
 movie_root::testInvariant() const
 {
        // TODO: fill this function !
-       assert(m_def);
+       assert(_movie.get());
 
        return true;
 }
 
 
-movie_root::movie_root(movie_def_impl* def)
+movie_root::movie_root()
        :
-       sprite_instance(def, this, NULL, -1),
-       //m_def(def),
        m_viewport_x0(0),
        m_viewport_y0(0),
        m_viewport_width(1),
@@ -64,7 +64,6 @@
        m_mouse_y(0),
        m_mouse_buttons(0),
        m_userdata(NULL),
-//     m_on_event_load_called(false),
        m_on_event_xmlsocket_ondata_called(false),
        m_on_event_xmlsocket_onxml_called(false),
        m_on_event_load_progress_called(false),
@@ -72,33 +71,29 @@
        m_time_remainder(0.0f),
        m_drag_state()
 {
-       assert(m_def != NULL);
-       
-       m_invalidated=true;
-
-       set_display_viewport(0, 0,
-               (int) m_def->get_width_pixels(),
-               (int) m_def->get_height_pixels());
-
-       assert(testInvariant());
 }
 
 movie_root::~movie_root()
 {
        assert(testInvariant());
-    assert(m_def != NULL);
-    m_movie = NULL;
-    m_def = NULL;
 }
 
-               
 void
-movie_root::set_root_movie(sprite_instance* root_movie)
+movie_root::setRootMovie(movie_instance* movie)
 {
-       m_movie = root_movie;
+       assert(movie != NULL);
+       _movie = movie;
+
+       _movie->set_invalidated();
+       
+       set_display_viewport(0, 0,
+               (int) _movie->get_movie_definition()->get_width_pixels(),
+               (int) _movie->get_movie_definition()->get_height_pixels());
+
        assert(testInvariant());
 }
 
+               
 void
 movie_root::set_display_viewport(int x0, int y0, int w, int h)
 {
@@ -109,8 +104,10 @@
     m_viewport_width = w;
     m_viewport_height = h;
 
+    // should we cache this ? it's immutable after all !
+    const rect& frame_size = _movie->get_frame_size();
+
     // Recompute pixel scale.
-    const rect& frame_size = m_def->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());
@@ -281,9 +278,8 @@
                        // onPress
 
                        // set/kill focus for current root
-                       movie_root* mroot = static_cast<movie_root*>( 
get_current_root() );
-                       assert(mroot);
-                       character* current_active_entity = 
mroot->get_active_entity();
+                       movie_root& mroot = VM::get().getRoot();
+                       character* current_active_entity = 
mroot.get_active_entity();
 
                        // It's another entity ?
                        if (current_active_entity != active_entity.get())
@@ -296,7 +292,7 @@
                                        //       wheter the action must trigger
                                        //       a redraw.
                                        need_redisplay=true;
-                                       mroot->set_active_entity(NULL);
+                                       mroot.set_active_entity(NULL);
                                }
 
                                // Then to set focus
@@ -304,7 +300,7 @@
                                {
                                        if 
(active_entity->on_event(event_id::SETFOCUS))
                                        {
-                                               
mroot->set_active_entity(active_entity.get());
+                                               
mroot.set_active_entity(active_entity.get());
                                        }
                                }
                        }
@@ -341,7 +337,7 @@
 
     // Generate a mouse event
     m_mouse_button_state.m_topmost_entity =
-        m_movie->get_topmost_mouse_entity(PIXELS_TO_TWIPS(m_mouse_x), 
PIXELS_TO_TWIPS(m_mouse_y));
+        _movie->get_topmost_mouse_entity(PIXELS_TO_TWIPS(m_mouse_x), 
PIXELS_TO_TWIPS(m_mouse_y));
     m_mouse_button_state.m_mouse_button_state_current = (m_mouse_buttons & 1);
 
     return generate_mouse_button_events(&m_mouse_button_state);
@@ -434,16 +430,14 @@
         for (unsigned int i=0; i<m_interval_timers.size(); i++) {
             if (m_interval_timers[i]->expired()) {
                 // printf("FIXME: Interval Timer Expired!\n");
-                //m_movie->on_event_interval_timer();
-                m_movie->do_something(m_interval_timers[i]);
+                //_movie->on_event_interval_timer();
+                _movie->do_something(m_interval_timers[i]);
                 // 
clear_interval_timer(m_interval_timers[i]->getIntervalID()); // FIXME: we 
shouldn't really disable the timer here
             }
         }
     }
                        
-       sprite_instance* current_root = m_movie.get();
-       assert(current_root);
-       current_root->advance(delta_time);
+       _movie->advance(delta_time);
 
        assert(testInvariant());
 }
@@ -452,53 +446,35 @@
 void
 movie_root::display()
 {
+//     GNASH_REPORT_FUNCTION;
+
        assert(testInvariant());
 
-  clear_invalidated();
+       _movie->clear_invalidated();
 
 //         GNASH_REPORT_FUNCTION;
-    if (m_movie->get_visible() == false)
+       if (_movie->get_visible() == false)
         {
             // Don't display.
             return;
         }
 
-    const rect& frame_size = m_def->get_frame_size();
+       // should we cache this ? it's immutable after all !
+       const rect& frame_size = _movie->get_frame_size();
 
        // null frame size ? don't display !
        if ( frame_size.is_null() ) return;
 
-    gnash::render::begin_display(
+       render::begin_display(
         m_background_color,
         m_viewport_x0, m_viewport_y0,
         m_viewport_width, m_viewport_height,
         frame_size.get_x_min(), frame_size.get_x_max(),
         frame_size.get_y_min(), frame_size.get_y_max());
 
-    m_movie->display();
+       _movie->display();
 
-    gnash::render::end_display();
-}
-
-bool
-movie_root::goto_labeled_frame(const char* label)
-{
-       assert(testInvariant());
-
-       log_error("movie_root::goto_labeled_frame called, guess we should 
delegate to m_movie instead! Please report url of the movie triggering this 
message so that developer can confirm the change will work fine.");
-               
-       size_t target_frame;
-       if (m_def->get_labeled_frame(label, &target_frame))
-        {
-               goto_frame(target_frame);
-               return true;
-        }
-       else
-        {
-               log_error("ERROR: movie_impl::goto_labeled_frame('%s') "
-                       " unknown label\n", label);
-               return false;
-        }
+       render::end_display();
 }
 
 
@@ -507,11 +483,10 @@
                const char* method_arg_fmt, ...)
 {
        assert(testInvariant());
-       assert(m_movie != NULL);
 
        va_list args;
        va_start(args, method_arg_fmt);
-       const char* result = m_movie->call_method_args(method_name,
+       const char* result = _movie->call_method_args(method_name,
                method_arg_fmt, args);
        va_end(args);
 
@@ -522,9 +497,8 @@
 char* movie_root::call_method_args(const char* method_name,
                const char* method_arg_fmt, va_list args)
 {
-       assert(m_movie != NULL);
        assert(testInvariant());
-       return m_movie->call_method_args(method_name, method_arg_fmt, args);
+       return _movie->call_method_args(method_name, method_arg_fmt, args);
 }
 
 void movie_root::notify_keypress_listeners(key::code k)
@@ -609,5 +583,20 @@
        return true;
 }
 
+void
+movie_root::get_invalidated_bounds(rect* bounds, bool force)
+{
+       // We have a problem with invalidated bounds, this temporary fix
+       // helps committing the refactored code, later we'll have to really
+       // fix this.
+       bounds->set_world(); return;
+
+       bounds->set_null();
+       _movie->get_invalidated_bounds(bounds, force);
+       if ( bounds->is_null() ) log_msg("NULL invalidated bounds!");
+       else log_msg("NOT NULL bounds");
+       // strk STRK FIXME TODO NOW: we have a problem here!! (see elvis.swf)
+}
+
 } // namespace gnash
 

Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- server/movie_root.h 6 Dec 2006 09:30:40 -0000       1.29
+++ server/movie_root.h 6 Dec 2006 10:21:32 -0000       1.30
@@ -14,7 +14,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.29 2006/12/06 09:30:40 strk Exp $ */
+/* $Id: movie_root.h,v 1.30 2006/12/06 10:21:32 strk Exp $ */
 
 /// \page events_handling Handling of user events
 ///
@@ -73,88 +73,81 @@
 #include "fontlib.h"
 #include "font.h"
 #include "tu_file.h"
-#include "movie_def_impl.h"
 #include "tu_config.h"
+#include "drag_state.h" // for composition
 #include "sprite_instance.h" // for inlines
-#include "movie_instance.h" // for inheritance
+
+// Forward declarations
+namespace gnash {
+       class import_info;
+       class movie_def_impl;
+       class movie_root;
+       class import_visitor; // in gnash.h
+       class sprite_instance;
+}
 
 namespace gnash
 {
 
-// Forward declarations
-class import_info;
-class movie_def_impl;
-class movie_root;
-class import_visitor; // in gnash.h
 
 
-/// Global, shared root state for a movie and all its characters.
+/// The absolute top level movie
 //
-/// This should become a wrapper around the top-level 
-/// movie_instance that it being played. We want a
-/// *single* instance of this class for each run,
-/// so that loading external movies will *not* create
-/// a new instance of it.
-///
-/// Currently, a movie_root is returned by
-/// movie_instance::create_instance. We want to
-/// avoid that.
-///
-/// Note that when we implement the new design
-/// the movie_root class won't inherit from sprite_instance
-/// anymore, nor from character of as_object. The closest
-/// class to inherit from would be ref_counted, altought
-/// I'm not even sure we need that... --strk 2006-12-05
+/// This is a wrapper around the top-level movie_instance that is being played.
+/// There is a *single* instance of this class for each run;
+/// loading external movies will *not* create a new instance of it.
 ///
-class movie_root : public sprite_instance
+class movie_root // : public ref_counted
 {
-       int                     m_viewport_x0, m_viewport_y0;
-       int                     m_viewport_width, m_viewport_height;
-       float                   m_pixel_scale;
-
-       rgba                    m_background_color;
-       float                   m_timer;
-       int                     m_mouse_x, m_mouse_y, m_mouse_buttons;
-       void *                  m_userdata;
-
-       mouse_button_state      m_mouse_button_state;
-//     bool                    m_on_event_load_called;
-
-       // Flags for event handlers
-       bool                    m_on_event_xmlsocket_ondata_called;
-       bool                    m_on_event_xmlsocket_onxml_called;
-       bool                    m_on_event_load_progress_called;
-       std::vector<Timer *>    m_interval_timers;
-       std::vector< as_object* >       m_keypress_listeners;
-       character* m_active_input_text;
-       float m_time_remainder;
-
-       /// @@ fold this into m_mouse_button_state?
-       character::drag_state m_drag_state;
 
 public:
-       // XXXbastiaan: make these two variables private
-       boost::intrusive_ptr<sprite_instance>   m_movie;
 
-       movie_root(movie_def_impl* def);
+       /// Default constructor
+       //
+       /// Make sure to call setRootMovie() 
+       /// before using any of this class methods !
+       ///
+       movie_root();
 
        ~movie_root();
 
-       /// @@ should these delegate to m_movie? 
-       virtual void set_member(
+       /// Set the root movie, replacing the current one if any.
+       //
+       /// This is needed for the cases in which the top-level movie
+       /// is replaced by another movie by effect of a loadMovie call
+       /// or similar.
+       ///
+       /// TODO: inspect what happens about VM version
+       ///       (should the *new* movie drive VM operations?
+       ///        -- hope not ! )
+       ///
+       /// Make sure to call this method before using the movie_root,
+       /// as most operations are delegated to the associated/wrapped
+       /// movie_instance.
+       ///
+       /// Note that the display viewport will be updated to match
+       /// the size of given movie.
+       ///
+       /// @param movie
+       ///     The movie_instance to wrap.
+       ///     Will be stored in an intrusive_ptr.
+       ///
+       void setRootMovie(movie_instance* movie);
+
+       /// @@ should this delegate to _movie?  probably !
+       void set_member(
                const tu_stringi& /*name*/,
                const as_value& /*val*/)
        {
        }
 
-       virtual bool get_member(const tu_stringi& /*name*/,
+       /// @@ should this delegate to _movie?  probably !
+       bool get_member(const tu_stringi& /*name*/,
                        as_value* /*val*/)
        {
                return false;
        }
 
-       void set_root_movie(sprite_instance* root_movie);
-
        void set_display_viewport(int x0, int y0, int w, int h);
 
        /// \brief
@@ -192,13 +185,13 @@
        /// Use this to retrieve the last state of the mouse, as set via
        /// notify_mouse_state().  Coordinates are in PIXELS, NOT TWIPS.
        ///
-       virtual void    get_mouse_state(int& x, int& y, int& buttons);
+       void    get_mouse_state(int& x, int& y, int& buttons);
 
-       virtual void get_drag_state(drag_state& st);
+       void get_drag_state(drag_state& st);
 
-       virtual void set_drag_state(const drag_state& st);
+       void set_drag_state(const drag_state& st);
 
-       sprite_instance* get_root_movie() { return m_movie.get(); }
+       sprite_instance* get_root_movie() { return _movie.get(); }
 
        void stop_drag()
        {
@@ -206,28 +199,29 @@
                m_drag_state.reset();
        }
 
-       movie_definition* get_movie_definition() {
-               return m_movie->get_movie_definition();
+       movie_definition* get_movie_definition() const {
+               assert(_movie);
+               return _movie->get_movie_definition();
        }
 
-       virtual int add_interval_timer(void *timer);
-       virtual void clear_interval_timer(int x);
-       virtual void do_something(void *timer);
+       int add_interval_timer(void *timer);
+       void clear_interval_timer(int x);
+       void do_something(void *timer);
 
        /// 0-based!!
        size_t get_current_frame() const {
-               return m_movie->get_current_frame();
+               return _movie->get_current_frame();
        }
 
        // @@ should this be in movie_instance ?
        float get_frame_rate() const {
-               return m_def->get_frame_rate();
+               return get_movie_definition()->get_frame_rate();
        }
 
        /// Return the size of a logical movie pixel as
        /// displayed on-screen, with the current device
        /// coordinates.
-       virtual float   get_pixel_scale() const
+       float   get_pixel_scale() const
        {
            return m_pixel_scale;
        }
@@ -235,7 +229,7 @@
        // @@ Is this one necessary?
        character* get_character(int character_id)
        {
-           return m_movie->get_character(character_id);
+           return _movie->get_character(character_id);
        }
 
        void set_background_color(const rgba& color)
@@ -255,70 +249,73 @@
 
        float   get_timer() const { return m_timer; }
 
-       void    restart() { m_movie->restart(); }
+       void    restart() { _movie->restart(); }
 
        void    advance(float delta_time);
 
        /// 0-based!!
        void goto_frame(size_t target_frame_number) {
-               m_movie->goto_frame(target_frame_number);
+               _movie->goto_frame(target_frame_number);
        }
 
-       virtual bool has_looped() const {
-               return m_movie->has_looped();
+       bool has_looped() const {
+               return _movie->has_looped();
        }
 
        void display();
 
-       virtual bool goto_labeled_frame(const char* label);
+       /// Delegate to wrapped movie_instance
+       bool goto_labeled_frame(const char* label) {
+               return _movie->goto_labeled_frame(label);
+       }
 
-       virtual void set_play_state(play_state s) {
-               m_movie->set_play_state(s);
+       void set_play_state(sprite_instance::play_state s) {
+               _movie->set_play_state(s);
        }
 
-       virtual play_state get_play_state() const {
-               return m_movie->get_play_state();
+       sprite_instance::play_state get_play_state() const {
+               return _movie->get_play_state();
        }
 
-       virtual void set_variable(const char* path_to_var,
+       void set_variable(const char* path_to_var,
                        const char* new_value)
        {
-               m_movie->set_variable(path_to_var, new_value);
+               _movie->set_variable(path_to_var, new_value);
        }
 
-       virtual void set_variable(const char* path_to_var,
+       void set_variable(const char* path_to_var,
                        const wchar_t* new_value)
        {
-               m_movie->set_variable(path_to_var, new_value);
+               _movie->set_variable(path_to_var, new_value);
        }
 
-       virtual const char* get_variable(const char* path_to_var) const
+       const char* get_variable(const char* path_to_var) const
        {
-               return m_movie->get_variable(path_to_var);
+               return _movie->get_variable(path_to_var);
        }
 
        /// For ActionScript interfacing convenience.
-       virtual const char* call_method(const char* method_name,
+       const char* call_method(const char* method_name,
                        const char* method_arg_fmt, ...);
-       virtual const char* call_method_args(const char* method_name,
+       const char* call_method_args(const char* method_name,
                        const char* method_arg_fmt, va_list args);
 
-       virtual void set_visible(bool visible) {
-               m_movie->set_visible(visible);
+       void set_visible(bool visible) {
+               _movie->set_visible(visible);
        }
-       virtual bool get_visible() const {
-               return m_movie->get_visible();
+       bool get_visible() const {
+               return _movie->get_visible();
        }
 
-       virtual void * get_userdata() { return m_userdata; }
-       virtual void set_userdata(void * ud ) { m_userdata = ud;  }
+       void * get_userdata() { return m_userdata; }
+       void set_userdata(void * ud ) { m_userdata = ud;  }
 
-       virtual void attach_display_callback(
+       void attach_display_callback(
                        const char* path_to_object,
                        void (*callback)(void* user_ptr),
                        void* user_ptr)
        {
-               m_movie->attach_display_callback(path_to_object,
+               _movie->attach_display_callback(path_to_object,
                        callback, user_ptr);
        }
 
@@ -329,39 +326,57 @@
        character* get_active_entity();
        void set_active_entity(character* ch);
        
-       void get_invalidated_bounds(rect* bounds, bool force)
-       {
-        
-               if (m_invalidated)
-               {
-                       // complete redraw (usually first frame)
-                       bounds->set_world();
-               }
-               else
-               {
-                       // browse characters to compute bounds
-                       // TODO: Use better start-values
-                       bounds->set_null();
-                       m_movie->get_invalidated_bounds(bounds,
-                               force||m_invalidated);
-               }
-
-          
-       }
+       void get_invalidated_bounds(rect* bounds, bool force);
 
        // reimplemented from movie_interface, see dox there
        bool isMouseOverActiveEntity() const;
 
        bool testInvariant() const;
 
+       void clear_invalidated() {
+               _movie->clear_invalidated();
+       }
+
 private:
 
+       // TODO: use Range2d<int> ?
+       int                     m_viewport_x0, m_viewport_y0;
+       int                     m_viewport_width, m_viewport_height;
+
+       float                   m_pixel_scale;
+
+       rgba                    m_background_color;
+       float                   m_timer;
+       int                     m_mouse_x, m_mouse_y, m_mouse_buttons;
+       void *                  m_userdata;
+
+       mouse_button_state      m_mouse_button_state;
+
+       // Flags for event handlers
+       bool                    m_on_event_xmlsocket_ondata_called;
+       bool                    m_on_event_xmlsocket_onxml_called;
+       bool                    m_on_event_load_progress_called;
+       std::vector<Timer *>    m_interval_timers;
+       std::vector< as_object* >       m_keypress_listeners;
+       character* m_active_input_text;
+       float m_time_remainder;
+
+       /// @@ fold this into m_mouse_button_state?
+       drag_state m_drag_state;
+
+       /// The movie instance wrapped by this movie_root
+       //
+       /// We keep a pointer to the base sprite_instance class
+       /// to avoid having to replicate all of the base class
+       /// interface to the movie_instance class definition
+       ///
+       boost::intrusive_ptr<sprite_instance> _movie;
+
        /// This function should return TRUE iff any action triggered
        /// by the event requires redraw, see \ref events_handling for
        /// more info.
        ///
         bool fire_mouse_event();
-
 };
 
 

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -b -r1.94 -r1.95
--- server/sprite_instance.cpp  1 Dec 2006 10:22:58 -0000       1.94
+++ server/sprite_instance.cpp  6 Dec 2006 10:21:32 -0000       1.95
@@ -37,6 +37,7 @@
 #include "fn_call.h"
 #include "Key.h"
 #include "movie_root.h"
+#include "movie_instance.h"
 #include "swf_event.h"
 #include "sprite_definition.h"
 #include "ActionExec.h"
@@ -50,6 +51,7 @@
 
 #include <functional> // for mem_fun, bind1st
 #include <algorithm> // for for_each
+#include <sstream>
 
 // This needs to be included first for NetBSD systems or we get a weird
 // problem with pthread_t being defined too many times if we use any
@@ -752,7 +754,7 @@
 
 // getURL(url:String, [window:String], [method:String]) : Void
 static void
-sprite_getURL(const fn_call& fn)
+sprite_getURL(const fn_call& /*fn*/)
 {
        log_error("FIXME: MovieClip.getURL() not implemented yet");
 }
@@ -760,7 +762,7 @@
 // startDrag([lockCenter:Boolean], [left:Number], [top:Number],
 //     [right:Number], [bottom:Number]) : Void`
 static void
-sprite_startDrag(const fn_call& fn)
+sprite_startDrag(const fn_call& /*fn*/)
 {
        log_error("FIXME: MovieClip.startDrag() not implemented yet");
 }
@@ -897,7 +899,7 @@
 //------------------------------------------------
 
 sprite_instance::sprite_instance(
-               movie_definition* def, movie_root* r,
+               movie_definition* def, movie_instance* r,
                character* parent, int id)
        :
        character(parent, id),
@@ -908,13 +910,11 @@
        m_goto_frame_action_list(),
        m_play_state(PLAY),
        m_current_frame(0),
-       m_time_remainder(0),
        m_update_frame(true),
        m_has_looped(false),
        m_accept_anim_moves(true),
        m_init_actions_executed(),
        m_as_environment(),
-       m_frame_time(0.0f),
        m_has_keypress_event(false),
        _text_variables(),
        m_sound_stream_id(-1),
@@ -932,17 +932,7 @@
 
        // Initialize the flags for init action executed.
        m_init_actions_executed.assign(m_def->get_frame_count(), false);
-#if 0 // replaced with above line (sounds more readable)
-//     m_init_actions_executed.resize(m_def->get_frame_count());
-//     for (std::vector<bool>::iterator p = m_init_actions_executed.begin(); p 
!= m_init_actions_executed.end(); ++p)
-//         {
-//             *p = false;
-//         }
-#endif
 
-       // assert(m_root); // duplicated assert ...
-       m_frame_time = 1.0f / m_root->get_frame_rate(); // cache
-       m_time_remainder = m_frame_time;
 }
 
 sprite_instance::~sprite_instance()
@@ -950,11 +940,10 @@
 
        if (m_has_keypress_event)
        {
-               m_root->remove_keypress_listener(this);
+               _vm.getRoot().remove_keypress_listener(this);
        }
 
        m_display_list.clear();
-       //m_root->drop_ref();
 }
 
 character* sprite_instance::get_character_at_depth(int depth)
@@ -1142,8 +1131,7 @@
        {
            // Local coord of mouse IN PIXELS.
            int x, y, buttons;
-           assert(m_root);
-           m_root->get_mouse_state(x, y, buttons);
+           _vm.getRoot().get_mouse_state(x, y, buttons);
 
            matrix      m = get_world_matrix();
 
@@ -1160,8 +1148,7 @@
        {
            // Local coord of mouse IN PIXELS.
            int x, y, buttons;
-           assert(m_root);
-           m_root->get_mouse_state(x, y, buttons);
+           _vm.getRoot().get_mouse_state(x, y, buttons);
 
            matrix      m = get_world_matrix();
 
@@ -1862,7 +1849,7 @@
                //
                if (m_has_keypress_event)
                {
-                       m_root->add_keypress_listener(this);
+                       _vm.getRoot().add_keypress_listener(this);
                }
        }
        
@@ -2094,9 +2081,10 @@
 
 void sprite_instance::display()
 {
-//     GNASH_REPORT_FUNCTION;
+       //GNASH_REPORT_FUNCTION;
 
-       if (get_visible() == false)     {
+       if (get_visible() == false)
+       {
                // We're invisible, so don't display!
                
                // Note: dlist.cpp will avoid to even call display() so this 
will probably
@@ -2108,7 +2096,8 @@
        rect bounds;
        m_display_list.get_invalidated_bounds(&bounds, true);
        
-       if (gnash::render::bounds_in_clipping_area(bounds)) {
+       if (gnash::render::bounds_in_clipping_area(bounds))
+       {
          m_display_list.display();
          clear_invalidated();
        }
@@ -2420,7 +2409,6 @@
 void sprite_instance::restart()
 {
     m_current_frame = 0;
-    m_time_remainder = 0;
     m_update_frame = true;
     m_has_looped = false;
     m_play_state = PLAY;
@@ -2494,74 +2482,62 @@
        return NULL;
 }
 
-float
-sprite_instance::get_timer() const
-{
-       return m_root->get_timer();
-}
+//float
+//sprite_instance::get_timer() const
+//{
+//     return m_root->get_timer();
+//}
+
 
 void
 sprite_instance::clear_interval_timer(int x)
 {
-       m_root->clear_interval_timer(x);
+       _vm.getRoot().clear_interval_timer(x);
 }
 
 int
 sprite_instance::add_interval_timer(void *timer)
 {
-       return m_root->add_interval_timer(timer);
+       return _vm.getRoot().add_interval_timer(timer);
 }
 
 sprite_instance*
 sprite_instance::get_root_movie()
 {
        assert(m_root);
-       return m_root->get_root_movie();
+       return m_root; // could as well be myself !
 }
 
 float
 sprite_instance::get_pixel_scale() const
 {
-       return m_root->get_pixel_scale();
+       return _vm.getRoot().get_pixel_scale();
 }
 
 void
 sprite_instance::get_mouse_state(int& x, int& y, int& buttons)
 {
-       m_root->get_mouse_state(x, y, buttons);
-}
-
-void
-sprite_instance::get_drag_state(drag_state& st)
-{
-       assert(m_root);
-       m_root->get_drag_state(st);
+       _vm.getRoot().get_mouse_state(x, y, buttons);
 }
 
 void
 sprite_instance::stop_drag()
 {
        assert(m_parent == NULL);       // we must be the root movie!!!
-       m_root->stop_drag();
-}
-
-void
-sprite_instance::set_drag_state(const drag_state& st)
-{
-       m_root->set_drag_state(st);
+       _vm.getRoot().stop_drag();
 }
 
 float
 sprite_instance::get_background_alpha() const
 {
     // @@ this doesn't seem right...
-    return m_root->get_background_alpha();
+    return _vm.getRoot().get_background_alpha();
 }
 
 void
 sprite_instance::set_background_color(const rgba& color)
 {
-       m_root->set_background_color(color);
+       _vm.getRoot().set_background_color(color);
 }
 
 
@@ -2602,14 +2578,50 @@
 } 
 
 void 
-sprite_instance::get_invalidated_bounds(rect* bounds, bool force) {
+sprite_instance::get_invalidated_bounds(rect* bounds, bool force)
+{
+//#define DEBUG_INVALIDATED_BOUNDS
   
-  bounds->expand_to_rect(m_old_invalidated_bounds);
+#ifdef DEBUG_INVALIDATED_BOUNDS
+       std::stringstream ss;
+       ss << this << ") sprite_instance::get_invalidated_bounds(" << *bounds 
<< ", " << force << ") called [ " << typeid(*this).name() << "]" << std::endl;
+#endif
+
+       // nothing to do if this sprite is not visible
+       if (!m_visible)
+       {
+#ifdef DEBUG_INVALIDATED_BOUNDS
+               ss << "Not visible, bounds untouched" << std::endl;
+               log_msg("%s", ss.str().c_str());
+#endif
+               return;
+       }
   
-  if (!m_visible) return;
   // TODO: check if alpha=0 (return if so)
   
+       // nothing to do if this sprite's bounds are
+       // not invalidated (unless *forced*)
+       if ( ! m_invalidated && ! force )
+       {
+#ifdef DEBUG_INVALIDATED_BOUNDS
+               ss << "Not invalidated and not forced, bounds untouched" << 
std::endl;
+               log_msg("%s", ss.str().c_str());
+#endif
+               return;
+       }
+  
+       // Add old invalidated bounds 
+       bounds->expand_to_rect(m_old_invalidated_bounds);
+#ifdef DEBUG_INVALIDATED_BOUNDS
+       ss << "After expanding to old_invalidated_bounds (" << 
m_old_invalidated_bounds << ") new bounds are: " << *bounds << std::endl;
+#endif
+  
   m_display_list.get_invalidated_bounds(bounds, force||m_invalidated);
+
+#ifdef DEBUG_INVALIDATED_BOUNDS
+       ss << "After getting invalidated bounds from m_display_list, new bounds 
are: " << *bounds << std::endl;
+       log_msg("%s", ss.str().c_str());
+#endif
 }
 
 const char*

Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- server/sprite_instance.h    28 Nov 2006 15:59:30 -0000      1.45
+++ server/sprite_instance.h    6 Dec 2006 10:21:32 -0000       1.46
@@ -17,7 +17,7 @@
 // 
 //
 
-/* $Id: sprite_instance.h,v 1.45 2006/11/28 15:59:30 strk Exp $ */
+/* $Id: sprite_instance.h,v 1.46 2006/12/06 10:21:32 strk Exp $ */
 
 // Stateful live Sprite instance
 
@@ -38,13 +38,16 @@
 #include <list>
 #include <map>
 
+// Forward declarations
+namespace gnash {
+       class movie_instance;
+       class swf_event;
+       class drag_state;
+}
+
 namespace gnash
 {
 
-// Forward declarations
-class movie_root; 
-class swf_event;
-
 /// Stateful Sprite object. Also known as a MovieClip.
 //
 /// Instance of this class are also known as "timelines".
@@ -60,8 +63,16 @@
        // definition must match movie_definition::PlayList
        typedef std::vector<execute_tag*> PlayList;
 
+       /// @param root
+       ///     The "relative" _root of this sprite, which is the 
+       ///     instance of top-level sprite defined by the same
+       ///     SWF that also contained *this* sprite definition.
+       ///     Note that this can be *different* from the top-level
+       ///     movie accessible trought the VM, in case this sprite
+       ///     was defined in an externally loaded movie.
+       ///
        sprite_instance(movie_definition* def,
-               movie_root* r, character* parent, int id);
+               movie_instance* root, character* parent, int id);
 
        virtual ~sprite_instance();
 
@@ -81,23 +92,21 @@
 
        virtual void has_keypress_event();
 
-       // sprite instance of add_interval_handler()
-       // delegates to m_root
+       // delegates to movie_root 
        virtual int    add_interval_timer(void *timer);
 
-       // delegates to m_root
+       // delegates to movie_root 
        virtual void  clear_interval_timer(int x);
        
 
        /// Interval timer timeout executor
        virtual void    do_something(void *timer);
 
-       movie_root* get_root() {
-               return m_root;
-       }
-
-       /// Get a pointer to the root sprite
-       sprite_instance* get_root_movie();
+       /// \brief
+       /// Return this sprite's relative root as
+       /// specified at contruction time
+       ///
+       virtual sprite_instance* get_root_movie();
 
        /// \brief
        /// Return the sprite_definition (or movie_definition)
@@ -152,7 +161,7 @@
        /// Stop or play the sprite.
        void set_play_state(play_state s)
        {
-           if (m_play_state != s) m_time_remainder = 0;
+           //if (m_play_state != s) m_time_remainder = 0;
            m_play_state = s;
        }
 
@@ -160,18 +169,19 @@
 
        character* get_character(int character_id);
 
-       float get_background_alpha() const;
+       // delegates to movie_root (possibly wrong)
+       virtual float get_background_alpha() const;
 
-       // delegates to m_root
-       float   get_pixel_scale() const;
+       // delegates to movie_root 
+       virtual float   get_pixel_scale() const;
 
-       // delegates to m_root
+       // delegates to movie_root 
        virtual void get_mouse_state(int& x, int& y, int& buttons);
 
-       // delegatest to m_root
+       // delegates to movie_root (possibly wrong)
        void    set_background_color(const rgba& color);
 
-       float   get_timer() const;
+       //float get_timer() const;
 
        void    restart();
 
@@ -385,15 +395,9 @@
        ///
        virtual void call_frame_actions(const as_value& frame_spec);
 
-       // delegatest to m_root
-       virtual void set_drag_state(const drag_state& st);
-
+       // delegates to movie_root 
        virtual void stop_drag();
 
-       // delegates to m_root
-       virtual void get_drag_state(drag_state& st);
-
-
        /// Duplicate the object with the specified name
        /// and add it with a new name  at a new depth.
        void clone_display_object(const std::string& name,
@@ -535,7 +539,8 @@
 
        mouse_state m_mouse_state;
 
-       movie_root*     m_root;
+       // TODO: shouldn't we keep this by intrusive_ptr ?
+       movie_instance* m_root;
 
        DisplayList     m_display_list;
 
@@ -544,7 +549,6 @@
 
        play_state      m_play_state;
        size_t          m_current_frame;
-       float           m_time_remainder;
        bool            m_update_frame;
        bool            m_has_looped;
 
@@ -561,7 +565,6 @@
        /// Increment m_current_frame, and take care of looping.
        void increment_frame_and_check_for_loop();
 
-       float   m_frame_time;
        bool m_has_keypress_event;
 
        /// A container for textfields, indexed by their variable name

Index: server/asobj/Key.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Key.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- server/asobj/Key.cpp        24 Nov 2006 14:50:30 -0000      1.5
+++ server/asobj/Key.cpp        6 Dec 2006 10:21:32 -0000       1.6
@@ -339,8 +339,8 @@
        // Notify keypress listeners.
        if (down) 
        {
-               movie_root* mroot = (movie_root*) get_current_root();
-               mroot->notify_keypress_listeners(k);
+               movie_root& mroot = VM::get().getRoot();
+               mroot.notify_keypress_listeners(k);
        }
 
     static tu_string   key_obj_name("Key");

Index: server/parser/movie_def_impl.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/movie_def_impl.cpp,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- server/parser/movie_def_impl.cpp    1 Dec 2006 10:23:32 -0000       1.53
+++ server/parser/movie_def_impl.cpp    6 Dec 2006 10:21:32 -0000       1.54
@@ -29,6 +29,7 @@
 #include "font.h"
 #include "log.h"
 #include "sprite_instance.h"
+#include "movie_instance.h"
 #include "bitmap_character_def.h"
 #include "swf/TagLoadersTable.h"
 #include "movie_root.h"
@@ -727,20 +728,17 @@
 sprite_instance*
 movie_def_impl::create_instance()
 {
+       return create_movie_instance();
+}
+
+movie_instance*
+movie_def_impl::create_movie_instance()
+{
 
        // @@ Shouldn't we return a movie_instance instead ?
        // @@ and leave movie_root creation to the caller ..
 
-       movie_root*     m = new movie_root(this);
-
-       movie_instance* root_movie = new movie_instance(this, m, NULL);
-
-       //root_movie->set_name("_root");
-       m->set_root_movie(root_movie);
-
-       m->add_ref(); // looking for leaks ??
-
-       return m;
+       return new movie_instance(this, NULL);
 }
 
 

Index: server/parser/movie_def_impl.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/movie_def_impl.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -b -r1.26 -r1.27
--- server/parser/movie_def_impl.h      4 Dec 2006 17:05:38 -0000       1.26
+++ server/parser/movie_def_impl.h      6 Dec 2006 10:21:32 -0000       1.27
@@ -46,6 +46,8 @@
        class import_info;
        class movie_def_impl;
        class movie_root;
+       class sprite_instance;
+       class movie_instance;
        namespace SWF {
                class TagLoadersTable;
        }
@@ -584,6 +586,9 @@
        ///
        sprite_instance* create_instance();
 
+       /// Instanc of this definition is a valid movie_instance
+       movie_instance* create_movie_instance();
+
        virtual const std::string& get_url() const { return _url; }
        
        const rect&     get_bound() const {

Index: server/parser/movie_definition.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/movie_definition.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- server/parser/movie_definition.h    5 Dec 2006 09:56:57 -0000       1.14
+++ server/parser/movie_definition.h    6 Dec 2006 10:21:32 -0000       1.15
@@ -61,6 +61,8 @@
 // Forward declarations
 namespace gnash {
        class bitmap_character_def;
+       class movie_instance;
+       class sprite_instance;
 }
 
 namespace gnash
@@ -101,7 +103,7 @@
        virtual size_t get_bytes_loaded() const = 0;
        virtual size_t get_bytes_total() const = 0;
        
-       /// Create a playable movie instance from a def.
+       /// Create a playable sprite_instance from a def.
        //
        /// This calls add_ref() on the movie_interface internally.
        /// Call drop_ref() on the movie_interface when you're done with it.
@@ -109,6 +111,23 @@
        ///
        virtual sprite_instance* create_instance() = 0;
        
+       /// Create a movie instance from a def.
+       //
+       /// Not all movie definitions allow creation of
+       /// movie_instance. In particular, sprite_definition
+       /// can only create sprite_instance (see create_instance)
+       ///
+       /// The default implementation returns NULL.
+       ///
+       /// Override this method for any definition that is
+       /// able to be instanciated as a movie_instance.
+       /// movie_def_impl is one such example, future examples
+       /// should include jpeg_movie_def and similar..
+       ///
+       virtual movie_instance* create_movie_instance() {
+               return NULL;
+       }
+       
        virtual void    output_cached_data(tu_file* /*out*/, const 
cache_options& /*options*/) {}
        virtual void    input_cached_data(tu_file* /*in*/) {}
        
@@ -502,9 +521,17 @@
        /// Ensure that frame number 'framenum' (1-based offset)
        /// has been loaded (load on demand).
        //
+       /// @param framenum
+       ///     1-based frame index that we want to be fully loaded
+       ///     before this function returns
+       ///
        /// @return false on error (like not enough frames available).
        ///
-       virtual bool ensure_frame_loaded(size_t framenum) = 0;
+       /// The default implementation is to always return true.
+       ///
+       virtual bool ensure_frame_loaded(size_t /*framenum*/) {
+               return true;
+       }
 
        /// \brief
        /// Load next chunk of this movie/sprite frames if available.

Index: server/vm/ASHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/ASHandlers.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/vm/ASHandlers.cpp    1 Dec 2006 10:23:56 -0000       1.7
+++ server/vm/ASHandlers.cpp    6 Dec 2006 10:21:32 -0000       1.8
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: ASHandlers.cpp,v 1.7 2006/12/01 10:23:56 alexeev Exp $ */
+/* $Id: ASHandlers.cpp,v 1.8 2006/12/06 10:21:32 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -43,6 +43,10 @@
 #include "gstring.h" // for automatic as_value::STRING => String as object
 #include "Number.h" // for automatic as_value::NUMBER => Number as object
 #include "types.h" // for PIXELS_TO_TWIPS
+#include "drag_state.h"
+#include "VM.h" // for getting the root
+#include "movie_root.h" // for set_drag_state (ActionStartDragMovie)
+#include "gstring.h"
 
 #include <string>
 #include <map>
@@ -1232,7 +1236,7 @@
 
        ensure_stack(env, 3); 
 
-       character::drag_state st;
+       drag_state st;
     
        character* tgt = env.find_target(env.top(0));
        if ( tgt ) {
@@ -1283,12 +1287,9 @@
 
        env.drop(3);
     
-       sprite_instance *root_movie = env.get_target()->get_root_movie();
-       assert(root_movie);
-    
        if (tgt)
        {
-               root_movie->set_drag_state(st);
+               VM::get().getRoot().set_drag_state(st);
        }
     
 }
@@ -1417,11 +1418,18 @@
 SWFHandlers::ActionGetTimer(ActionExec& thread)
 {
 //    GNASH_REPORT_FUNCTION;
-       as_environment& env = thread.env;
 
-       sprite_instance* tgt = env.get_target()->to_movie();
-       assert(tgt);
-       env.push(floorf(tgt->get_timer() * 1000.0f));
+       // Maybe the timer should be associated to the VM
+       // rather then to the movie_root... 
+       //
+       // Oh, another thing, rather then calling VM::get().getRoot()
+       // we should likely get the movie_root from the environment,
+       // to take into account a future support for multiple concurrent
+       // VM running in a single process (for example: playing multiple
+       // movies in multiple windows using the same executable)
+
+       as_environment& env = thread.env;
+       env.push(floorf(VM::get().getRoot().get_timer() * 1000.0f));
 }
 
 void
@@ -2585,7 +2593,7 @@
 
        // for temporarly storing result of automatic
        // String and Number conversion
-       std::auto_ptr<as_object> obj_ptr;
+       boost::intrusive_ptr<as_object> obj_ptr;
 
     if (!obj)
     {
@@ -2596,11 +2604,11 @@
        switch ( obj_value.get_type() )
        {
                case as_value::STRING:
-                       obj_ptr = init_string_instance(obj_value.to_string());
+                       obj_ptr = 
init_string_instance(obj_value.to_string()).release();
                        obj = obj_ptr.get();
                        break;
                case as_value::NUMBER:
-                       obj_ptr = init_number_instance(obj_value.to_number());
+                       obj_ptr = 
init_number_instance(obj_value.to_number()).release();
                        obj = obj_ptr.get();
                        break;
                default:

Index: server/vm/VM.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/VM.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/vm/VM.cpp    24 Nov 2006 17:50:47 -0000      1.3
+++ server/vm/VM.cpp    6 Dec 2006 10:21:32 -0000       1.4
@@ -16,7 +16,7 @@
 
 //
 
-/* $Id: VM.cpp,v 1.3 2006/11/24 17:50:47 strk Exp $ */
+/* $Id: VM.cpp,v 1.4 2006/12/06 10:21:32 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -24,7 +24,8 @@
 
 #include "VM.h"
 #include "movie_definition.h"
-#include "sprite_instance.h"
+#include "movie_instance.h"
+#include "movie_root.h"
 #include "Global.h"
 
 #include <memory>
@@ -45,8 +46,9 @@
 
        assert(_singleton.get());
 
-       _singleton->setRoot(movie.create_instance());
-       assert(_singleton->getRoot());
+       std::auto_ptr<movie_instance> inst ( movie.create_movie_instance() );
+       assert(inst.get()); // or an invalid movie_definition was given
+       _singleton->setRoot(inst.release()); // transfer ownership
 
        _singleton->setGlobal(new gnash::Global(*_singleton));
        assert(_singleton->getGlobal());
@@ -97,10 +99,19 @@
        return _swfversion;
 }
 
-sprite_instance*
+movie_root&
 VM::getRoot() const
 {
-       return _root_movie.get();
+       return *_root_movie;
+}
+
+/*private*/
+void
+VM::setRoot(movie_instance* root)
+{
+       assert(!_root_movie.get());
+       _root_movie.reset(new movie_root());
+       _root_movie->setRootMovie(root);
 }
 
 /*public*/
@@ -112,14 +123,6 @@
 
 /*private*/
 void
-VM::setRoot(sprite_instance* inst)
-{
-       assert(!_root_movie);
-       _root_movie = inst;
-}
-
-/*private*/
-void
 VM::setGlobal(as_object* o)
 {
        assert(!_global);

Index: server/vm/VM.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/VM.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/vm/VM.h      24 Nov 2006 17:50:47 -0000      1.3
+++ server/vm/VM.h      6 Dec 2006 10:21:32 -0000       1.4
@@ -23,7 +23,8 @@
 #include "config.h"
 #endif
 
-#include <smart_ptr.h> // for boost::intrusive_ptr
+#include "smart_ptr.h" // for boost::intrusive_ptr
+#include "movie_root.h" // for composition
 
 #include <memory> // for auto_ptr
 #include <locale>
@@ -31,7 +32,6 @@
 // Forward declarations
 namespace gnash {
        class movie_definition;
-       class sprite_instance;
        class as_object;
 }
 
@@ -76,9 +76,10 @@
        static std::auto_ptr<VM> _singleton;
 
        /// \brief
-       /// Root movie, will be instanciated from the definition
+       /// Root movie, will be instantiated from the definition
        /// given to the init() function.
-       boost::intrusive_ptr<sprite_instance> _root_movie;
+       ///
+       std::auto_ptr<movie_root> _root_movie;
 
        /// The _global ActionScript object
        boost::intrusive_ptr<as_object> _global;
@@ -90,7 +91,7 @@
        //
        /// Will be called by the init() function
        /// 
-       void setRoot(sprite_instance*);
+       void setRoot(movie_instance*);
 
        /// Set the _global Object for actions run by Virtual Machine
        //
@@ -112,6 +113,11 @@
        ///
        /// @param movie
        ///     The definition for the root movie.
+       ///     It is required that the given definition's
+       ///     create_movie_instance() method returns
+       ///     not NULL, or an assertion will fail.
+       ///     See movie_definition::create_root_instance()
+       ///     for more info.
        ///
        static VM& init(movie_definition& movie);
 
@@ -134,7 +140,7 @@
        int getSWFVersion() const;
 
        /// Get a pointer to this VM's Root movie 
-       sprite_instance* getRoot() const;
+       movie_root& getRoot() const;
 
        /// Get a pointer to this VM's _global Object
        as_object* getGlobal() const;

Index: server/vm/action.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/action.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/vm/action.cpp        24 Nov 2006 14:50:30 -0000      1.2
+++ server/vm/action.cpp        6 Dec 2006 10:21:32 -0000       1.3
@@ -22,7 +22,6 @@
 
 #include "action.h"
 #include "as_object.h"
-//#include "impl.h"
 #include "log.h"
 #include "tu_random.h"
 #include "movie_definition.h"
@@ -34,6 +33,8 @@
 #include "array.h"
 #include "types.h"
 #include "sprite_instance.h"
+#include "movie_instance.h"
+#include "movie_root.h" // to reset root movie from attach_extern_movie
 #include "Global.h"
 #include "swf.h"
 #include "URL.h"
@@ -156,7 +157,11 @@
                        log_error("can't create extern root sprite for %s\n", 
url.str().c_str());
                        return;
                }
-           set_current_root(extern_movie);
+
+               // It would be better if create_library_movie_inst() returned a 
movie_instance
+               // directly !
+               gnash::movie_instance* mi = 
dynamic_cast<movie_instance*>(extern_movie);
+               VM::get().getRoot().setRootMovie(mi);
            sprite_instance* m = extern_movie->get_root_movie();
 
            m->on_event(event_id::LOAD);

Index: testsuite/MovieTester.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/MovieTester.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- testsuite/MovieTester.cpp   6 Dec 2006 09:27:31 -0000       1.13
+++ testsuite/MovieTester.cpp   6 Dec 2006 10:21:32 -0000       1.14
@@ -63,17 +63,13 @@
                throw GnashException("Could not load movie from "+url);
        }
 
-       sprite_instance* root = VM::init(*_movie_def).getRoot();
-       assert(root);
+       _movie_root = &(VM::init(*_movie_def).getRoot());
 
        // Now complete load of the movie
        _movie_def->completeLoad();
        _movie_def->ensure_frame_loaded(_movie_def->get_frame_count());
 
-       _movie_root = dynamic_cast<movie_root*>(root);
-       assert(_movie_root);
-
-       _movie = root->get_root_movie();
+       _movie = _movie_root->get_root_movie();
        assert(_movie);
 
        // Activate verbosity so that self-contained testcases are
@@ -83,7 +79,7 @@
 
 
        // Now place the root movie on the stage
-       root->advance(1.0);
+       advance();
 }
 
 void

Index: testsuite/server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/server/Makefile.am,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- testsuite/server/Makefile.am        1 Dec 2006 16:51:08 -0000       1.17
+++ testsuite/server/Makefile.am        6 Dec 2006 10:21:32 -0000       1.18
@@ -25,7 +25,9 @@
        -I$(srcdir) \
         -I$(top_srcdir)/testsuite  \
         -I$(top_srcdir)/libbase  \
+        -I$(top_srcdir)/libgeometry  \
         -I$(top_srcdir)/server  \
+        -I$(top_srcdir)/server/parser  \
         -I$(top_srcdir)/server/vm  \
        $(BOOST_CFLAGS) \
        $(NULL)

Index: testsuite/server/PropertyListTest.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/server/PropertyListTest.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- testsuite/server/PropertyListTest.cpp       11 Nov 2006 14:36:33 -0000      
1.6
+++ testsuite/server/PropertyListTest.cpp       6 Dec 2006 10:21:32 -0000       
1.7
@@ -20,9 +20,12 @@
 
 #include "check.h"
 #include "PropertyList.h"
+#include "DummyMovieDefinition.h"
+#include "VM.h"
 #include "as_object.h" // need to set as owner of PropertyList
 #include "as_value.h"
 #include "log.h"
+#include "smart_ptr.h"
 
 #include <iostream>
 #include <sstream>
@@ -38,6 +41,13 @@
        gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
        dbglogfile.setVerbosity();
 
+       boost::intrusive_ptr<movie_definition> md5 ( new 
DummyMovieDefinition(5) );
+       boost::intrusive_ptr<movie_definition> md6 ( new 
DummyMovieDefinition(6) );
+
+       VM& vm = VM::init(*md5);
+
+       dbglogfile << "VM version " << vm.getSWFVersion() << endl;
+
        as_object obj;
        PropertyList props;
 

Index: utilities/processor.cpp
===================================================================
RCS file: /sources/gnash/gnash/utilities/processor.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -b -r1.40 -r1.41
--- utilities/processor.cpp     27 Nov 2006 15:57:51 -0000      1.40
+++ utilities/processor.cpp     6 Dec 2006 10:21:32 -0000       1.41
@@ -17,7 +17,7 @@
 //
 //
 
-/* $Id: processor.cpp,v 1.40 2006/11/27 15:57:51 strk Exp $ */
+/* $Id: processor.cpp,v 1.41 2006/12/06 10:21:32 strk Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -28,6 +28,7 @@
 #include "gnash.h"
 #include "movie_definition.h"
 #include "sprite_instance.h"
+#include "movie_root.h"
 #include "log.h"
 #include "rc.h"
 #include "URL.h"
@@ -254,7 +255,7 @@
        exit(1);
     }
 
-    gnash::sprite_instance* m = VM::init(*md).getRoot();
+    gnash::movie_root& m = VM::init(*md).getRoot();
 
     md->completeLoad();
     
@@ -272,30 +273,30 @@
        // @@ Maybe we should allow the user to specify some
        // safety margin on scaled shapes.
        
-       size_t  last_frame = m->get_current_frame();
-       m->advance(0.010f);
-       m->display();
+       size_t  last_frame = m.get_current_frame();
+       m.advance(0.010f);
+       m.display();
        
-       if (m->get_current_frame() == md->get_frame_count() - 1) {
+       if (m.get_current_frame() == md->get_frame_count() - 1) {
            // Done.
            break;
        }
        
-       if (m->get_play_state() == gnash::sprite_instance::STOP) {
+       if (m.get_play_state() == gnash::sprite_instance::STOP) {
            // Kick the movie.
            printf("kicking movie, kick ct = %d\n", kick_count);
-           m->goto_frame(last_frame + 1);
-           m->set_play_state(gnash::sprite_instance::PLAY);
+           m.goto_frame(last_frame + 1);
+           m.set_play_state(gnash::sprite_instance::PLAY);
            kick_count++;
            
            if (kick_count > 10) {
                printf("movie is stalled; giving up on playing it through.\n");
                break;
            }
-       } else if (m->get_current_frame() < last_frame) {
+       } else if (m.get_current_frame() < last_frame)  {
            // Hm, apparently we looped back.  Skip ahead...
            printf("loop back; jumping to frame " SIZET_FMT "\n", last_frame);
-           m->goto_frame(last_frame + 1);
+           m.goto_frame(last_frame + 1);
        } else {
            kick_count = 0;
        }

Index: server/drag_state.h
===================================================================
RCS file: server/drag_state.h
diff -N server/drag_state.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/drag_state.h 6 Dec 2006 10:21:32 -0000       1.1
@@ -0,0 +1,126 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+/* $Id: drag_state.h,v 1.1 2006/12/06 10:21:32 strk Exp $ */
+
+
+#ifndef GNASH_DRAG_STATE_H
+#define GNASH_DRAG_STATE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rect.h" // for composition
+#include "smart_ptr.h" // we keep character being dragged by intrusive_ptr
+//#include "character.h" // for dtor visibility by intrusive_ptr ?
+
+namespace gnash
+{
+
+// Forward declarations
+class character;
+
+
+/// What is being dragged and how
+class drag_state
+{
+
+       bool _hasbounds;
+
+       /// Boundaries to constraint the drag into.
+       /// Coordinates in TWIPS.
+       /// TODO: use Range2d<float> directly ?
+       rect _bounds;
+
+       boost::intrusive_ptr<character> _character;
+
+       bool    _lock_centered;
+
+public:
+
+       bool isLockCentered() const {
+               return _lock_centered;
+       }
+
+       void setLockCentered(bool lock) {
+               _lock_centered = lock;
+       }
+
+       bool hasBounds() const {
+               return _hasbounds;
+       }
+
+       /// \brief
+       /// Get the boundaries to constraint
+       /// the drag into.
+       //
+       /// Coordinates of the rectangle are
+       /// expected in TWIPS.
+       ///
+       /// Note that if hasBounds() is false
+       /// the returned rectangle is the NULL
+       /// rectangle - see rect::is_null().
+       ///
+       const rect& getBounds() const {
+               return _bounds;
+       }
+
+       /// \brief
+       /// Set the boundaries to constraint
+       /// the drag into.
+       //
+       /// Coordinates of the rectangle are
+       /// expected in TWIPS.
+       ///
+       void setBounds(const rect& bounds) {
+               _bounds = bounds;
+               _hasbounds = true;
+       }
+
+       /// May return NULL !!
+       character* getCharacter() {
+               return _character.get();
+       }
+
+       /// Stores character in an intrusive pointer
+       void setCharacter(character* ch) {
+               _character = ch;
+       }
+
+       /// Reset drag state to its initial condition
+       void reset()
+       {
+               _character = NULL;
+               _hasbounds = false;
+               _bounds.set_null();
+               _lock_centered = false;
+       }
+
+       drag_state()
+               :
+               _hasbounds(false),
+               _bounds(),
+               _character(0),
+               _lock_centered(false)
+       {
+       }
+};
+
+
+} // namespace gnash
+
+#endif // GNASH_DRAG_STATE_H

Index: testsuite/DummyMovieDefinition.h
===================================================================
RCS file: testsuite/DummyMovieDefinition.h
diff -N testsuite/DummyMovieDefinition.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ testsuite/DummyMovieDefinition.h    6 Dec 2006 10:21:32 -0000       1.1
@@ -0,0 +1,170 @@
+// 
+//   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+// 
+//
+
+
+#ifndef GNASH_DUMMYMOVIEDEFINITION_H
+#define GNASH_DUMMYMOVIEDEFINITION_H
+
+#include "movie_definition.h" // for inheritance
+#include "rect.h" // for composition
+#include "movie_instance.h" // for create_movie_instance
+
+#include <string>
+#include <memory> // for auto_ptr
+
+// Forward declarations
+namespace gnash {
+       class bitmap_character_def;
+}
+
+namespace gnash
+{
+
+/// A dummy movie definition, for use by unit tests
+//
+/// This class provides implementation of all virtual
+/// methods of movie_definition by returning user-defined
+/// values for version/size/frame rate etc..
+///
+/// The create_instance function will return the same
+/// object created by createEmptyMovieClip() calls
+/// (an empty movieclip... still to be designed)
+///
+class DummyMovieDefinition : public movie_definition
+{
+       int _version;
+       rect _framesize;
+       size_t _framecount;
+       std::vector<PlayList> _playlist;
+       float _framerate;
+       std::string _url;
+
+public:
+
+
+       /// Default constructor
+       //
+       /// Will be initialized with the following values
+       ///
+       ///  - SWF version 6
+       ///  - 640x480 size
+       ///  - Single frame (unlabeled)
+       ///  - 12 FPS
+       ///  - 0 bytes (for get_bytes_loaded()/get_bytes_total())
+       ///  - empty url
+       ///
+       DummyMovieDefinition()
+               :
+               _version(6),
+               _framesize(0, 0, 640*20, 480*20),
+               _framecount(1),
+               _playlist(_framecount),
+               _framerate(12),
+               _url()
+       {
+       }
+
+       /// Overloaded constructor for specifying target version
+       //
+       /// This is particularly useful for unit tests.
+       /// All but the target version will be initialized
+       /// exactly as with the default constructor.
+       ///
+       DummyMovieDefinition(int version)
+               :
+               _version(version),
+               _framesize(0, 0, 640*20, 480*20),
+               _framecount(1),
+               _playlist(_framecount),
+               _framerate(12),
+               _url()
+       {
+       }
+
+       virtual int     get_version() const {
+               return _version;
+       }
+
+       virtual float   get_width_pixels() const {
+               return _framesize.width()/20;
+       }
+
+       virtual float   get_height_pixels() const {
+               return _framesize.height()/20;
+       }
+
+       virtual size_t  get_frame_count() const {
+               return _framecount;
+       }
+
+       virtual float   get_frame_rate() const {
+               return _framerate;
+       }
+
+       virtual const rect& get_frame_size() const {
+               return _framesize;
+       }
+
+       virtual const rect& get_bound() const {
+               return _framesize;
+       }
+
+       virtual size_t get_bytes_loaded() const {
+               return 0;
+       }
+
+       virtual size_t get_bytes_total() const {
+               return 0;
+       }
+       
+       /// Create a playable sprite instance from a def.
+       virtual sprite_instance* create_instance()
+       {
+               return create_movie_instance();
+       }
+
+       /// Create a playable movie instance from a def.
+       virtual movie_instance* create_movie_instance()
+       {
+               return new movie_instance(this, NULL);
+       }
+       
+       virtual const PlayList& get_playlist(size_t frame_number) {
+               assert ( frame_number < _playlist.size() );
+               return _playlist[frame_number];
+       }
+
+       //
+       // For use during creation.
+       //
+
+       /// Returns 1 based index. Ex: if 1 then 1st frame as been fully loaded
+       virtual size_t  get_loading_frame() const  {
+               return 1;
+       }
+
+       virtual const std::string& get_url() const {
+               return _url;
+       }
+
+};
+
+} // namespace gnash
+
+#endif // GNASH_DUMMYMOVIEDEFINITION_H




reply via email to

[Prev in Thread] Current Thread [Next in Thread]