? .LOG.swp
? ASOBJSTRING.PATCH
? BROKEN
? ChangeLog-bogus
? ChangeLog-good
? ChangeLog.gen
? ERR
? LOG
? NativeMCprops.patch
? NonFiniteAssert.patch
? P
? P2
? StringTableDebugging.patch
? TODO.STRK
? arrayTest.as
? cl
? config.h.in
? intllibs.patch
? libltdl
? loadDebugging.patch
? log
? movie_root.ConstructLiveChars.PATCH
? t
? libbase/ChangeLog
? libbase/png.cpp
? libbase/png.h
? plugin/ChildRequestParsing.patch
? server/.Property.h.swp
? server/edit_text_character.cpp-noTextFieldVars
? server/edit_text_character.h-noTextFieldVars
? server/sprite_instance.cpp-noTextFieldVars
? server/sprite_instance.h-noTextFieldVars
? server/asobj/System.Capabilities.txt
? testsuite/actionscript.all/ASnative.as
? testsuite/actionscript.all/MovieClipLoaderData.as
? testsuite/media/RMS.flv
? testsuite/misc-ming.all/P
? testsuite/misc-ming.all/isMaskTest.as
? testsuite/misc-ming.all/masks_test3.c
? testsuite/movies.all/gravity-embedded.flm
Index: server/Property.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/Property.cpp,v
retrieving revision 1.8
diff -u -r1.8 Property.cpp
--- server/Property.cpp	28 Feb 2008 07:26:42 -0000	1.8
+++ server/Property.cpp	5 Mar 2008 16:15:26 -0000
@@ -44,7 +44,7 @@
 	if (mDestructive)
 	{
 		as_function *f = a->mGetter;
-		as_value ret = (*f)(fn);
+		as_value ret = f ? (*f)(fn) : a->cGetter(fn);
 		// The getter might have called the setter, and we should not override.
 		if (mDestructive)
 		{
@@ -53,7 +53,7 @@
 		}
 		return ret;
 	}
-	return (*a->mGetter)(fn);
+	return a->mGetter ? (*a->mGetter)(fn) : a->cGetter(fn);
 
 	as_value v;	
 	VM::get().getMachine()->immediateFunction(a->mGetter, 
@@ -89,12 +89,14 @@
 	as_environment env;
 	env.push(value);
 	fn_call fn(&this_ptr, &env, 1, 0);
-	(*a->mSetter)(fn);
+	if ( a->mSetter ) (*a->mSetter)(fn);
+	else a->cSetter(fn);
+
 
 	return;
 
 	// TODO: Push value
-	VM::get().getMachine()->immediateProcedure(a->mSetter,
+	VM::get().getMachine()->immediateProcedure(a->mSetter, // could be ->cSetter ...
 		const_cast<as_object*>(&this_ptr), 1, 0);
 }
 
@@ -103,7 +105,9 @@
 {
 	if (isGetterSetter())
 	{
-		boost::get<as_accessors>(&mBound)->mSetter = func;
+		as_accessors* a = boost::get<as_accessors>(&mBound);
+		a->cSetter = 0;
+		a->mSetter = func;
 	}
 	else
 		mBound = as_accessors(NULL, func);
@@ -114,7 +118,9 @@
 {
 	if (isGetterSetter())
 	{
-		boost::get<as_accessors>(&mBound)->mGetter = func;
+		as_accessors* a = boost::get<as_accessors>(&mBound);
+		a->cGetter = 0;
+		a->mGetter = func;
 	}
 	else
 		mBound = as_accessors(func, NULL);
Index: server/Property.h
===================================================================
RCS file: /sources/gnash/gnash/server/Property.h,v
retrieving revision 1.21
diff -u -r1.21 Property.h
--- server/Property.h	5 Mar 2008 03:55:58 -0000	1.21
+++ server/Property.h	5 Mar 2008 16:15:26 -0000
@@ -33,6 +33,8 @@
 
 namespace gnash {
 
+typedef as_value (*as_c_function_ptr)(const fn_call& fn);
+
 class as_function;
 class PropertyList;
 
@@ -80,8 +82,15 @@
 
 	as_value underlyingValue;
 
+	as_c_function_ptr cGetter;
+	as_c_function_ptr cSetter;
+
 	as_accessors(as_function* getter, as_function* setter) : mGetter(getter),
-		mSetter(setter), underlyingValue(), beingAccessed(false)
+		mSetter(setter), underlyingValue(), cGetter(0), cSetter(0), beingAccessed(false)
+	{/**/}
+
+	as_accessors(as_c_function_ptr getter, as_c_function_ptr setter) : mGetter(0),
+		mSetter(0), underlyingValue(), cGetter(getter), cSetter(setter), beingAccessed(false)
 	{/**/}
 
 	void markReachableResources() const;
@@ -172,6 +181,13 @@
 		mOrderId(0)
 	{/**/}
 
+	Property(string_table::key name, string_table::key nsId,
+		as_c_function_ptr getter, as_c_function_ptr setter, bool destroy = false) :
+		_flags(), mBound(as_accessors(getter, setter)), mDestructive(destroy),
+		mName(name), mNamespace(nsId),
+		mOrderId(0)
+	{/**/}
+
 	/// accessor to the properties flags
 	const as_prop_flags& getFlags() const { return _flags; }
 	as_prop_flags& getFlags() { return _flags; }
Index: server/PropertyList.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/PropertyList.cpp,v
retrieving revision 1.29
diff -u -r1.29 PropertyList.cpp
--- server/PropertyList.cpp	19 Feb 2008 19:20:52 -0000	1.29
+++ server/PropertyList.cpp	5 Mar 2008 16:15:27 -0000
@@ -364,6 +364,34 @@
 }
 
 bool
+PropertyList::addGetterSetter(string_table::key key, as_c_function_ptr getter,
+	as_c_function_ptr setter, string_table::key nsId)
+{
+	Property a(key, nsId, getter, setter);
+	a.setOrder(- ++mDefaultOrder - 1);
+
+	container::iterator found = iterator_find(_props, key, nsId);
+	if (found != _props.end())
+	{
+		// copy flags from previous member (even if it's a normal member ?)
+		as_prop_flags& f = a.getFlags();
+		f = found->getFlags();
+
+		_props.replace(found, a);
+		assert ( iterator_find(_props, key, nsId) != _props.end() );
+
+	}
+	else
+	{
+		_props.insert(a);
+        	assert ( iterator_find(_props, key, nsId) != _props.end() );
+	}
+
+
+	return true;
+}
+
+bool
 PropertyList::addDestructiveGetterSetter(string_table::key key,
 	as_function& getter, as_function& setter, string_table::key nsId)
 {
Index: server/PropertyList.h
===================================================================
RCS file: /sources/gnash/gnash/server/PropertyList.h,v
retrieving revision 1.23
diff -u -r1.23 PropertyList.h
--- server/PropertyList.h	19 Feb 2008 19:20:52 -0000	1.23
+++ server/PropertyList.h	5 Mar 2008 16:15:27 -0000
@@ -284,6 +284,27 @@
 		as_function& setter, string_table::key ns = 0);
 
 	/// \brief
+	/// Add a getter/setter property, if not already existing
+	/// (or should we allow override ?)
+	//
+	/// @param key
+	///	Name of the property. Search is case-*sensitive*
+	///
+	/// @param getter
+	///	A function to invoke when this property value is requested.
+	///	add_ref will be called on the function.
+	///
+	/// @param setter
+	///	A function to invoke when setting this property's value.
+	///	add_ref will be called on the function.
+	///
+	/// @return true if the property was successfully added, false
+	///         otherwise (property already existent?)
+	///
+	bool addGetterSetter(string_table::key key, as_c_function_ptr getter,
+		as_c_function_ptr setter, string_table::key ns = 0);
+
+	/// \brief
 	/// Add a destructive getter/setter property, if not already extant.
 	///
 	/// @param key
Index: server/as_object.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.cpp,v
retrieving revision 1.99
diff -u -r1.99 as_object.cpp
--- server/as_object.cpp	19 Feb 2008 19:20:52 -0000	1.99
+++ server/as_object.cpp	5 Mar 2008 16:15:27 -0000
@@ -87,6 +87,14 @@
 	return _members.addGetterSetter(st.find(PROPNAME(name)), getter, setter);
 }
 
+bool
+as_object::add_property(const std::string& name, as_c_function_ptr getter,
+		as_c_function_ptr setter)
+{
+	string_table &st = _vm.getStringTable();
+	return _members.addGetterSetter(st.find(PROPNAME(name)), getter, setter);
+}
+
 /*protected*/
 bool
 as_object::get_member_default(string_table::key name, as_value* val,
@@ -455,7 +463,6 @@
 {
 	string_table::key k = _vm.getStringTable().find(PROPNAME(key));
 	init_property(k, getter, setter, flags, nsname);
-
 }
 
 void
@@ -475,6 +482,31 @@
 
 }
 
+void
+as_object::init_property(const std::string& key, as_c_function_ptr getter,
+		as_c_function_ptr setter, int flags, string_table::key nsname)
+{
+	string_table::key k = _vm.getStringTable().find(PROPNAME(key));
+	init_property(k, getter, setter, flags, nsname);
+}
+
+void
+as_object::init_property(string_table::key key, as_c_function_ptr getter,
+		as_c_function_ptr setter, int flags, string_table::key nsname)
+{
+	bool success;
+	success = _members.addGetterSetter(key, getter, setter, nsname);
+
+	// We shouldn't attempt to initialize a property twice, should we ?
+	assert(success);
+
+	//log_debug(_("Initialized property '%s'"), name.c_str());
+
+	// TODO: optimize this, don't scan again !
+	_members.setFlags(key, flags, nsname);
+
+}
+
 bool
 as_object::init_destructive_property(string_table::key key, as_function& getter,
 	as_function& setter, int flags, string_table::key nsname)
@@ -498,6 +530,17 @@
 	assert(_members.getProperty(k, nsname));
 }
 
+void
+as_object::init_readonly_property(const std::string& key, as_c_function_ptr getter,
+	int initflags, string_table::key nsname)
+{
+	string_table::key k = _vm.getStringTable().find(PROPNAME(key));
+
+	init_property(k, getter, getter, initflags | as_prop_flags::readOnly
+		| as_prop_flags::isProtected, nsname);
+	assert(_members.getProperty(k, nsname));
+}
+
 std::string
 as_object::asPropName(string_table::key name)
 {
Index: server/as_object.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_object.h,v
retrieving revision 1.93
diff -u -r1.93 as_object.h
--- server/as_object.h	19 Feb 2008 19:20:52 -0000	1.93
+++ server/as_object.h	5 Mar 2008 16:15:27 -0000
@@ -339,6 +339,36 @@
 		string_table::key nsname = 0);
 
 	/// \brief
+	/// Initialize a getter/setter property by name
+	//
+	/// This is just a wrapper around the other init_property method
+	/// used as a trampoline to avoid changing all classes to 
+	/// use string_table::key directly.
+	///
+	/// @param key
+	///     Name of the property.
+	///	Will be converted to lowercase if VM is initialized for SWF6 or lower.
+	///
+	/// @param getter
+	///	A function to invoke when this property value is requested.
+	///	add_ref will be called on the function.
+	///
+	/// @param setter
+	///	A function to invoke when setting this property's value.
+	///	add_ref will be called on the function.
+	///
+	/// @param flags
+	///     Flags for the new member. By default dontDelete and dontEnum.
+	///	See as_prop_flags::Flags.
+	///
+	/// @param nsname
+	/// The id of the namespace to which this member belongs. 0 is a wildcard
+	/// and will be matched by anything not asking for a specific namespace.
+	void init_property(const std::string& key, as_c_function_ptr getter,
+		as_c_function_ptr setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+		string_table::key nsname = 0);
+
+	/// \brief
 	/// Initialize a getter/setter property by key
 	//
 	/// This method has to be used by built-in classes initialization
@@ -367,6 +397,35 @@
 		as_function& setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
 		string_table::key nsname = 0);
 
+	/// \brief
+	/// Initialize a getter/setter property by key
+	//
+	/// This method has to be used by built-in classes initialization
+	/// (VM initialization in general) as will avoid to scan the
+	/// inheritance chain.
+	///
+	/// @param key
+	///     Key of the property.
+	///
+	/// @param getter
+	///	A function to invoke when this property value is requested.
+	///	add_ref will be called on the function.
+	///
+	/// @param setter
+	///	A function to invoke when setting this property's value.
+	///	add_ref will be called on the function.
+	///
+	/// @param flags
+	///     Flags for the new member. By default dontDelete and dontEnum.
+	///	See as_prop_flags::Flags.
+	///
+	/// @param nsname
+	/// The id of the namespace to which this member belongs. 0 is a wildcard
+	/// and will be matched by anything not asking for a specific namespace.
+	void init_property(string_table::key key, as_c_function_ptr getter,
+		as_c_function_ptr setter, int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+		string_table::key nsname = 0);
+
 
 	/// \brief
 	/// Initialize a destructive getter/setter property
@@ -418,6 +477,24 @@
 			int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
 			string_table::key nsname = 0);
 
+	/// \brief
+	/// Use this method for read-only properties.
+	//
+	/// This method achieves the same as the above init_property method.
+	/// Additionally, it sets the property as read-only so that a default
+	/// handler will be triggered when ActionScript attempts to set the
+	/// property.
+	/// 
+	/// The arguments are the same as the above init_property arguments,
+	/// although the setter argument is omitted.
+	///
+	/// @param nsname
+	/// The id of the namespace to which this member belongs. 0 is a wildcard
+	/// and will be matched by anything not asking for a specific namespace.
+	void init_readonly_property(const std::string& key, as_c_function_ptr getter,
+			int flags=as_prop_flags::dontDelete|as_prop_flags::dontEnum,
+			string_table::key nsname = 0);
+
 	/// Get a member as_value by name
 	//
 	/// The default behaviour is to call set_member_default,
@@ -783,6 +860,29 @@
 	bool add_property(const std::string& key, as_function& getter,
 		as_function& setter);
 
+	/// \brief
+	/// Add a getter/setter property, if no member already has
+	/// that name (or should we allow override ? TODO: check this)
+	//
+	/// @param key
+	///     Name of the property.
+	///	Case insensitive up to SWF6,
+	///	case *sensitive* from SWF7 up.
+	///
+	/// @param getter
+	///	A function to invoke when this property value is requested.
+	///	add_ref will be called on the function.
+	///
+	/// @param setter
+	///	A function to invoke when setting this property's value.
+	///	add_ref will be called on the function.
+	///
+	/// @return true if the property was successfully added, false
+	///         otherwise (property already existent?)
+	///
+	bool add_property(const std::string& key, as_c_function_ptr getter,
+		as_c_function_ptr setter);
+
 	/// Return this object '__proto__' member.
 	//
 	/// The __proto__ member is the exported interface ('prototype')
Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.482
diff -u -r1.482 sprite_instance.cpp
--- server/sprite_instance.cpp	4 Mar 2008 11:04:35 -0000	1.482
+++ server/sprite_instance.cpp	5 Mar 2008 16:15:28 -0000
@@ -2008,8 +2008,6 @@
 {
   //int target_version = o.getVM().getSWFVersion();
 
-  boost::intrusive_ptr<builtin_function> gettersetter;
-
   // This is a normal property, can be overridden, deleted and enumerated
   // See swfdec/test/trace/movieclip-version-#.swf for why we only initialize this
   // if we don't have a parent
@@ -2019,6 +2017,10 @@
   // Properties (TODO: move to appropriate SWF version section)
   //
   
+#if 0
+
+  boost::intrusive_ptr<builtin_function> gettersetter;
+
   gettersetter = new builtin_function(&character::x_getset, NULL);
   o.init_property("_x", *gettersetter, *gettersetter);
 
@@ -2085,24 +2087,76 @@
   gettersetter = new builtin_function(&sprite_soundbuftime_getset, NULL);
   o.init_property("_soundbuftime", *gettersetter, *gettersetter);
 
-#if 0
-  gettersetter = new builtin_function(&character::onrollover_getset, NULL);
-  o.init_property("onRollOver", *gettersetter, *gettersetter);
+#else
+
+  as_c_function_ptr gettersetter;
+
+  gettersetter = character::x_getset;
+  o.init_property("_x", gettersetter, gettersetter);
+
+  gettersetter = character::y_getset;
+  o.init_property("_y", gettersetter, gettersetter);
+
+  gettersetter = character::xscale_getset;
+  o.init_property("_xscale", gettersetter, gettersetter);
+
+  gettersetter = character::yscale_getset;
+  o.init_property("_yscale", gettersetter, gettersetter);
+
+  gettersetter = character::xmouse_get;
+  o.init_readonly_property("_xmouse", gettersetter);
+
+  gettersetter = character::ymouse_get;
+  o.init_readonly_property("_ymouse", gettersetter);
+
+  gettersetter = character::alpha_getset;
+  o.init_property("_alpha", gettersetter, gettersetter);
+
+  gettersetter = character::visible_getset;
+  o.init_property("_visible", gettersetter, gettersetter);
+
+  gettersetter = character::width_getset;
+  o.init_property("_width", gettersetter, gettersetter);
+
+  gettersetter = character::height_getset;
+  o.init_property("_height", gettersetter, gettersetter);
+
+  gettersetter = character::rotation_getset;
+  o.init_property("_rotation", gettersetter, gettersetter);
+
+  gettersetter = character::parent_getset;
+  o.init_property("_parent", gettersetter, gettersetter);
+
+  gettersetter = sprite_currentframe_get;
+  o.init_property("_currentframe", gettersetter, gettersetter);
+
+  gettersetter = sprite_totalframes_get;
+  o.init_property("_totalframes", gettersetter, gettersetter);
+
+  gettersetter = sprite_framesloaded_get;
+  o.init_property("_framesloaded", gettersetter, gettersetter);
+
+  gettersetter = character::target_getset;
+  o.init_property("_target", gettersetter, gettersetter);
+
+  gettersetter = character::name_getset;
+  o.init_property("_name", gettersetter, gettersetter);
+
+  gettersetter = sprite_droptarget_getset;
+  o.init_property("_droptarget", gettersetter, gettersetter);
 
-  gettersetter = new builtin_function(&character::onrollout_getset, NULL);
-  o.init_property("onRollOut", *gettersetter, *gettersetter);
+  gettersetter = sprite_url_getset;
+  o.init_property("_url", gettersetter, gettersetter);
 
-  gettersetter = new builtin_function(&character::onload_getset, NULL);
-  o.init_property("onLoad", *gettersetter, *gettersetter);
+  gettersetter = sprite_highquality_getset;
+  o.init_property("_highquality", gettersetter, gettersetter);
 
-  gettersetter = new builtin_function(&character::onmouseup_getset, NULL);
-  o.init_property("onMouseUp", *gettersetter, *gettersetter);
+  gettersetter = sprite_focusrect_getset;
+  o.init_property("_focusrect", gettersetter, gettersetter);
 
-  gettersetter = new builtin_function(&character::onmousedown_getset, NULL);
-  o.init_property("onMouseDown", *gettersetter, *gettersetter);
+  gettersetter = sprite_soundbuftime_getset;
+  o.init_property("_soundbuftime", gettersetter, gettersetter);
 
-  gettersetter = new builtin_function(&character::onmousemove_getset, NULL);
-  o.init_property("onMouseMove", *gettersetter, *gettersetter);
 #endif
 
 }
