[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r11619: Fix Keyboard handling so tha
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r11619: Fix Keyboard handling so that it can work with AS3 and AS2. |
Date: |
Thu, 12 Nov 2009 12:30:16 +0100 |
User-agent: |
Bazaar (1.16.1) |
------------------------------------------------------------
revno: 11619 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2009-11-12 12:30:16 +0100
message:
Fix Keyboard handling so that it can work with AS3 and AS2.
modified:
libcore/BitmapMovie.cpp
libcore/MovieClip.cpp
libcore/MovieFactory.h
libcore/asobj/Globals.cpp
libcore/asobj/flash/ui/Keyboard_as.cpp
libcore/asobj/flash/ui/Keyboard_as.h
libcore/movie_root.cpp
libcore/movie_root.h
=== modified file 'libcore/BitmapMovie.cpp'
--- a/libcore/BitmapMovie.cpp 2009-11-08 12:53:30 +0000
+++ b/libcore/BitmapMovie.cpp 2009-11-12 07:43:03 +0000
@@ -29,7 +29,7 @@
{
assert(def);
assert(object);
- Bitmap* bm = new Bitmap(getRoot(*object), 0, def, this);
+ Bitmap* bm = new Bitmap(stage(), 0, def, this);
const int depth = 1 + DisplayObject::staticDepthOffset;
placeDisplayObject(bm, depth);
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2009-11-10 07:52:58 +0000
+++ b/libcore/MovieClip.cpp 2009-11-12 08:04:11 +0000
@@ -61,14 +61,10 @@
#include "DisplayObjectContainer.h"
#include "Global_as.h"
-// TODO: get rid of this include.
-#include "flash/display/MovieClip_as.h"
-
#include <vector>
#include <string>
#include <algorithm> // for std::swap
#include <boost/algorithm/string/case_conv.hpp>
-//#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
namespace gnash {
=== modified file 'libcore/MovieFactory.h'
--- a/libcore/MovieFactory.h 2009-07-13 09:04:26 +0000
+++ b/libcore/MovieFactory.h 2009-11-12 09:03:35 +0000
@@ -53,10 +53,6 @@
///
/// @@ this explanation/functionality could be clearer!
///
- /// This calls add_ref() on the newly created definition; call
- /// drop_ref() when you're done with it.
- /// Or use boost::intrusive_ptr<T> from base/smart_ptr.h if you want.
- ///
/// If real_url is given, the movie's url will be set to that value.
///
/// @param url
=== modified file 'libcore/asobj/Globals.cpp'
--- a/libcore/asobj/Globals.cpp 2009-10-23 15:28:46 +0000
+++ b/libcore/asobj/Globals.cpp 2009-11-12 10:47:18 +0000
@@ -521,7 +521,8 @@
NS_GLOBAL, 5))
(N(textformat_class_init, NSV::CLASS_TEXT_FORMAT, NSV::CLASS_OBJECT,
NS_GLOBAL, 5))
- (N(Keyboard_as::init, NSV::CLASS_KEY, NSV::CLASS_OBJECT, NS_GLOBAL, 5))
+ (N(keyboard_class_init, NSV::CLASS_KEY, NSV::CLASS_OBJECT,
+ NS_GLOBAL, 5))
(N(AsBroadcaster::init, NSV::CLASS_AS_BROADCASTER, NSV::CLASS_OBJECT,
NS_GLOBAL, 5))
(N(textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT,
NSV::CLASS_OBJECT,
@@ -679,7 +680,7 @@
// UI classes
(N(mouse_class_init, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT,
NSV::NS_FLASH_UI, 5))
- (N(Keyboard_as::init, st.find("Keyboard"), NSV::CLASS_OBJECT,
+ (N(keyboard_class_init, st.find("Keyboard"), NSV::CLASS_OBJECT,
NSV::NS_FLASH_UI, 5))
(N(contextmenu_class_init, NSV::CLASS_CONTEXTMENU, NSV::CLASS_OBJECT,
NSV::NS_FLASH_UI, 7))
=== modified file 'libcore/asobj/flash/ui/Keyboard_as.cpp'
--- a/libcore/asobj/flash/ui/Keyboard_as.cpp 2009-10-23 06:25:25 +0000
+++ b/libcore/asobj/flash/ui/Keyboard_as.cpp 2009-11-12 10:47:18 +0000
@@ -37,105 +37,13 @@
#include "GnashKey.h"
#include "GnashException.h" // for ActionException
+#include <bitset>
+
namespace gnash {
-Keyboard_as::Keyboard_as()
- :
- as_object(getObjectInterface()),
- _unreleasedKeys(0),
- _lastKeyEvent(0)
-{
- // Key is a broadcaster only in SWF6 and up (correct?)
- int swfversion = getSWFVersion(*this);
- if ( swfversion > 5 )
- {
- AsBroadcaster::initialize(*this);
- }
-}
-
-bool
-Keyboard_as::is_key_down(int keycode)
-{
- // caller must check this
- assert (keycode >= 0 && keycode < key::KEYCOUNT);
-
- if (_unreleasedKeys.test(keycode)) return true;
- return false;
-}
-
-void
-Keyboard_as::set_key_down(key::code code)
-{
- if (code >= key::KEYCOUNT)
- {
- // programmatic error, as only movie_root calls us
- log_error("Key_as::set_key_down(%d): code out of range", code);
- return;
- }
-
- // This is used for getAscii() of the last key event, so we store
- // the unique gnash::key::code.
- _lastKeyEvent = code;
-
- // Key.isDown() only cares about flash keycode, not DisplayObject, so
- // we lookup keycode to add to _unreleasedKeys.
- size_t keycode = key::codeMap[code][key::KEY];
-
-#ifdef GNASH_DEBUG_KEYEVENTS
- log_debug("Key_as::set_key_down(%d): setting unreleased keycode %d (from
code %d)", keycode, code);
-#endif
- _unreleasedKeys.set(keycode, 1);
-}
-
-void
-Keyboard_as::set_key_up(key::code code)
-{
- if (code >= key::KEYCOUNT)
- {
- // programmatic error, as only movie_root calls us
- log_error("Key_as::set_key_up(%d): code out of range", code);
- return;
- }
-
- // This is used for getAscii() of the last key event, so we store
- // the unique gnash::key::code.
- _lastKeyEvent = code;
-
- // Key.isDown() only cares about flash keycode, not DisplayObject, so
- // we lookup keycode to add to _unreleasedKeys.
- size_t keycode = key::codeMap[code][key::KEY];
-
-#ifdef GNASH_DEBUG_KEYEVENTS
- log_debug("Key_as::set_key_down(%d): setting released keycode %d (from
code %d)", keycode, code);
-#endif
- _unreleasedKeys.set(keycode, 0);
-}
-
-
-void
-Keyboard_as::notify_listeners(const event_id& ev)
-{
- // There is no user defined "onKeyPress" event handler
- if((ev.id() != event_id::KEY_DOWN) &&
- (ev.id() != event_id::KEY_UP)) return;
-
-#ifdef GNASH_DEBUG_KEYEVENTS
- log_debug("notify_listeners calling broadcastMessage with arg %s", ev);
-#endif
- callMethod(NSV::PROP_BROADCAST_MESSAGE, ev.functionName());
-}
-
-int
-Keyboard_as::get_last_key() const
-{
- return _lastKeyEvent;
-}
-
as_value
-key_is_accessible(const fn_call& fn)
+key_is_accessible(const fn_call& /*fn*/)
{
- Keyboard_as* ptr = ensure<ThisIs<Keyboard_as> >(fn);
- UNUSED(ptr);
log_unimpl("Key.isAccessible");
return as_value();
}
@@ -145,10 +53,8 @@
as_value
key_get_ascii(const fn_call& fn)
{
- Keyboard_as* ko = ensure<ThisIs<Keyboard_as> >(fn);
-
- int code = ko->get_last_key();
-
+ movie_root& mr = getRoot(fn);
+ const key::code code = mr.lastKeyEvent();
return as_value(gnash::key::codeMap[code][key::ASCII]);
}
@@ -156,10 +62,8 @@
as_value
key_get_code(const fn_call& fn)
{
- Keyboard_as* ko = ensure<ThisIs<Keyboard_as> >(fn);
-
- int code = ko->get_last_key();
-
+ movie_root& mr = getRoot(fn);
+ const key::code code = mr.lastKeyEvent();
return as_value(key::codeMap[code][key::KEY]);
}
@@ -167,27 +71,27 @@
as_value
key_is_down(const fn_call& fn)
{
- Keyboard_as* ko = ensure<ThisIs<Keyboard_as> >(fn);
- if (fn.nargs < 1)
- {
+ if (fn.nargs < 1) {
IF_VERBOSE_ASCODING_ERRORS(
log_aserror(_("Key.isDown needs one argument (the key code)"));
);
return as_value();
}
- int keycode = fn.arg(0).to_int();
- if (keycode < 0 || keycode >= key::KEYCOUNT)
- {
+ const int keycode = fn.arg(0).to_int();
+ if (keycode < 0 || keycode >= key::KEYCOUNT) {
// AS coding error !
IF_VERBOSE_ASCODING_ERRORS(
- log_aserror("Key.isKeyDown(%d): keycode out of range", keycode);
+ log_aserror("Key.isKeyDown(%d): keycode out of range", keycode);
);
return as_value(false);
}
- return as_value(ko->is_key_down(keycode));
+ movie_root& mr = getRoot(fn);
+ const movie_root::Keys& keys = mr.unreleasedKeys();
+
+ return as_value(keys.test(keycode));
}
/// \brief
@@ -202,19 +106,6 @@
return as_value(false);
}
-#ifdef GNASH_USE_GC
-void
-Keyboard_as::markReachableResources() const
-{
- markAsObjectReachable();
- for (Listeners::const_iterator i=_listeners.begin(), e=_listeners.end();
- i != e; ++i)
- {
- (*i)->setReachable();
- }
-}
-#endif // def GNASH_USE_GC
-
void
registerKeyboardNative(as_object& global)
{
@@ -225,21 +116,15 @@
vm.registerNative(key_is_toggled, 800, 3);
}
-// extern (used by Global.cpp)
void
-Keyboard_as::init(as_object& where, const ObjectURI& uri)
+attachKeyboardInterface(as_object& o)
{
-
- // Create built-in key object.
- // NOTE: _global.Key *is* an object, not a constructor
- as_object* key_obj = new Keyboard_as;
-
const int flags = PropFlags::readOnly |
PropFlags::dontDelete |
PropFlags::dontEnum;
// constants
-#define KEY_CONST(k) key_obj->init_member(#k, key::codeMap[key::k][key::KEY],
flags)
+#define KEY_CONST(k) o.init_member(#k, key::codeMap[key::k][key::KEY], flags)
KEY_CONST(BACKSPACE);
KEY_CONST(CAPSLOCK);
KEY_CONST(CONTROL);
@@ -262,18 +147,31 @@
// methods
- VM& vm = getVM(where);
+ VM& vm = getVM(o);
+ Global_as& gl = getGlobal(o);
+
+ o.init_member("getAscii", vm.getNative(800, 0), flags);
+ o.init_member("getCode", vm.getNative(800, 1), flags);
+ o.init_member("isDown", vm.getNative(800, 2), flags);
+ o.init_member("isToggled", vm.getNative(800, 3), flags);
+ o.init_member("isAccessible",
+ gl.createFunction(key_is_accessible), flags);
+}
+
+// extern (used by Global.cpp)
+void
+keyboard_class_init(as_object& where, const ObjectURI& uri)
+{
+ as_object* key = registerBuiltinObject(where, attachKeyboardInterface,
+ uri);
+
+ /// Handles addListener, removeListener, and _listeners.
+ AsBroadcaster::initialize(*key);
+
+ // All properties are protected using ASSetPropFlags.
Global_as& gl = getGlobal(where);
-
- key_obj->init_member("getAscii", vm.getNative(800, 0), flags);
- key_obj->init_member("getCode", vm.getNative(800, 1), flags);
- key_obj->init_member("isDown", vm.getNative(800, 2), flags);
- key_obj->init_member("isToggled", vm.getNative(800, 3), flags);
- key_obj->init_member("isAccessible",
- gl.createFunction(key_is_accessible), flags);
-
- where.init_member(getName(uri), key_obj, as_object::DefaultFlags,
- getNamespace(uri));
+ as_object* null = 0;
+ gl.callMethod(NSV::PROP_AS_SET_PROP_FLAGS, key, null, 7);
}
} // gnash namespace
=== modified file 'libcore/asobj/flash/ui/Keyboard_as.h'
--- a/libcore/asobj/flash/ui/Keyboard_as.h 2009-07-29 13:50:30 +0000
+++ b/libcore/asobj/flash/ui/Keyboard_as.h 2009-11-12 10:47:18 +0000
@@ -24,59 +24,12 @@
#include "gnashconfig.h"
#endif
-#include "smart_ptr.h" // GNASH_USE_GC
-#include "as_object.h" // for inheritance
-#include "GnashKey.h" // for key::code
-#include "dsodefs.h"
-#include <bitset>
-
namespace gnash {
-// Forward declarations
-class event_id;
-
-class Keyboard_as : public as_object
-{
-protected:
-
-#ifdef GNASH_USE_GC
- // Mark all key listeners as reachable
- void markReachableResources() const;
-#endif // def GNASH_USE_GC
-
-public:
-
- Keyboard_as();
- static void init(as_object& where, const ObjectURI& uri);
- // Pass SWF keycode, returns true if currently pressed.
- bool is_key_down(int keycode);
-
- // Pass gnash::key::code. Changes m_last_key_event
- // and adds appropriate SWF keycode to bit array of keys
- // pressed (_unreleasedKeys)
- void set_key_down(key::code code);
-
- // Pass gnash::key::code. Changes m_last_key_event
- // and removes appropriate SWF keycode from bit array of keys
- // pressed (_unreleasedKeys)
- void set_key_up(key::code code);
-
- int get_last_key() const;
-
- /// Responsible for user defined key events handlers only;
- /// take over both DisplayObjects and non-DisplayObjects object.
- void notify_listeners(const event_id& key_event_type);
-
-private:
- /// bit-array for recording the unreleased keys
- std::bitset<key::KEYCOUNT> _unreleasedKeys;
-
- typedef std::list<boost::intrusive_ptr<as_object> > Listeners;
- Listeners _listeners;
-
- int _lastKeyEvent;
-};
-
+class as_object;
+class ObjectURI;
+
+void keyboard_class_init(as_object& global, const ObjectURI& uri);
void registerKeyboardNative(as_object& global);
} // gnash namespace
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2009-11-10 20:16:03 +0000
+++ b/libcore/movie_root.cpp 2009-11-12 10:47:18 +0000
@@ -35,7 +35,6 @@
#include "GnashAlgorithm.h"
#include "GnashNumeric.h"
#include "Global_as.h"
-#include "flash/ui/Keyboard_as.h"
#include "utf8.h"
#include "LoadableObject.h"
#include "IOChannel.h"
@@ -45,6 +44,7 @@
#include <iostream>
#include <string>
#include <map>
+#include <bitset>
#include <typeinfo>
#include <cassert>
#include <functional> // std::bind2nd, std::equal_to
@@ -82,6 +82,7 @@
namespace {
bool generate_mouse_button_events(movie_root& mr, MouseButtonState& ms);
const DisplayObject* getNearestObject(const DisplayObject* o);
+ as_object* getBuiltinObject(movie_root& mr, string_table::key cl);
}
}
@@ -120,8 +121,8 @@
m_mouse_y(0),
m_mouse_buttons(0),
_lastTimerId(0),
+ _lastKeyEvent(key::INVALID),
_currentFocus(0),
- m_time_remainder(0.0f),
m_drag_state(),
_movies(),
_rootMovie(0),
@@ -520,8 +521,8 @@
clearLoadMovieRequests();
// remove key/mouse listeners
- m_key_listeners.clear();
- m_mouse_listeners.clear();
+ _keyListeners.clear();
+ _mouseListeners.clear();
// Cleanup the stack.
_vm.getStack().clear();
@@ -534,33 +535,6 @@
setInvalidated();
}
-as_object*
-movie_root::getSelectionObject() const
-{
- // This can never be null, though it is possible to override the
- // reference to _global in AS2. If that makes a difference, we should
- // look up the object by path (_global.Selection) rather than using
- // the stored global object.
- Global_as& gl = *_vm.getGlobal();
-
- as_value s;
- if (!gl.get_member(NSV::CLASS_SELECTION, &s)) return 0;
-
- as_object* sel = s.to_object(gl);
-
- return sel;
-}
-
-as_object*
-movie_root::getStageObject()
-{
- as_value v;
- assert (VM::isInitialized());
- Global_as& gl = *_vm.getGlobal();
- if (!gl.get_member(NSV::PROP_iSTAGE, &v) ) return 0;
- return v.to_object(gl);
-}
-
void
movie_root::set_display_viewport(int x0, int y0, int w, int h)
{
@@ -573,7 +547,7 @@
if (_scaleMode == noScale) {
//log_debug("Rescaling disabled");
- as_object* stage = getStageObject();
+ as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
if (stage) {
log_debug("notifying Stage listeners about a resize");
stage->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
@@ -596,86 +570,40 @@
}
-Keyboard_as*
-movie_root::getKeyObject()
-{
- Global_as& gl = *_vm.getGlobal();
-
- as_value kval;
- if (!gl.get_member(NSV::CLASS_KEY, &kval)) return 0;
-
- as_object* obj = kval.to_object(gl);
- return dynamic_cast<Keyboard_as*>(obj);
-}
-
-as_object*
-movie_root::getMouseObject()
-{
- Global_as& gl = *_vm.getGlobal();
-
- as_value val;
- if (!gl.get_member(NSV::CLASS_MOUSE, &val)) return 0;
- return val.to_object(gl);
-}
-
-
-Keyboard_as*
-movie_root::notify_global_key(key::code k, bool down)
-{
- // NOTE: we don't check SWF version here
- // because even if the top-level movie was
- // an SWF4, it could have loaded an SWF5+
- // which would need to query Key object.
- // Testcase: http://www.ferryhalim.com/orisinal/g3/00dog.swf
-
- Keyboard_as* keyobject = getKeyObject();
- if (keyobject) {
- if (down) keyobject->set_key_down(k);
- else keyobject->set_key_up(k);
- }
- else
- {
- log_error("gnash::notify_key_event(): _global.Key doesn't "
- "exist, or isn't the expected built-in");
- }
-
- return keyobject;
-}
bool
movie_root::notify_key_event(key::code k, bool down)
{
- //
- // First of all, notify the _global.Key object about key event
- //
- Keyboard_as* global_key = notify_global_key(k, down);
+ _lastKeyEvent = k;
+ const size_t keycode = key::codeMap[k][key::KEY];
+ if (keycode < key::KEYCOUNT) {
+ _unreleasedKeys.set(keycode, down);
+ }
// Notify DisplayObject key listeners for clip key events
notify_key_listeners(k, down);
// Notify both DisplayObject and non-DisplayObject Key listeners
- // for user defined handerlers.
- if (global_key)
- {
- try
- {
+ // for user defined handers.
+ as_object* key = getBuiltinObject(*this, NSV::CLASS_KEY);
+ if (key) {
+
+ try {
// Can throw an action limit exception if the stack limit is 0
or 1,
// i.e. if the stack is at the limit before it contains
anything.
// A stack limit like that is hardly of any use, but could be used
// maliciously to crash Gnash.
- if(down)
- {
- global_key->notify_listeners(event_id::KEY_DOWN);
- global_key->notify_listeners(event_id::KEY_PRESS);
+ if (down) {
+ key->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onKeyDown");
}
- else
- {
- global_key->notify_listeners(event_id::KEY_UP);
+ else {
+ key->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onKeyUp");
}
}
catch (ActionLimitException &e)
{
- log_error(_("ActionLimits hit notifying key listeners: %s."),
e.what());
+ log_error(_("ActionLimits hit notifying key listeners: %s."),
+ e.what());
clearActionQueue();
}
}
@@ -1035,7 +963,7 @@
-void movie_root::cleanupUnloadedListeners(CharacterList& ll)
+void movie_root::cleanupUnloadedListeners(Listeners& ll)
{
bool needScan;
@@ -1054,7 +982,7 @@
needScan=false;
// remove unloaded DisplayObject listeners from movie_root
- for (CharacterList::iterator iter = ll.begin(); iter != ll.end(); )
+ for (Listeners::iterator iter = ll.begin(); iter != ll.end(); )
{
DisplayObject* const ch = *iter;
if ( ch->unloaded() )
@@ -1083,28 +1011,24 @@
}
-void movie_root::notify_key_listeners(key::code k, bool down)
+void
+movie_root::notify_key_listeners(key::code k, bool down)
{
- // log_debug("Notifying %d DisplayObject Key listeners",
- // m_key_listeners.size());
- KeyListeners copy = m_key_listeners;
- for (CharacterList::iterator iter = copy.begin(), itEnd=copy.end();
+ Listeners copy = _keyListeners;
+ for (Listeners::iterator iter = copy.begin(), itEnd=copy.end();
iter != itEnd; ++iter)
{
// sprite, button & input_edit_text DisplayObjects
DisplayObject* const ch = *iter;
- if ( ! ch->unloaded() )
- {
- if(down)
- {
+ if (!ch->unloaded()) {
+ if (down) {
// KEY_UP and KEY_DOWN events are unrelated to
any key!
ch->notifyEvent(event_id(event_id::KEY_DOWN,
key::INVALID));
// Pass the unique Gnash key code!
ch->notifyEvent(event_id(event_id::KEY_PRESS,
k));
}
- else
- {
+ else {
ch->notifyEvent(event_id(event_id::KEY_UP,
key::INVALID));
}
}
@@ -1112,15 +1036,14 @@
assert(testInvariant());
- if ( ! copy.empty() )
- {
+ if (!copy.empty()) {
// process actions queued in the above step
processActionQueue();
}
}
void
-movie_root::add_listener(CharacterList& ll, DisplayObject* listener)
+movie_root::add_listener(Listeners& ll, DisplayObject* listener)
{
assert(listener);
@@ -1132,7 +1055,7 @@
void
-movie_root::remove_listener(CharacterList& ll, DisplayObject* listener)
+movie_root::remove_listener(Listeners& ll, DisplayObject* listener)
{
assert(listener);
ll.remove_if(std::bind2nd(std::equal_to<DisplayObject*>(), listener));
@@ -1142,8 +1065,8 @@
movie_root::notify_mouse_listeners(const event_id& event)
{
- CharacterList copy = m_mouse_listeners;
- for (CharacterList::iterator iter = copy.begin(), itEnd=copy.end();
+ Listeners copy = _mouseListeners;
+ for (Listeners::iterator iter = copy.begin(), itEnd=copy.end();
iter != itEnd; ++iter)
{
DisplayObject* const ch = *iter;
@@ -1153,7 +1076,7 @@
}
}
- as_object* mouseObj = getMouseObject();
+ as_object* mouseObj = getBuiltinObject(*this, NSV::CLASS_MOUSE);
if (mouseObj) {
try {
@@ -1227,7 +1150,7 @@
getObject(to)->callMethod(NSV::PROP_ON_SET_FOCUS, getObject(from));
}
- as_object* sel = getSelectionObject();
+ as_object* sel = getBuiltinObject(*this, NSV::CLASS_SELECTION);
// Notify Selection listeners with previous and new focus as arguments.
// Either argument may be null.
@@ -1424,11 +1347,10 @@
callInterface("Stage.align");
if (notifyResize) {
- as_object* stage = getStageObject();
+ as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
if (stage) {
log_debug("notifying Stage listeners about a resize");
- stage->callMethod(NSV::PROP_BROADCAST_MESSAGE,
- "onResize");
+ stage->callMethod(NSV::PROP_BROADCAST_MESSAGE, "onResize");
}
}
}
@@ -1438,7 +1360,7 @@
{
_displayState = ds;
- as_object* stage = getStageObject();
+ as_object* stage = getBuiltinObject(*this, NSV::PROP_iSTAGE);
if (stage) {
log_debug("notifying Stage listeners about fullscreen state");
const bool fs = _displayState == DISPLAYSTATE_FULLSCREEN;
@@ -1786,8 +1708,8 @@
// NOTE: cleanupUnloadedListeners should have cleaned up all unloaded
// key listeners. The remaining ones should be marked by their parents
#if GNASH_PARANOIA_LEVEL > 1
- for (LiveChars::const_iterator i=m_key_listeners.begin(),
- e=m_key_listeners.end(); i!=e; ++i) {
+ for (LiveChars::const_iterator i=_keyListeners.begin(),
+ e=_keyListeners.end(); i!=e; ++i) {
assert((*i)->isReachable());
}
#endif
@@ -1796,8 +1718,8 @@
// unloaded mouse listeners. The remaining ones should be marked by
// their parents
#if GNASH_PARANOIA_LEVEL > 1
- for (LiveChars::const_iterator i = m_mouse_listeners.begin(),
- e = m_mouse_listeners.end(); i!=e; ++i) {
+ for (LiveChars::const_iterator i = _mouseListeners.begin(),
+ e = _mouseListeners.end(); i!=e; ++i) {
assert((*i)->isReachable());
}
#endif
@@ -2480,20 +2402,6 @@
return "<no iface to hosting app>";
}
-void
-movie_root::addChild(DisplayObject* ch)
-{
- setInvalidated();
- _rootMovie->addChild(ch);
-}
-
-void
-movie_root::addChildAt(DisplayObject* ch, int depth)
-{
- setInvalidated();
- _rootMovie->addChildAt(ch, depth);
-}
-
short
stringToStageAlign(const std::string& str)
{
@@ -2646,6 +2554,17 @@
}
}
+as_object*
+getBuiltinObject(movie_root& mr, string_table::key cl)
+{
+ Global_as& gl = *mr.getVM().getGlobal();
+
+ as_value val;
+ if (!gl.get_member(cl, &val)) return 0;
+ return val.to_object(gl);
+}
+
+
}
=== modified file 'libcore/movie_root.h'
--- a/libcore/movie_root.h 2009-11-10 18:45:16 +0000
+++ b/libcore/movie_root.h 2009-11-12 10:48:38 +0000
@@ -109,7 +109,6 @@
class Timer;
class MovieClip;
class VirtualClock;
- class Keyboard_as;
class IOChannel;
}
@@ -157,6 +156,8 @@
typedef std::list<LoadCallback> LoadCallbacks;
+ typedef std::bitset<key::KEYCOUNT> Keys;
+
/// Default constructor
//
/// Make sure to call setRootMovie()
@@ -439,13 +440,13 @@
/// Push a new DisplayObject listener for key events
void add_key_listener(DisplayObject* listener)
{
- add_listener(m_key_listeners, listener);
+ add_listener(_keyListeners, listener);
}
/// Remove a DisplayObject listener for key events
void remove_key_listener(DisplayObject* listener)
{
- remove_listener(m_key_listeners, listener);
+ remove_listener(_keyListeners, listener);
}
/// Notify still loaded DisplayObject listeners for mouse events
@@ -454,13 +455,13 @@
/// Push a new DisplayObject listener for mouse events
void add_mouse_listener(DisplayObject* listener)
{
- add_listener(m_mouse_listeners, listener);
+ add_listener(_mouseListeners, listener);
}
/// Remove a DisplayObject listener for mouse events
void remove_mouse_listener(DisplayObject* listener)
{
- remove_listener(m_mouse_listeners, listener);
+ remove_listener(_mouseListeners, listener);
}
/// Get the DisplayObject having focus
@@ -625,8 +626,8 @@
/// - Mouse entities (m_mouse_button_state)
/// - Timer targets (_intervalTimers)
/// - Resources reachable by ActionQueue code (_actionQueue)
- /// - Key listeners (m_key_listeners)
- /// - Mouse listeners (m_mouse_listeners)
+ /// - Key listeners (_keyListeners)
+ /// - Mouse listeners (_mouseListeners)
/// - Any DisplayObject being dragged
///
void markReachableResources() const;
@@ -737,6 +738,13 @@
/// returned
bool isLevelTarget(const std::string& name, unsigned int& levelno);
+ key::code lastKeyEvent() const {
+ return _lastKeyEvent;
+ }
+
+ const std::bitset<key::KEYCOUNT>& unreleasedKeys() const {
+ return _unreleasedKeys;
+ }
/// Set a filedescriptor to use for host application requests
/// (for browser communication mostly)
@@ -875,22 +883,6 @@
const RunResources& runResources() const { return _runResources; }
- /// Add a DisplayObject child on top depth
- //
- /// @param ch
- /// The child DisplayObject to add
- void addChild(DisplayObject* ch);
-
- /// Add a DisplayObject child at given depth
- //
- /// @param ch
- /// The child DisplayObject to add
- ///
- /// @param depth
- /// The depth to add the child to
- ///
- void addChildAt(DisplayObject* ch, int depth);
-
private:
/// Set the root movie, replacing the current one if any.
@@ -1034,11 +1026,7 @@
void processCompletedLoadMovieRequests();
/// Listeners container
- typedef std::list<DisplayObject*> CharacterList;
-
- /// key and mouse listeners container
- typedef CharacterList KeyListeners;
- typedef CharacterList MouseListeners;
+ typedef std::list<DisplayObject*> Listeners;
/// Take care of dragging, if needed
void doMouseDrag();
@@ -1058,39 +1046,25 @@
/// Execute expired timers
void executeTimers();
- /// Notify the global Key ActionScript object about a key status change
- Keyboard_as* notify_global_key(key::code k, bool down);
-
/// Remove unloaded key and mouselisteners.
void cleanupUnloadedListeners()
{
- cleanupUnloadedListeners(m_key_listeners);
- cleanupUnloadedListeners(m_mouse_listeners);
+ cleanupUnloadedListeners(_keyListeners);
+ cleanupUnloadedListeners(_mouseListeners);
}
/// Erase unloaded DisplayObjects from the given listeners list
- static void cleanupUnloadedListeners(CharacterList& ll);
+ static void cleanupUnloadedListeners(Listeners& ll);
- /// Cleanup references to unloaded DisplayObjects and run the garbage
collector.
+ /// Cleanup references to unloaded DisplayObjects and run the GC.
void cleanupAndCollect();
/// Push a DisplayObject listener to the front of given container, if not
/// already present
- static void add_listener(CharacterList& ll, DisplayObject* elem);
+ static void add_listener(Listeners& ll, DisplayObject* elem);
/// Remove a listener from the list
- static void remove_listener(CharacterList& ll, DisplayObject* elem);
-
- /// Return the current Stage object
- //
- /// Can return NULL if it's been deleted or not
- /// yet initialized.
- as_object* getStageObject();
-
- /// Return the singleton Selection object
- //
- /// Can return 0 if it's been deleted.
- as_object* getSelectionObject() const;
+ static void remove_listener(Listeners& ll, DisplayObject* elem);
/// This function should return TRUE iff any action triggered
/// by the event requires redraw, see \ref events_handling for
@@ -1137,12 +1111,6 @@
/// its name to _level<num>
void setLevel(unsigned int num, Movie* movie);
- /// Return the global Key object
- Keyboard_as* getKeyObject();
-
- /// Return the global Mouse object
- as_object* getMouseObject();
-
/// Boundaries of the Stage are always world boundaries
/// and are only invalidated by changes in the background
/// color.
@@ -1226,17 +1194,20 @@
TimerMap _intervalTimers;
unsigned int _lastTimerId;
+ /// bit-array for recording the unreleased keys
+ std::bitset<key::KEYCOUNT> _unreleasedKeys;
+
+ key::code _lastKeyEvent;
+
/// Characters for listening key events
- KeyListeners m_key_listeners;
+ Listeners _keyListeners;
/// Objects listening for mouse events (down,up,move)
- MouseListeners m_mouse_listeners;
+ Listeners _mouseListeners;
/// The DisplayObject currently holding focus, or 0 if no focus.
DisplayObject* _currentFocus;
- float m_time_remainder;
-
/// @todo fold this into m_mouse_button_state?
drag_state m_drag_state;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11619: Fix Keyboard handling so that it can work with AS3 and AS2.,
Benjamin Wolsey <=