gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-450-gcbd2c94
Date: Fri, 08 Jul 2011 06:51:56 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  cbd2c943540042c175f8a07cb0d21a06fafc3098 (commit)
       via  85dc4b2d054ffec6cbbbe9d5831c08b96225d9b5 (commit)
       via  3c9c5fc1dfd5b269b6cde4a6fec8ff1eba0273e3 (commit)
      from  ef15bcbffe6f448e6f7824d5ed0c1c98ec94c7dd (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=cbd2c943540042c175f8a07cb0d21a06fafc3098


commit cbd2c943540042c175f8a07cb0d21a06fafc3098
Merge: ef15bcb 85dc4b2
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Jul 8 08:04:27 2011 +0200

    Merge branch 'main'


http://git.savannah.gnu.org/cgit//commit/?id=85dc4b2d054ffec6cbbbe9d5831c08b96225d9b5


commit 85dc4b2d054ffec6cbbbe9d5831c08b96225d9b5
Author: Benjamin Wolsey <address@hidden>
Date:   Fri Jul 8 07:59:09 2011 +0200

    Add interface to check for a streaming sound.
    
    sound_handler::streamingSound() returns true if there is one, false if
    not. Add new test (the only one with a sound stream!) to check that it
    works.

diff --git a/libsound/sound_handler.cpp b/libsound/sound_handler.cpp
index 8a3a986..413d5e3 100644
--- a/libsound/sound_handler.cpp
+++ b/libsound/sound_handler.cpp
@@ -529,8 +529,7 @@ sound_handler::plugInputStream(std::auto_ptr<InputStream> 
newStreamer)
     InputStream* newStream = newStreamer.get(); // for debugging
 #endif
 
-    if ( ! _inputStreams.insert(newStreamer.release()).second )
-    {
+    if (!_inputStreams.insert(newStreamer.release()).second) {
         // this should never happen !
         log_error("_inputStreams container still has a pointer "
             "to deleted InputStream %p!", newStreamer.get());
@@ -639,7 +638,19 @@ sound_handler::setAudioDump(const std::string& wavefile)
     }
 }
 
-/*private*/
+bool
+sound_handler::streamingSound() const
+{
+    if (_streamingSounds.empty()) return false;
+    if (_inputStreams.empty()) return false;
+
+    for (StreamingSounds::const_iterator it = _streamingSounds.begin(), 
+            e = _streamingSounds.end(); it != e; ++it) {
+        if ((*it)->isPlaying()) return true;
+    }
+    return false;
+}
+
 void
 sound_handler::unplugCompletedInputStreams()
 {
diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 2fb50e4..9202a18 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -445,6 +445,11 @@ public:
     ///
     void setAudioDump(const std::string& wavefile);
 
+    /// Check if a streaming sound is playing.
+    //
+    /// @return true if any streaming sound is playing, false if not.
+    bool streamingSound() const;
+
 protected:
 
     sound_handler(media::MediaHandler* m)
diff --git a/testsuite/MovieTester.cpp b/testsuite/MovieTester.cpp
index 3a552d3..9d341b6 100644
--- a/testsuite/MovieTester.cpp
+++ b/testsuite/MovieTester.cpp
@@ -495,6 +495,13 @@ MovieTester::getInvalidatedRanges() const
     
 }
 
+bool
+MovieTester::streamingSound() const
+{
+    if (!_sound_handler.get()) return false;
+    return _sound_handler->streamingSound();
+}
+
 int
 MovieTester::soundsStarted()
 {
diff --git a/testsuite/MovieTester.h b/testsuite/MovieTester.h
index b34932b..ec6aff7 100644
--- a/testsuite/MovieTester.h
+++ b/testsuite/MovieTester.h
@@ -257,6 +257,9 @@ public:
        /// cursor in the current position.
        bool usingHandCursor();
 
+    /// Return true if a streaming sound is active, false if not.
+    bool streamingSound() const;
+
        /// \brief
        /// Return the number of times a sound has been stopped,
        /// or 0 if sound testing is not supported. See canTestSound().
diff --git a/testsuite/misc-ming.all/Makefile.am 
b/testsuite/misc-ming.all/Makefile.am
index e214a0a..d061881 100644
--- a/testsuite/misc-ming.all/Makefile.am
+++ b/testsuite/misc-ming.all/Makefile.am
@@ -171,6 +171,8 @@ check_PROGRAMS = \
 
 if MING_VERSION_0_4_3
 check_PROGRAMS += \
+       StreamSoundTest \
+       StreamSoundTestRunner \
        EmbeddedSoundTest \
        EmbeddedSoundTest-Runner \
        eventSoundTest1 \
@@ -1178,6 +1180,38 @@ EmbeddedSoundTest_Runner_DEPENDENCIES = \
        EmbeddedSoundTest.swf   \
        $(NULL)
 
+StreamSoundTest_SOURCES = \
+       StreamSoundTest.c \
+       $(NULL)
+
+StreamSoundTest_CFLAGS = \
+       -DMEDIADIR='"$(abs_mediadir)"' \
+       $(NULL)
+
+StreamSoundTest_LDADD = libgnashmingutils.la
+
+StreamSoundTest.swf: StreamSoundTest
+       ./StreamSoundTest $(abs_mediadir)
+
+StreamSoundTestRunner_SOURCES = \
+       StreamSoundTestRunner.cpp \
+       $(NULL)
+
+StreamSoundTestRunner_CXXFLAGS = \
+       -DSRCDIR='"$(srcdir)"' \
+       -DTGTDIR='"$(abs_builddir)"' \
+       $(NULL)
+
+StreamSoundTestRunner_LDADD = \
+       $(top_builddir)/testsuite/libtestsuite.la \
+       $(AM_LDFLAGS) \
+       $(NULL)
+
+StreamSoundTestRunner_DEPENDENCIES = \
+       $(top_builddir)/testsuite/libtestsuite.la \
+       StreamSoundTest.swf     \
+       $(NULL)
+
 BitmapSmoothingTest_SOURCES = \
        BitmapSmoothingTest.c \
        $(NULL)
@@ -1740,7 +1774,8 @@ TEST_CASES = \
 
 if MING_VERSION_0_4_3
 TEST_CASES += \
-    EmbeddedSoundTest-Runner \
+       StreamSoundTestRunner \
+       EmbeddedSoundTest-Runner \
        eventSoundTest1-Runner \
     $(NULL)
 endif
diff --git a/testsuite/misc-ming.all/StreamSoundTest.c 
b/testsuite/misc-ming.all/StreamSoundTest.c
new file mode 100644
index 0000000..a169f65
--- /dev/null
+++ b/testsuite/misc-ming.all/StreamSoundTest.c
@@ -0,0 +1,119 @@
+/* 
+ *   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
+ *   2011 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ */ 
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ming.h>
+#include <errno.h>
+
+#include "ming_utils.h"
+
+#define OUTPUT_VERSION 8
+#define OUTPUT_FILENAME "StreamSoundTest.swf"
+
+void addSoundExport(SWFMovie mo);
+
+void
+addSoundExport(SWFMovie mo)
+{
+    SWFSoundStream sounda;
+    SWFInput inp;
+
+    FILE* f;
+
+    f = fopen(MEDIADIR"/click.mp3", "r");
+
+    if (!f) {
+        perror(MEDIADIR"/click.mp3");
+        exit(EXIT_FAILURE);
+    }
+    
+    inp = newSWFInput_file(f);
+
+    sounda = newSWFSoundStream_fromInput(inp);
+
+    SWFMovie_setSoundStream(mo, sounda);
+}
+
+int
+main(int argc, char** argv)
+{
+       SWFMovie mo;
+       const char *srcdir=".";
+       SWFMovieClip  dejagnuclip;
+    SWFDisplayItem it;
+
+
+       /*********************************************
+        *
+        * Initialization
+        *
+        *********************************************/
+
+       if ( argc>1 ) srcdir=argv[1];
+       else
+       {
+               fprintf(stderr, "Usage: %s\n", argv[0]);
+               return 1;
+       }
+
+       puts("Setting things up");
+
+       Ming_init();
+    Ming_useSWFVersion(OUTPUT_VERSION);
+       Ming_setScale(20.0); /* let's talk pixels */
+ 
+       mo = newSWFMovie();
+       SWFMovie_setRate(mo, 0.5);
+       SWFMovie_setDimension(mo, 640, 400);
+
+       /*********************************************
+        *
+        * Body
+        *
+        *********************************************/
+
+       dejagnuclip = get_dejagnu_clip((SWFBlock)get_default_font(srcdir), 10,
+            0, 80, 800, 600);
+       it = SWFMovie_add(mo, (SWFBlock)dejagnuclip);
+
+    SWFMovie_add(mo, newSWFAction(
+            "_root.onEnterFrame = function() { trace('Frame'); };"
+            ));
+
+       SWFMovie_nextFrame(mo);  /* end of frame1 */
+       addSoundExport(mo);
+       SWFMovie_nextFrame(mo);  /* end of frame2 */
+       SWFMovie_nextFrame(mo);  /* end of frame3 */
+       SWFMovie_nextFrame(mo);  /* end of frame4 */
+       SWFMovie_nextFrame(mo);  /* end of frame5 */
+
+       /*****************************************************
+        *
+        * Output movie
+        *
+        *****************************************************/
+
+       puts("Saving " OUTPUT_FILENAME );
+
+       SWFMovie_save(mo, OUTPUT_FILENAME);
+
+       return 0;
+}
diff --git a/testsuite/misc-ming.all/StreamSoundTestRunner.cpp 
b/testsuite/misc-ming.all/StreamSoundTestRunner.cpp
new file mode 100644
index 0000000..b78e08f
--- /dev/null
+++ b/testsuite/misc-ming.all/StreamSoundTestRunner.cpp
@@ -0,0 +1,73 @@
+/* 
+ *   Copyright (C) 2007, 2008, 2009, 2010, 2011 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ */ 
+
+#define INPUT_FILENAME "StreamSoundTest.swf"
+
+#include "MovieTester.h"
+#include "MovieClip.h"
+#include "DisplayObject.h"
+#include "DisplayList.h"
+#include "log.h"
+#include "VM.h"
+
+#include "check.h"
+#include <string>
+#include <cassert>
+
+using namespace gnash;
+using namespace std;
+
+int
+main(int /*argc*/, char** /*argv*/)
+{
+       string filename = string(TGTDIR) + string("/") + string(INPUT_FILENAME);
+       MovieTester tester(filename);
+
+       gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
+       dbglogfile.setVerbosity(1);
+
+       MovieClip* root = tester.getRootMovie();
+       assert(root);
+
+    VM& vm = getVM(*getObject(root));
+
+    const size_t framecount = root->get_frame_count();
+
+    // Sanity.
+    check_equals(framecount, 5);
+
+       if (!tester.canTestSound()) {
+               cout << "UNTESTED: sounds can't be tested with this build." << 
endl;
+               return EXIT_SUCCESS; // so testing doesn't abort
+       } 
+
+    // Shouldn't be streaming yet.
+    check_equals(tester.streamingSound(), false);
+
+    // 20 x 0.75 seconds = 15 in total. The sound should last
+    // 13.74 seconds.
+    for (size_t i = 0; i < 20; ++i) {
+        if (root->get_current_frame() + 1 == framecount) break;
+        tester.advance();
+        check_equals(tester.streamingSound(), true);
+    }
+
+}
+
diff --git a/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp 
b/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
index 21653dc..edaf52e 100644
--- a/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
+++ b/testsuite/misc-ming.all/eventSoundTest1-Runner.cpp
@@ -98,8 +98,8 @@ main(int /*argc*/, char** /*argv*/)
        int test = 0;
        while (frame <= totalFrames) {
                as_value testReady;
-               if (getObject(root)->get_member(getURI(vm, "testReady"), 
&testReady))
-               {
+               if (getObject(root)->get_member(getURI(vm, "testReady"), 
&testReady)) {
+
                        getObject(root)->delProperty(getURI(vm, "testReady"));
                        
                        // When a test is ready, check the result of the 
previous test.
@@ -111,6 +111,7 @@ main(int /*argc*/, char** /*argv*/)
                        }
 
                        check_equals(tester.soundsStopped(), 
tester.soundsStarted());
+            check_equals(tester.streamingSound(), false);
                        ++test;
                        tester.click();
 
@@ -128,7 +129,8 @@ main(int /*argc*/, char** /*argv*/)
 
     // Consistency checking
     as_value eot;
-    bool endOfTestFound = getObject(root)->get_member(getURI(vm, "endoftest"), 
&eot);
+    bool endOfTestFound =
+        getObject(root)->get_member(getURI(vm, "endoftest"), &eot);
     check(endOfTestFound);
 
 }

http://git.savannah.gnu.org/cgit//commit/?id=3c9c5fc1dfd5b269b6cde4a6fec8ff1eba0273e3


commit 3c9c5fc1dfd5b269b6cde4a6fec8ff1eba0273e3
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jul 7 20:23:45 2011 +0200

    Rationalize event handling.
    
    Drop all-purpose event handling functions and replace with specific
    ones. TextField gets keyInput for handling user key presses.
    
    Move queueEvent to MovieClip; only ENTER_FRAME, LOAD, and INITIALIZE
    events were queued from MovieClip; only UNLOAD was queued from
    DisplayObject, but this event is only handled by MovieClip subclasses.
    
    Remove notifyEvent from DisplayObject, InteractiveObject, and
    TextField.
    
    Only MovieClips have a notifyEvent, which probably does more than it
    should. InteractiveObjects have only a mouseEvent (which in
    MovieClip is still handled by notifyEvent).

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index 4f2f9e0..251a4b3 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -354,7 +354,7 @@ Button::isEnabled()
 
 
 void
-Button::keyPress(const event_id& id)
+Button::keyPress(key::code c)
 {
     if (unloaded()) {
         // We don't respond to events while unloaded
@@ -362,11 +362,8 @@ Button::keyPress(const event_id& id)
         return; 
     }
 
-    assert(id.id() == event_id::KEY_PRESS);
-    assert(id.keyCode() != key::INVALID);
-
     ButtonActionPusher xec(stage(), this); 
-    _def->forEachTrigger(id, xec);
+    _def->forEachTrigger(event_id(event_id::KEY_PRESS, c), xec);
 }
 
 bool
diff --git a/libcore/Button.h b/libcore/Button.h
index 19f3509..3803f82 100644
--- a/libcore/Button.h
+++ b/libcore/Button.h
@@ -23,12 +23,13 @@
 #ifndef GNASH_BUTTON_H
 #define GNASH_BUTTON_H
 
-#include "InteractiveObject.h" // for inheritance
-
 #include <boost/intrusive_ptr.hpp>
 #include <vector>
 #include <set>
 
+#include "InteractiveObject.h" 
+#include "GnashKey.h"
+
 // Forward declarations.
 namespace gnash {
     namespace SWF {
@@ -37,86 +38,83 @@ namespace gnash {
 }
 
 namespace gnash {
-//
-// Button
-//
 
+/// Button implements Flash buttons.
 class Button : public InteractiveObject
 {
 public:
 
-       typedef std::vector<DisplayObject*> DisplayObjects;
-       typedef std::vector<const DisplayObject*> ConstDisplayObjects;
-       
+    typedef std::vector<DisplayObject*> DisplayObjects;
+    typedef std::vector<const DisplayObject*> ConstDisplayObjects;
+    
     /// A container for holding the id of active button records.
     typedef std::set<int> ActiveRecords;
 
-       enum mouse_flags
-       {
-               FLAG_IDLE = 0,
-               FLAG_OVER = 1,
-               FLAG_DOWN = 2,
-               OVER_DOWN = FLAG_OVER | FLAG_DOWN,
-
-               // aliases
-               OVER_UP = FLAG_OVER,
-               OUT_DOWN = FLAG_DOWN
-       };
-
-       enum MouseState
-       {
-               MOUSESTATE_UP = 0,
-               MOUSESTATE_DOWN,
-               MOUSESTATE_OVER,
-               MOUSESTATE_HIT
-       };
+    enum mouse_flags
+    {
+        FLAG_IDLE = 0,
+        FLAG_OVER = 1,
+        FLAG_DOWN = 2,
+        OVER_DOWN = FLAG_OVER | FLAG_DOWN,
+
+        // aliases
+        OVER_UP = FLAG_OVER,
+        OUT_DOWN = FLAG_DOWN
+    };
+
+    enum MouseState
+    {
+        MOUSESTATE_UP = 0,
+        MOUSESTATE_DOWN,
+        MOUSESTATE_OVER,
+        MOUSESTATE_HIT
+    };
 
     /// Construct a Button
     //
     /// A button should always have an associated object.
-       Button(as_object* object, const SWF::DefineButtonTag* def,
+    Button(as_object* object, const SWF::DefineButtonTag* def,
             DisplayObject* parent);
 
-       ~Button();
-       
+    ~Button();
+    
     static const char* mouseStateName(MouseState s);
 
-       bool mouseEnabled() const { return true; }
+    bool mouseEnabled() const { return true; }
 
     virtual bool trackAsMenu();
 
-       // called from keypress listener only
-       void keyPress(const event_id& id);
+    /// Handle a key press associated with a button event.
+    void keyPress(key::code c);
 
     /// Render this Button.
-       virtual void display(Renderer& renderer, const Transform& xform);
-       
-       void set_current_state(MouseState new_state);
-
-       /// \brief
-       /// Return the topmost entity that the given point covers. 
-       /// NULL if none.
-       //
-       /// I.e. check against ourself.
-       ///
-       virtual InteractiveObject* topmostMouseEntity(boost::int32_t x,
+    virtual void display(Renderer& renderer, const Transform& xform);
+    
+    void set_current_state(MouseState new_state);
+
+    /// Return the topmost entity that the given point covers. NULL if none.
+    //
+    /// I.e. check against ourself.
+    virtual InteractiveObject* topmostMouseEntity(boost::int32_t x,
             boost::int32_t y);
-       
-       virtual void mouseEvent(const event_id& event);
+    
+    /// Called whenever a mouse event affects this Button.
+    virtual void mouseEvent(const event_id& event);
 
+    /// Called when the Button is in focus.
     virtual bool handleFocus();
 
-       void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
-       
-       virtual SWFRect getBounds() const;
-       
-       // See dox in DisplayObject.h
-       bool pointInShape(boost::int32_t x, boost::int32_t y) const;
+    void add_invalidated_bounds(InvalidatedRanges& ranges, bool force);
+    
+    virtual SWFRect getBounds() const;
+    
+    // See dox in DisplayObject.h
+    bool pointInShape(boost::int32_t x, boost::int32_t y) const;
 
-       bool isEnabled();
+    bool isEnabled();
 
-       /// Properly destroy contained DisplayObjects
-       void destroy();
+    /// Properly destroy contained DisplayObjects
+    void destroy();
 
     /// Do ActionScript construction of the Button.
     //
@@ -127,38 +125,35 @@ public:
     virtual void construct(as_object* init = 0);
 
 #ifdef USE_SWFTREE
-       // Override to append button DisplayObjects info, see dox in 
DisplayObject.h
-       virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
+    // Override to append button DisplayObjects info, see dox in 
DisplayObject.h
+    virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
             InfoTree::iterator it);
 #endif
 
 protected:
-       
-       /// Properly unload contained DisplayObjects
-       virtual bool unloadChildren();
-
-       /// Mark reachable resources (for the GC)
-       //
-       /// These are:
-       ///     - this char's definition (_def)
-       ///     - the vector of state DisplayObjects (_stateCharacters)
-       ///     - the vector of hit DisplayObjects (_hitCharacters)
-       ///
-       void markOwnResources() const;
+    
+    /// Properly unload contained DisplayObjects
+    virtual bool unloadChildren();
+
+    /// Mark reachable resources (for the GC)
+    //
+    /// These are:
+    ///    - this char's definition (_def)
+    ///    - the vector of state DisplayObjects (_stateCharacters)
+    ///    - the vector of hit DisplayObjects (_hitCharacters)
+    ///
+    void markOwnResources() const;
 
 private:
 
-       /// Returns all DisplayObjects that are active based on the current 
state.
-       //
-       /// The "_visible" property does not matter here. 
-       ///
-       /// @param list
-       ///     The container to push active DisplayObjects into
-       ///
-       /// @param includeUnloaded
-       ///     If true, include unloaded but still reachable chars in the 
records slot.
-       ///
-       void getActiveCharacters(DisplayObjects& list, bool 
includeUnloaded=false);
+    /// Returns all DisplayObjects that are active based on the current state.
+    //
+    /// The "_visible" property does not matter here. 
+    ///
+    /// @param list             The container to push active DisplayObjects 
into
+    /// @param includeUnloaded  If true, include unloaded but still reachable
+    ///                         chars in the records slot.
+    void getActiveCharacters(DisplayObjects& list, bool includeUnloaded=false);
 
     /// Returns all DisplayObjects that are active based on the current state.
     //
@@ -166,40 +161,39 @@ private:
     /// modified.
     ///
     /// @param list     The container to push unmodifiable DisplayObjects into.
-       void getActiveCharacters(ConstDisplayObjects& list) const;
+    void getActiveCharacters(ConstDisplayObjects& list) const;
 
-       /// Returns all DisplayObjects (record nums) that should be active on
+    /// Returns all DisplayObjects (record nums) that should be active on
     /// the given state.
-       //
-       /// @param list
-       ///     The set to push active DisplayObjects record number into
-       ///
-       /// @param state
-       ///     The state we're interested in
-       ///
-       void get_active_records(ActiveRecords& list, MouseState state);
-
-       /// Return version of the SWF containing the button definition.
+    //
+    /// @param list
+    ///    The set to push active DisplayObjects record number into
+    ///
+    /// @param state
+    ///    The state we're interested in
+    ///
+    void get_active_records(ActiveRecords& list, MouseState state);
+
+    /// Return version of the SWF containing the button definition.
     virtual int getDefinitionVersion() const;
-       
-       MouseState _mouseState;
+    
+    MouseState _mouseState;
     
     const boost::intrusive_ptr<const SWF::DefineButtonTag> _def;
 
-       DisplayObjects _stateCharacters;
+    DisplayObjects _stateCharacters;
 
-       DisplayObjects _hitCharacters;
+    DisplayObjects _hitCharacters;
 
 
 };
 
-
 /// Initialize the global Button class
 void button_class_init(as_object& global, const ObjectURI& uri);
 
 void registerButtonNative(as_object& global);
 
-}      // end namespace gnash
+} // namespace gnash
 
 
 #endif // GNASH_BUTTON_H
diff --git a/libcore/DisplayObject.cpp b/libcore/DisplayObject.cpp
index 7da37d4..978c6b7 100644
--- a/libcore/DisplayObject.cpp
+++ b/libcore/DisplayObject.cpp
@@ -430,10 +430,6 @@ void
 DisplayObject::add_event_handler(const event_id& id, const action_buffer& code)
 {
     _event_handlers[id].push_back(&code);
-
-    // todo: drop the DisplayObject as a listener
-    //       if it gets no valid handlers for
-    //       mouse or Key events.
 }
 
 std::auto_ptr<ExecutableCode>
@@ -453,13 +449,8 @@ DisplayObject::get_event_handler(const event_id& id) const
 bool
 DisplayObject::unload()
 {
-
     const bool childHandler = unloadChildren();
 
-    if (!_unloaded) {
-        queueEvent(event_id(event_id::UNLOAD), movie_root::PRIORITY_DOACTION);
-    }
-
     // Unregister this DisplayObject as mask and/or maskee.
     if (_maskee) _maskee->setMask(0);
     if (_mask) _mask->setMaskee(0);
@@ -476,14 +467,6 @@ DisplayObject::unload()
     return hasEvent;
 }
 
-void
-DisplayObject::queueEvent(const event_id& id, int lvl)
-{
-    if (!_object) return;
-    std::auto_ptr<ExecutableCode> event(new QueuedEvent(this, id));
-    stage().pushAction(event, lvl);
-}
-
 bool
 DisplayObject::hasEventHandler(const event_id& id) const
 {
diff --git a/libcore/DisplayObject.h b/libcore/DisplayObject.h
index b4fc6a1..6100871 100644
--- a/libcore/DisplayObject.h
+++ b/libcore/DisplayObject.h
@@ -622,17 +622,6 @@ public:
     // Return true if this DisplayObject should be rendered
     bool visible() const { return _visible; }
 
-    /// Notify clip events (and also user-defined ones).
-    virtual void notifyEvent(const event_id& /*id*/)
-    {
-    }
-
-    /// Queue event in the global action queue.
-    //
-    /// notifyEvent(id) will be called by execution of the queued
-    /// action
-    void queueEvent(const event_id& id, int lvl);
-
     /// Return true if an handler for the given event is defined
     //
     /// NOTE that we look for both clip-defined and user-defined
diff --git a/libcore/InteractiveObject.h b/libcore/InteractiveObject.h
index a1b58cb..eaaff3b 100644
--- a/libcore/InteractiveObject.h
+++ b/libcore/InteractiveObject.h
@@ -115,10 +115,11 @@ public:
     virtual InteractiveObject* topmostMouseEntity(boost::int32_t /*x*/,
             boost::int32_t /*y*/) = 0;
 
-    virtual void mouseEvent(const event_id& id)
-    {
-        notifyEvent(id);
-    }
+    /// Called whenever a mouse event affects this InteractiveObject.
+    //
+    /// All InteractiveObjects (Button, MovieClip, TextField) can handle
+    /// mouse input, so must override this function.
+    virtual void mouseEvent(const event_id& id) = 0;
 
     /// Return true if the given point falls in this DisplayObject's shape
     //
diff --git a/libcore/MovieClip.cpp b/libcore/MovieClip.cpp
index b5c8176..5e74fd4 100644
--- a/libcore/MovieClip.cpp
+++ b/libcore/MovieClip.cpp
@@ -511,6 +511,13 @@ MovieClip::getDisplayObjectAtDepth(int depth)
     return _displayList.getDisplayObjectAtDepth(depth);
 }
 
+void
+MovieClip::queueEvent(const event_id& id, int lvl)
+{
+    std::auto_ptr<ExecutableCode> event(new QueuedEvent(this, id));
+    stage().pushAction(event, lvl);
+}
+
 /// This handles special properties of MovieClip.
 //
 /// The only genuine special properties are DisplayList members. These
@@ -687,7 +694,8 @@ MovieClip::notifyEvent(const event_id& id)
     // We do not execute ENTER_FRAME if unloaded
     if (id.id() == event_id::ENTER_FRAME && unloaded()) {
 #ifdef GNASH_DEBUG
-        log_debug(_("Sprite %s ignored ENTER_FRAME event (is unloaded)"), 
getTarget());
+        log_debug(_("Sprite %s ignored ENTER_FRAME event (is unloaded)"),
+                getTarget());
 #endif
         return;
     }
@@ -700,12 +708,18 @@ MovieClip::notifyEvent(const event_id& id)
         return;
     }
 
-    std::auto_ptr<ExecutableCode> code (get_event_handler(id));
+    // Dispatch static event handlers (defined in PlaceObject tags).
+    std::auto_ptr<ExecutableCode> code(get_event_handler(id));
     if (code.get()) {
         // Dispatch.
         code->execute();
     }
 
+    // Now call user-defined event handlers, but not for everything.
+
+    // User-defined key events are never called.
+    if (isKeyEvent(id)) return;
+
     // user-defined onInitialize is never called
     if (id.id() == event_id::INITIALIZE) return;
 
@@ -758,9 +772,7 @@ MovieClip::notifyEvent(const event_id& id)
     }
 
     // Call the appropriate member function.
-    if (!isKeyEvent(id)) {
-        sendEvent(*getObject(this), get_environment(), id.functionURI());
-    }
+    sendEvent(*getObject(this), get_environment(), id.functionURI());
 
 }
 
@@ -1745,6 +1757,7 @@ MovieClip::construct(as_object* initObj)
 bool
 MovieClip::unloadChildren()
 {
+
 #ifdef GNASH_DEBUG
     log_debug(_("Unloading movieclip '%s'"), getTargetPath());
 #endif
@@ -1757,7 +1770,14 @@ MovieClip::unloadChildren()
     // on itself.
     _drawable.clear();
     
-    return _displayList.unload();
+    const bool childHandler = _displayList.unload();
+
+    if (!unloaded()) {
+        queueEvent(event_id(event_id::UNLOAD), movie_root::PRIORITY_DOACTION);
+    }
+
+    return childHandler;
+
 }
 
 void
diff --git a/libcore/MovieClip.h b/libcore/MovieClip.h
index 60ae754..4f00225 100644
--- a/libcore/MovieClip.h
+++ b/libcore/MovieClip.h
@@ -131,6 +131,12 @@ public:
 
     virtual bool trackAsMenu();
 
+    /// Queue event in the global action queue.
+    //
+    /// notifyEvent(id) will be called by execution of the queued
+    /// action
+    void queueEvent(const event_id& id, int lvl);
+
     /// Return the _root ActionScript property of this sprite.
     //
     /// Relative or absolute is determined by the _lockroot property,
@@ -490,9 +496,17 @@ public:
     /// @param init_object
     ///     If not null, will be used to copy properties over.
     MovieClip* duplicateMovieClip(const std::string& newname,
-        int newdepth, as_object* init_object=NULL);
+        int newdepth, as_object* init_object = 0);
+
+    /// Called when a mouse event affects this MovieClip
+    virtual void mouseEvent(const event_id& id) {
+        notifyEvent(id);
+    }
         
     /// Dispatch event handler(s), if any.
+    //
+    /// This handles key, mouse, and specific MovieClip events.
+    /// TODO: split this sensibly.
     virtual void notifyEvent(const event_id& id);
 
     // inherited from DisplayObject class, see dox in DisplayObject.h
diff --git a/libcore/TextField.cpp b/libcore/TextField.cpp
index d11ec5b..81cb2a1 100644
--- a/libcore/TextField.cpp
+++ b/libcore/TextField.cpp
@@ -524,7 +524,213 @@ TextField::setSelection(int start, int end)
 }
 
 void
-TextField::notifyEvent(const event_id& ev)
+TextField::keyInput(key::code c)
+{
+    // c is the unique gnash::key::code for a DisplayObject/key.
+    // The maximum value is about 265, including function keys.
+    // It seems that typing in DisplayObjects outside the Latin-1 set
+    // (256 DisplayObject codes, identical to the first 256 of UTF-8)
+    // is not supported, though a much greater number UTF-8 codes can be
+    // stored and displayed. See utf.h for more information.
+    // This is a limit on the number of key codes, not on the
+    // capacity of strings.
+
+
+    setHtml(false); //editable html fields are not yet implemented
+    std::wstring s = _text;
+
+    // maybe _text is changed in ActionScript
+    m_cursor = std::min<size_t>(m_cursor, _text.size());
+    
+    size_t cur_cursor = m_cursor;
+    size_t previouslinesize = 0;
+    size_t nextlinesize = 0;
+    size_t manylines = _line_starts.size();
+    LineStarts::iterator linestartit = _line_starts.begin();
+    LineStarts::const_iterator linestartend = _line_starts.end();
+
+    switch (c) {
+        case key::BACKSPACE:
+            if (isReadOnly()) return;
+            if (m_cursor > 0)
+            {
+                s.erase(m_cursor - 1, 1);
+                m_cursor--;
+                setTextValue(s);
+            }
+            break;
+
+        case key::DELETEKEY:
+            if (isReadOnly()) return;
+            if (_glyphcount > m_cursor)
+            {
+                s.erase(m_cursor, 1);
+                setTextValue(s);
+            }
+            break;
+
+        case key::INSERT:        // TODO
+            if (isReadOnly()) return;
+            break;
+
+        case key::HOME:
+            while ( linestartit < linestartend && *linestartit <= m_cursor ) {
+                cur_cursor = *linestartit;
+                linestartit++;
+            }
+            m_cursor = cur_cursor;
+            break;
+            
+        case key::PGUP:
+            // if going a page up is too far...
+            if(_scroll < _linesindisplay) {
+                _scroll = 0;
+                m_cursor = 0;
+            } else { // go a page up
+                _scroll -= _linesindisplay;
+                m_cursor = _line_starts[_scroll];
+            }
+            scrollLines();
+            break;
+            
+        case key::UP:
+            while ( linestartit < linestartend && *linestartit <= m_cursor ) {
+                cur_cursor = *linestartit;
+                linestartit++;
+            }
+            //if there is no previous line
+            if ( linestartit-_line_starts.begin() - 2 < 0 ) {
+                m_cursor = 0;
+                break;
+            }
+            previouslinesize = _textRecords[linestartit-_line_starts.begin() - 
2].glyphs().size();
+            //if the previous line is smaller
+            if (m_cursor - cur_cursor > previouslinesize) {
+                m_cursor = *(--(--linestartit)) + previouslinesize;
+            } else {
+                m_cursor = *(--(--linestartit)) + (m_cursor - cur_cursor);
+            }
+            if (m_cursor < _line_starts[_scroll] && _line_starts[_scroll] != 
0) {
+                --_scroll;
+            }
+            scrollLines();
+            break;
+            
+        case key::END:
+            while ( linestartit < linestartend && *linestartit <= m_cursor ) {
+                linestartit++;
+            }
+            m_cursor = linestartit != linestartend ? *linestartit - 1 : 
_text.size();
+            break;
+            
+        case key::PGDN:
+            //if going another page down is too far...
+            if(_scroll + _linesindisplay >= manylines) {
+                if(manylines - _linesindisplay <= 0) {
+                    _scroll = 0;
+                } else {
+                    _scroll = manylines - _linesindisplay;
+                }
+                if(m_cursor < _line_starts[_scroll-1]) {
+                    m_cursor = _line_starts[_scroll-1];
+                } else {
+                    m_cursor = _text.size();
+                }
+            } else { //go a page down
+                _scroll += _linesindisplay;
+                m_cursor = _line_starts[_scroll];
+            }
+            scrollLines();
+            break;
+            
+        case key::DOWN:
+        {
+            while (linestartit < linestartend &&
+                    *linestartit <= m_cursor ) {
+                cur_cursor = *linestartit;
+                linestartit++;
+            }
+
+            // linestartit should never be before _line_starts.begin()
+            const size_t currentLine = linestartit -
+                _line_starts.begin();
+            
+            //if there is no next line
+            if (currentLine >= manylines ) {
+                m_cursor = _text.size();
+                break;
+            }
+            nextlinesize = _textRecords[currentLine].glyphs().size();
+            
+            //if the next line is smaller
+            if (m_cursor - cur_cursor > nextlinesize) {
+                m_cursor = *linestartit + nextlinesize;
+            } else { 
+                //put the cursor at the same character distance
+                m_cursor = *(linestartit) + (m_cursor - cur_cursor);
+            }
+            if (_line_starts.size() > _linesindisplay &&
+                m_cursor >= _line_starts[_scroll+_linesindisplay]) {
+                ++_scroll;
+            }
+            scrollLines();
+            break;
+        }
+
+        case key::LEFT:
+            m_cursor = m_cursor > 0 ? m_cursor - 1 : 0;
+            break;
+
+        case key::RIGHT:
+            m_cursor = m_cursor < _glyphcount ? m_cursor + 1 :
+                                                _glyphcount;
+            break;
+            
+        case key::ENTER:
+            if (isReadOnly()) return;
+            if (!multiline()) break;
+
+        default:
+        
+            if (maxChars() != 0) {
+                if (_maxChars <= _glyphcount) {
+                    break;
+                }
+            }
+            
+            if (isReadOnly()) return;
+            wchar_t t = static_cast<wchar_t>(
+                    gnash::key::codeMap[c][key::ASCII]);
+            if (t != 0) {
+                
+                if (!_restrictDefined) {
+                    // Insert one copy of the character
+                    // at the cursor position.
+                    s.insert(m_cursor, 1, t);
+                    m_cursor++;
+                } else if (_restrictedchars.count(t)) {
+                    // Insert one copy of the character
+                    // at the cursor position.
+                    s.insert(m_cursor, 1, t);
+                    m_cursor++;
+                } else if (_restrictedchars.count(tolower(t))) {
+                    // restrict substitutes the opposite case
+                    s.insert(m_cursor, 1, tolower(t));
+                    m_cursor++;
+                } else if (_restrictedchars.count(toupper(t))) {
+                    // restrict substitutes the opposite case
+                    s.insert(m_cursor, 1, toupper(t));
+                    m_cursor++;
+                }
+            }
+            setTextValue(s);
+    }
+    onChanged();
+    set_invalidated();
+}
+
+void
+TextField::mouseEvent(const event_id& ev)
 {    
     switch (ev.id())
     {
@@ -558,213 +764,6 @@ TextField::notifyEvent(const event_id& ev)
 
                        break;
                }
-        case event_id::KEY_PRESS:
-        {
-            setHtml(false); //editable html fields are not yet implemented
-            std::wstring s = _text;
-
-            // id.keyCode is the unique gnash::key::code for a 
DisplayObject/key.
-            // The maximum value is about 265, including function keys.
-            // It seems that typing in DisplayObjects outside the Latin-1 set
-            // (256 DisplayObject codes, identical to the first 256 of UTF-8)
-            // is not supported, though a much greater number UTF-8 codes can 
be
-            // stored and displayed. See utf.h for more information.
-            // This is a limit on the number of key codes, not on the
-            // capacity of strings.
-            gnash::key::code c = ev.keyCode();
-                       
-
-            // maybe _text is changed in ActionScript
-            m_cursor = std::min<size_t>(m_cursor, _text.size());
-            
-            size_t cur_cursor = m_cursor;
-            size_t previouslinesize = 0;
-            size_t nextlinesize = 0;
-            size_t manylines = _line_starts.size();
-            LineStarts::iterator linestartit = _line_starts.begin();
-            LineStarts::const_iterator linestartend = _line_starts.end();
-
-            switch (c)
-            {
-                case key::BACKSPACE:
-                    if (isReadOnly()) return;
-                    if (m_cursor > 0)
-                    {
-                        s.erase(m_cursor - 1, 1);
-                        m_cursor--;
-                        setTextValue(s);
-                    }
-                    break;
-
-                case key::DELETEKEY:
-                    if (isReadOnly()) return;
-                    if (_glyphcount > m_cursor)
-                    {
-                        s.erase(m_cursor, 1);
-                        setTextValue(s);
-                    }
-                    break;
-
-                case key::INSERT:        // TODO
-                    if (isReadOnly()) return;
-                    break;
-
-                case key::HOME:
-                    while ( linestartit < linestartend && *linestartit <= 
m_cursor ) {
-                        cur_cursor = *linestartit;
-                        linestartit++;
-                    }
-                    m_cursor = cur_cursor;
-                    break;
-                    
-                case key::PGUP:
-                    // if going a page up is too far...
-                    if(_scroll < _linesindisplay) {
-                        _scroll = 0;
-                        m_cursor = 0;
-                    } else { // go a page up
-                        _scroll -= _linesindisplay;
-                        m_cursor = _line_starts[_scroll];
-                    }
-                    scrollLines();
-                    break;
-                    
-                case key::UP:
-                    while ( linestartit < linestartend && *linestartit <= 
m_cursor ) {
-                        cur_cursor = *linestartit;
-                        linestartit++;
-                    }
-                    //if there is no previous line
-                    if ( linestartit-_line_starts.begin() - 2 < 0 ) {
-                        m_cursor = 0;
-                        break;
-                    }
-                    previouslinesize = 
_textRecords[linestartit-_line_starts.begin() - 2].glyphs().size();
-                    //if the previous line is smaller
-                    if (m_cursor - cur_cursor > previouslinesize) {
-                        m_cursor = *(--(--linestartit)) + previouslinesize;
-                    } else {
-                        m_cursor = *(--(--linestartit)) + (m_cursor - 
cur_cursor);
-                    }
-                    if (m_cursor < _line_starts[_scroll] && 
_line_starts[_scroll] != 0) {
-                        --_scroll;
-                    }
-                    scrollLines();
-                    break;
-                    
-                case key::END:
-                    while ( linestartit < linestartend && *linestartit <= 
m_cursor ) {
-                        linestartit++;
-                    }
-                    m_cursor = linestartit != linestartend ? *linestartit - 1 
: _text.size();
-                    break;
-                    
-                case key::PGDN:
-                    //if going another page down is too far...
-                    if(_scroll + _linesindisplay >= manylines) {
-                        if(manylines - _linesindisplay <= 0) {
-                            _scroll = 0;
-                        } else {
-                            _scroll = manylines - _linesindisplay;
-                        }
-                        if(m_cursor < _line_starts[_scroll-1]) {
-                            m_cursor = _line_starts[_scroll-1];
-                        } else {
-                            m_cursor = _text.size();
-                        }
-                    } else { //go a page down
-                        _scroll += _linesindisplay;
-                        m_cursor = _line_starts[_scroll];
-                    }
-                    scrollLines();
-                    break;
-                    
-                case key::DOWN:
-                {
-                    while (linestartit < linestartend &&
-                            *linestartit <= m_cursor ) {
-                        cur_cursor = *linestartit;
-                        linestartit++;
-                    }
-
-                    // linestartit should never be before _line_starts.begin()
-                    const size_t currentLine = linestartit -
-                        _line_starts.begin();
-                    
-                    //if there is no next line
-                    if (currentLine >= manylines ) {
-                        m_cursor = _text.size();
-                        break;
-                    }
-                    nextlinesize = _textRecords[currentLine].glyphs().size();
-                    
-                    //if the next line is smaller
-                    if (m_cursor - cur_cursor > nextlinesize) {
-                        m_cursor = *linestartit + nextlinesize;
-                    } else { 
-                        //put the cursor at the same character distance
-                        m_cursor = *(linestartit) + (m_cursor - cur_cursor);
-                    }
-                    if (_line_starts.size() > _linesindisplay &&
-                        m_cursor >= _line_starts[_scroll+_linesindisplay]) {
-                        ++_scroll;
-                    }
-                    scrollLines();
-                    break;
-                }
-
-                case key::LEFT:
-                    m_cursor = m_cursor > 0 ? m_cursor - 1 : 0;
-                    break;
-
-                case key::RIGHT:
-                    m_cursor = m_cursor < _glyphcount ? m_cursor + 1 :
-                                                        _glyphcount;
-                    break;
-                    
-                case key::ENTER:
-                    if (isReadOnly()) return;
-                    if (!multiline()) break;
-
-                default:
-                               
-                                       if (maxChars() != 0) {
-                                               if (_maxChars <= _glyphcount) {
-                                                       break;
-                                               }
-                                       }
-                                       
-                    if (isReadOnly()) return;
-                    wchar_t t = static_cast<wchar_t>(
-                            gnash::key::codeMap[c][key::ASCII]);
-                    if (t != 0) {
-                        
-                        if (!_restrictDefined) {
-                            // Insert one copy of the character
-                            // at the cursor position.
-                            s.insert(m_cursor, 1, t);
-                            m_cursor++;
-                        } else if (_restrictedchars.count(t)) {
-                            // Insert one copy of the character
-                            // at the cursor position.
-                            s.insert(m_cursor, 1, t);
-                            m_cursor++;
-                        } else if (_restrictedchars.count(tolower(t))) {
-                            // restrict substitutes the opposite case
-                            s.insert(m_cursor, 1, tolower(t));
-                            m_cursor++;
-                        } else if (_restrictedchars.count(toupper(t))) {
-                            // restrict substitutes the opposite case
-                            s.insert(m_cursor, 1, toupper(t));
-                            m_cursor++;
-                        }
-                    }
-                    setTextValue(s);
-            }
-            onChanged();
-            set_invalidated();
-        }
-
         default:
             return;
     };
diff --git a/libcore/TextField.h b/libcore/TextField.h
index dae270c..3f68149 100644
--- a/libcore/TextField.h
+++ b/libcore/TextField.h
@@ -28,6 +28,7 @@
 #include "LineStyle.h" // for LineStyle
 #include "snappingrange.h"
 #include "SWFRect.h" // for inlines
+#include "GnashKey.h"
 
 // Forward declarations
 namespace gnash {
@@ -125,7 +126,10 @@ public:
     virtual int getDefinitionVersion() const;
 
        /// This function is called as a user-input handler
-       void notifyEvent(const event_id& id);   
+       void mouseEvent(const event_id& id);    
+
+    /// Handle user input from a key press.
+    void keyInput(key::code k);
 
        const std::string& getVariableName() const
        {
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index bf0f720..90e1183 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -577,8 +577,7 @@ movie_root::keyEvent(key::code k, bool down)
     for (LiveChars::iterator iter = copy.begin(), itEnd=copy.end();
             iter != itEnd; ++iter) {
 
-        // sprite, button & input_edit_text DisplayObjects
-        InteractiveObject* const ch = *iter;
+        MovieClip* const ch = *iter;
         if (ch->unloaded()) continue;
 
         if (down) {
@@ -624,14 +623,14 @@ movie_root::keyEvent(key::code k, bool down)
         // because we search through them all to register the key codes.
         if (it != _buttonKeys.end()) {
             if (!it->second.first->unloaded()) {
-                it->second.first->keyPress(event_id(event_id::KEY_PRESS, k));
+                it->second.first->keyPress(k);
             }
         }
 
         // If we're focused on an editable text field, finally the text
         // is updated
         TextField* tf = dynamic_cast<TextField*>(_currentFocus);
-        if (tf) tf->notifyEvent(event_id(event_id::KEY_PRESS, k));
+        if (tf) tf->keyInput(k);
     }
 
     processActionQueue();
diff --git a/libcore/vm/ExecutableCode.h b/libcore/vm/ExecutableCode.h
index c66420b..6023536 100644
--- a/libcore/vm/ExecutableCode.h
+++ b/libcore/vm/ExecutableCode.h
@@ -133,7 +133,7 @@ class QueuedEvent : public ExecutableCode
 {
 public:
 
-    QueuedEvent(DisplayObject* nTarget, const event_id& id)
+    QueuedEvent(MovieClip* nTarget, const event_id& id)
         :
         ExecutableCode(nTarget),
         _eventId(id)
@@ -142,7 +142,7 @@ public:
     virtual void execute() {
         // don't execute any events for destroyed DisplayObject.
         if (!target()->isDestroyed()) {
-            target()->notifyEvent(_eventId);
+            static_cast<MovieClip*>(target())->notifyEvent(_eventId);
         }
     }
 
diff --git a/testsuite/DummyCharacter.h b/testsuite/DummyCharacter.h
index c646d55..20fa49b 100644
--- a/testsuite/DummyCharacter.h
+++ b/testsuite/DummyCharacter.h
@@ -56,6 +56,8 @@ public:
 
     virtual bool mouseEnabled() const { return true; }
 
+    virtual void mouseEvent(const event_id&) {}
+
     InteractiveObject* topmostMouseEntity(boost::int32_t, boost::int32_t)
     {
         return 0;

-----------------------------------------------------------------------

Summary of changes:
 libcore/Button.cpp                                 |    7 +-
 libcore/Button.h                                   |  190 +++++-----
 libcore/DisplayObject.cpp                          |   17 -
 libcore/DisplayObject.h                            |   11 -
 libcore/InteractiveObject.h                        |    9 +-
 libcore/MovieClip.cpp                              |   32 ++-
 libcore/MovieClip.h                                |   16 +-
 libcore/TextField.cpp                              |  415 ++++++++++----------
 libcore/TextField.h                                |    6 +-
 libcore/movie_root.cpp                             |    7 +-
 libcore/vm/ExecutableCode.h                        |    4 +-
 libsound/sound_handler.cpp                         |   17 +-
 libsound/sound_handler.h                           |    5 +
 testsuite/DummyCharacter.h                         |    2 +
 testsuite/MovieTester.cpp                          |    7 +
 testsuite/MovieTester.h                            |    3 +
 testsuite/misc-ming.all/Makefile.am                |   37 ++-
 .../Dejagnu.c => misc-ming.all/StreamSoundTest.c}  |   70 +++--
 ...ndTest-Runner.cpp => StreamSoundTestRunner.cpp} |   27 +-
 testsuite/misc-ming.all/eventSoundTest1-Runner.cpp |    8 +-
 20 files changed, 492 insertions(+), 398 deletions(-)
 copy testsuite/{network.all/Dejagnu.c => misc-ming.all/StreamSoundTest.c} (54%)
 copy testsuite/misc-ming.all/{EmbeddedSoundTest-Runner.cpp => 
StreamSoundTestRunner.cpp} (74%)


hooks/post-receive
-- 
Gnash



reply via email to

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