[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo...,
Sandro Santilli <=