gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo...
Date: Thu, 29 Mar 2007 12:37:31 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/03/29 12:37:31

Modified files:
        .              : ChangeLog 
        server         : movie_root.cpp movie_root.h 
        server/asobj   : Stage.cpp Stage.h 
        testsuite/actionscript.all: Stage.as 
        utilities      : Makefile.am 

Log message:
                * server/movie_root.{cpp,h}: support for
                  setting scaleMode (allow scaling) and
                  notifying Stage listeners when disabled.
                * server/asobj/Stage.{cpp,h}: rework layout,
                  implement addListener, removeListener and
                  scaleMode.
                * testsuite/actionscript.all/Stage.as: add a few
                  tests for Stage. The notification-based tests
                  are not automatically run yet (will need a MovieTester
                  test runner, with new interfaces to it for resize request)
                * utilities/Makefile.am: add libgnashasobjs, now needed.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2716&r2=1.2717
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.41&r2=1.42
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Stage.cpp?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Stage.h?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Stage.as?cvsroot=gnash&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/Makefile.am?cvsroot=gnash&r1=1.48&r2=1.49

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2716
retrieving revision 1.2717
diff -u -b -r1.2716 -r1.2717
--- ChangeLog   29 Mar 2007 11:42:46 -0000      1.2716
+++ ChangeLog   29 Mar 2007 12:37:31 -0000      1.2717
@@ -1,3 +1,17 @@
+2007-03-29 Sandro Santilli <address@hidden>
+
+       * server/movie_root.{cpp,h}: support for
+         setting scaleMode (allow scaling) and
+         notifying Stage listeners when disabled.
+       * server/asobj/Stage.{cpp,h}: rework layout,
+         implement addListener, removeListener and
+         scaleMode.
+       * testsuite/actionscript.all/Stage.as: add a few
+         tests for Stage. The notification-based tests
+         are not automatically run yet (will need a MovieTester
+         test runner, with new interfaces to it for resize request)
+       * utilities/Makefile.am: add libgnashasobjs, now needed.
+
 2007-03-29 Ann Barcomb <address@hidden>
 
        * devtools/testsuite/tabs.t: added check for hard tabs in 

Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- server/movie_root.cpp       27 Mar 2007 14:52:05 -0000      1.45
+++ server/movie_root.cpp       29 Mar 2007 12:37:31 -0000      1.46
@@ -32,6 +32,7 @@
 #include "VM.h"
 #include "tu_random.h"
 #include "ExecutableCode.h"
+#include "Stage.h"
 
 #include <iostream>
 #include <string>
@@ -76,7 +77,8 @@
        m_on_event_load_progress_called(false),
        m_active_input_text(NULL),
        m_time_remainder(0.0f),
-       m_drag_state()
+       m_drag_state(),
+       _allowRescale(true)
 {
 }
 
@@ -100,6 +102,16 @@
        assert(testInvariant());
 }
 
+boost::intrusive_ptr<Stage>
+movie_root::getStageObject()
+{
+       as_value v;
+       if ( ! VM::isInitialized() ) return NULL;
+       as_object* global = VM::get().getGlobal();
+       if ( ! global ) return NULL;
+       if ( ! global->get_member("Stage", &v) ) return NULL;
+       return boost::dynamic_pointer_cast<Stage>(v.to_object());
+}
                
 void
 movie_root::set_display_viewport(int x0, int y0, int w, int h)
@@ -111,15 +123,26 @@
     m_viewport_width = w;
     m_viewport_height = h;
 
+       if ( _allowRescale ) // Recompute pixel scale.
+       {
+               log_msg("Rescaling allowed");
+
     // should we cache this ? it's immutable after all !
     const rect& frame_size = _movie->get_frame_size();
 
-    // Recompute pixel scale.
-
     float      scale_x = m_viewport_width / 
TWIPS_TO_PIXELS(frame_size.width());
     float      scale_y = m_viewport_height / 
TWIPS_TO_PIXELS(frame_size.height());
     m_pixel_scale = fmax(scale_x, scale_y);
 
+       }
+       else // rescale not allowed, notify Stage (if any)
+       {
+               log_msg("Rescaling disabled");
+               boost::intrusive_ptr<Stage> stage = getStageObject();
+               // how do I get the environment from ??
+               if ( stage ) stage->onResize(NULL);
+       }
+
        assert(testInvariant());
 }
 

Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -b -r1.41 -r1.42
--- server/movie_root.h 27 Mar 2007 14:52:05 -0000      1.41
+++ server/movie_root.h 29 Mar 2007 12:37:31 -0000      1.42
@@ -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.41 2007/03/27 14:52:05 strk Exp $ */
+/* $Id: movie_root.h,v 1.42 2007/03/29 12:37:31 strk Exp $ */
 
 /// \page events_handling Handling of user events
 ///
@@ -85,6 +85,7 @@
 // Forward declarations
 namespace gnash {
        class ExecutableCode; // for ActionQueue
+       class Stage;
 }
 
 namespace gnash
@@ -147,8 +148,29 @@
                return false;
        }
 
+       /// Change display viewport coordinates
+       //
+       /// This currently also change the display scale
+       /// but we should instead only do it if rescaling
+       /// is allowed.
+       ///
        void set_display_viewport(int x0, int y0, int w, int h);
 
+       /// Set whether rescaling is allowed or not.
+       //
+       /// When rescaling is not allowed the Stage listeners
+       /// will get notified on any resize attempt.
+       ///
+       void allowRescaling(bool v)
+       {
+               _allowRescale=v;
+       }
+
+       bool isRescalingAllowed()
+       {
+               return _allowRescale;
+       }
+
        /// \brief
         /// The host app can use this to tell the movie when
         /// user's mouse pointer has moved.
@@ -391,6 +413,13 @@
 
 private:
 
+       /// Return the current Stage object
+       //
+       /// Can return NULL if it's been deleted or not
+       /// yet initialized.
+       ///
+       boost::intrusive_ptr<Stage> getStageObject();
+
        typedef boost::ptr_list<ExecutableCode> ActionQueue;
 
        ActionQueue _actionQueue;
@@ -453,6 +482,9 @@
        ///
         bool fire_mouse_event();
 
+       /// If set to false, no rescale should be performed
+       /// when changing viewport size
+       bool _allowRescale;
 };
 
 

Index: server/asobj/Stage.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Stage.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- server/asobj/Stage.cpp      19 Mar 2007 17:11:14 -0000      1.8
+++ server/asobj/Stage.cpp      29 Mar 2007 12:37:31 -0000      1.9
@@ -28,74 +28,211 @@
 #include "builtin_function.h" // need builtin_function
 #include "VM.h"
 
+#include <string>
+
 namespace gnash {
 
 as_value stage_addlistener(const fn_call& fn);
 as_value stage_removelistener(const fn_call& fn);
-as_value stage_ctor(const fn_call& fn);
+as_value stage_scalemode_getset(const fn_call& fn);
 
 static void
 attachStageInterface(as_object& o)
 {
-       if ( VM::get().getSWFVersion() > 5 )
-       {
+       if ( VM::get().getSWFVersion() < 6 ) return;
+
                o.init_member("addListener", new 
builtin_function(stage_addlistener));
                o.init_member("removeListener", new 
builtin_function(stage_removelistener));
+
+       boost::intrusive_ptr<builtin_function> getset(new 
builtin_function(stage_scalemode_getset));
+       o.init_property("scaleMode", *getset, *getset);
+}
+
+Stage::Stage()
+       :
+       _scaleMode(showAll)
+{
+       attachStageInterface(*this);
+}
+
+void
+Stage::onResize(as_environment* env)
+{
+       as_value v;
+       if ( get_member("scaleMode", &v) && v.to_std_string(env) == 
std::string("noScale") )
+       {
+               notifyResize(env);
        }
 }
 
-static as_object*
-getStageInterface()
+void
+Stage::notifyResize(as_environment* env)
 {
-       static boost::intrusive_ptr<as_object> o;
-       if ( ! o )
+       for (ListenersList::iterator it=_listeners.begin(),
+                       itEnd=_listeners.end();
+                       it != itEnd; ++it)
        {
-               o = new as_object();
-               attachStageInterface(*o);
+               if ( (*it)->get_ref_count() == 1 ) it=_listeners.erase(it);
+               else notifyResize(*it, env);
        }
-       return o.get();
 }
 
-class stage_as_object: public as_object
+/// Notify an object about an resize event
+void
+Stage::notifyResize(boost::intrusive_ptr<as_object> obj, as_environment* env)
 {
+       const std::string eventname = "onResize";
 
-public:
+       as_value method;
+       if ( ! obj->get_member(eventname, &method) ) {
+               // nothing to do
+               return;
+       }
 
-       stage_as_object()
-               :
-               as_object(getStageInterface())
-       {}
+       boost::intrusive_ptr<as_function> func = method.to_as_function();
+       if ( ! func ) return; // method is not a function
+
+       func->call(fn_call(obj.get(), env, 0, 0));
+}
 
-       // override from as_object ?
-       //const char* get_text_value() const { return "Stage"; }
+void
+Stage::addListener(boost::intrusive_ptr<as_object> obj)
+{
+       log_msg("Adding listener %p to Stage %p", obj.get(), this);
+       _listeners.push_back(obj);
+}
+
+void
+Stage::removeListener(boost::intrusive_ptr<as_object> obj)
+{
+       log_msg("Removing listener %p from Stage %p", obj.get(), this);
+       _listeners.remove(obj);
+}
+
+/// Remove listeners with a refcount == 1
+//
+/// This function should be called before marking
+/// objects to keep alive (when GC gets in effect)
+///
+void
+Stage::dropDanglingListeners()
+{
+       for (ListenersList::iterator it=_listeners.begin(),
+                       itEnd=_listeners.end();
+                       it != itEnd; ++it)
+       {
+               if ( (*it)->get_ref_count() == 1 ) it=_listeners.erase(it);
+       }
+}
+
+const char*
+Stage::getScaleModeString()
+{
+       static const char* modeName[] = {
+               "showAll",
+               "noScale",
+               "exactFill",
+               "noBorder" };
 
-       // override from as_object ?
-       //double get_numeric_value() const { return 0; }
-};
+       return modeName[_scaleMode];
+}
+
+void
+Stage::setScaleMode(ScaleMode mode)
+{
+       _scaleMode = mode;
 
-as_value stage_addlistener(const fn_call& /*fn*/) {
-    log_warning("%s: unimplemented \n", __FUNCTION__);
+       log_msg("Scale mode set to %s", getScaleModeString());
+       if ( _scaleMode == noScale )
+       {
+               log_msg("Setting rescaling allowance to false");
+               VM::get().getRoot().allowRescaling(false);
+       }
+}
+
+as_value stage_addlistener(const fn_call& fn)
+{
+       boost::intrusive_ptr<Stage> stage = ensureType<Stage>(fn.this_ptr);
+
+       if ( fn.nargs < 1 )
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+               log_aserror("Stage.addListener() needs one argument");
+               );
+               return as_value();
+       }
+
+       boost::intrusive_ptr<as_object> obj = fn.arg(0).to_object();
+       if ( ! obj )
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+               std::stringstream ss;
+               fn.dump_args(ss);
+               log_aserror("Invalid call to Stage.addListener(%s) : first arg 
doesn't cast to an object",
+                       ss.str().c_str());
+               );
+               return as_value();
+       }
+
+       stage->addListener(obj);
     return as_value();
 }
-as_value stage_removelistener(const fn_call& /*fn*/) {
-    log_warning("%s: unimplemented \n", __FUNCTION__);
+
+as_value stage_removelistener(const fn_call& fn)
+{
+       boost::intrusive_ptr<Stage> stage = ensureType<Stage>(fn.this_ptr);
+
+       if ( fn.nargs < 1 )
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+               log_aserror("Stage.removeListener() needs one argument");
+               );
+               return as_value();
+       }
+
+       boost::intrusive_ptr<as_object> obj = fn.arg(0).to_object();
+       if ( ! obj )
+       {
+               IF_VERBOSE_ASCODING_ERRORS(
+               std::stringstream ss;
+               fn.dump_args(ss);
+               log_aserror("Invalid call to Stage.removeListener(%s) : first 
arg doesn't cast to an object",
+                       ss.str().c_str());
+               );
+               return as_value();
+       }
+
+       stage->removeListener(obj);
     return as_value();
 }
 
-as_value
-stage_ctor(const fn_call& /* fn */)
+as_value stage_scalemode_getset(const fn_call& fn)
 {
-       boost::intrusive_ptr<as_object> obj = new stage_as_object;
+       boost::intrusive_ptr<Stage> stage = ensureType<Stage>(fn.this_ptr);
        
-       return as_value(obj.get()); // will keep alive
+       if ( fn.nargs == 0 ) // getter
+       {
+               return as_value(stage->getScaleModeString());
+       }
+       else // setter
+       {
+               Stage::ScaleMode mode = Stage::showAll;
+
+               std::string str = fn.arg(0).to_std_string(&(fn.env()));
+               if ( str == "noScale" ) mode = Stage::noScale;
+               else if ( str == "exactFill" ) mode = Stage::exactFill;
+               else if ( str == "noBorder" ) mode = Stage::noBorder;
+
+               stage->setScaleMode(mode);
+               return as_value();
+       }
 }
 
 // extern (used by Global.cpp)
 void stage_class_init(as_object& global)
 {
 
-       static boost::intrusive_ptr<as_object> obj = new as_object();
-       attachStageInterface(*obj);
+       static boost::intrusive_ptr<as_object> obj = new Stage();
        global.init_member("Stage", obj.get());
 
 }

Index: server/asobj/Stage.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Stage.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- server/asobj/Stage.h        20 Nov 2006 21:44:24 -0000      1.5
+++ server/asobj/Stage.h        29 Mar 2007 12:37:31 -0000      1.6
@@ -23,18 +23,94 @@
 #include "config.h"
 #endif
 
-#include <memory> // for auto_ptr
+#include "as_object.h" // for inheritance
+
+#include <list>
 
 namespace gnash {
 
-class as_object;
+/// This is the Stage ActionScript object.
+//
+/// It is currently not used as it should, in particular
+/// it should control resize behaviour, while it's not.
+///
+class Stage: public as_object
+{
+
+public:
+
+       typedef enum {
+               showAll,
+               noScale,
+               exactFill,
+               noBorder
+       } ScaleMode;
+
+       Stage();
+
+       // override from as_object ?
+       //const char* get_text_value() const { return "Stage"; }
+
+       // override from as_object ?
+       //double get_numeric_value() const { return 0; }
+       
+       void addListener(boost::intrusive_ptr<as_object> obj);
+
+       void removeListener(boost::intrusive_ptr<as_object> obj);
+
+       /// Recive a resize event.
+       //
+       /// @param env
+       ///     Environment to use for notifying listeners
+       ///
+       void onResize(as_environment* env);
+
+       /// Set scale mode 
+       void setScaleMode(ScaleMode mode);
+
+       /// \brief
+       /// Return the string representation for current
+       /// scale mode.
+       //
+       /// Valid values are:
+       ///     - showAll
+       ///     - noBorder
+       ///     - exactFit
+       ///     - noScale
+       ///
+       const char* getScaleModeString();
+
+private:
+
+       /// Notify all listeners about a resize event
+       //
+       /// @param env
+       ///     Environment to use for notifying listeners
+       ///
+       void notifyResize(as_environment* env);
+
+
+       /// Notify an object about an resize event
+       void notifyResize(boost::intrusive_ptr<as_object> obj, as_environment* 
env);
+
+       /// Remove listeners with a refcount == 1
+       //
+       /// This function should be called before marking
+       /// objects to keep alive (when GC gets in effect)
+       ///
+       void dropDanglingListeners();
+
+       typedef std::list<boost::intrusive_ptr<as_object> > ListenersList;
+
+       ListenersList _listeners;
+
+       ScaleMode _scaleMode;
+};
+
 
 /// Initialize the global Stage class
 void stage_class_init(as_object& global);
 
-/// Return a Stage instance (in case the core lib needs it)
-//std::auto_ptr<as_object> init_stage_instance();
-  
 } // end of gnash namespace
 
 // __GNASH_ASOBJ_STAGE_H__

Index: testsuite/actionscript.all/Stage.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Stage.as,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- testsuite/actionscript.all/Stage.as 28 Feb 2007 23:24:45 -0000      1.8
+++ testsuite/actionscript.all/Stage.as 29 Mar 2007 12:37:31 -0000      1.9
@@ -20,7 +20,7 @@
 // compile this test case with Ming makeswf, and then
 // execute it like this gnash -1 -r 0 -v out.swf
 
-rcsid="$Id: Stage.as,v 1.8 2007/02/28 23:24:45 strk Exp $";
+rcsid="$Id: Stage.as,v 1.9 2007/03/29 12:37:31 strk Exp $";
 
 #include "check.as"
 
@@ -29,6 +29,8 @@
 var stageObj = new Stage;
 check_equals (typeof(stageObj), 'undefined');
 
+check_equals(Stage.__proto__, Object.prototype);
+
 #if OUTPUT_VERSION > 5
 
 // test the Stage::addlistener method
@@ -36,6 +38,20 @@
 // test the Stage::removelistener method
 check_equals (typeof(Stage.removeListener), 'function');
 
+listener = new Object;
+listener.onResize = function() {
+       _root.note("Resize event received, args to handler: "+arguments.length);
+       // If we delete the Stage object, events won't arrive anymore, but
+       // the precedent setting of 'scaleMode' will persist !!
+       //delete Stage;
+};
+Stage.addListener(listener);
+
+// resize events are not sent unless scaleMode == "noScale"
+Stage.scaleMode = 5;
+check_equals(Stage.scaleMode, "showAll");
+Stage.scaleMode = "noScale";
+
 #else // OUTPUT_VERSION <= 5
 
 check_equals (typeof(Stage.addListener), 'undefined');

Index: utilities/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/utilities/Makefile.am,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -b -r1.48 -r1.49
--- utilities/Makefile.am       28 Mar 2007 23:42:20 -0000      1.48
+++ utilities/Makefile.am       29 Mar 2007 12:37:31 -0000      1.49
@@ -1,5 +1,5 @@
 # 
-#   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+#   Copyright (C) 2005, 2006, 2007 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
@@ -25,6 +25,7 @@
 
 GNASH_LIBS = \
        $(top_builddir)/server/libgnashserver.la \
+       $(top_builddir)/server/asobj/libgnashasobjs.la \
        $(top_builddir)/server/vm/libgnashvm.la \
        $(top_builddir)/libbase/libgnashbase.la \
        $(top_builddir)/libamf/libgnashamf.la




reply via email to

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