gnash-commit
[Top][All Lists]
Advanced

[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;
 


reply via email to

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