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. 4bafbe26756ac4749cb1


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. 4bafbe26756ac4749cb151d8b80e08ad17b557f0
Date: Wed, 08 Dec 2010 10:03:25 +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  4bafbe26756ac4749cb151d8b80e08ad17b557f0 (commit)
       via  421d14fcdaa31ef6d6e81b462375f4fe39c19eb3 (commit)
       via  2b94a40612018c4124f493b00d06419e37b41732 (commit)
       via  1e1e653cbe4cf092b671ba6b9e0e2164c9612522 (commit)
       via  eb5023c7c315ea8acddee845de9f1bef1b9b5cbe (commit)
       via  a81f8f4746df4bfa11ceabba308c1e040ed190c6 (commit)
       via  0425be7f8da72cb58adcfdb0c88987a98c5f99e2 (commit)
       via  06cfeb10bf99b790031ad7e0be84cae5d0c1f281 (commit)
       via  59eb09bad652bb6141fb0eb2c9b2503affef7331 (commit)
       via  6238c4d97126dfe65fc251b0761f24ab9b37436f (commit)
       via  fb4f789a1f262d3b836b877e4fc698702eeeabd1 (commit)
       via  17046db1a33994cf2ad43dea8a0fabe7f946e3f6 (commit)
       via  3ef126b594e6857a5991ecece5e0626321cdd0c1 (commit)
       via  3cee7f1b50f5d0ec3ed29089d9394ee908e9c29d (commit)
       via  b6c2fe0648119e0a29737086cf73220d0e56b7ce (commit)
       via  ebb410b630e22ec5ee576e27f5d9480c0ac6dd9b (commit)
       via  8656e9d2bc656253fbfa3d6971fb52090dc4d37d (commit)
       via  4650458f903d0d847f7036975536bed115f67270 (commit)
      from  775ec6f542263dde338e9b3b88b08bbfdc033cfa (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=4bafbe26756ac4749cb151d8b80e08ad17b557f0


commit 4bafbe26756ac4749cb151d8b80e08ad17b557f0
Merge: 421d14f 775ec6f
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Dec 8 10:49:09 2010 +0100

    Merge branch 'master' of git.sv.gnu.org:/srv/git/gnash


http://git.savannah.gnu.org/cgit//commit/?id=421d14fcdaa31ef6d6e81b462375f4fe39c19eb3


commit 421d14fcdaa31ef6d6e81b462375f4fe39c19eb3
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Dec 8 10:00:18 2010 +0100

    Drop unused silly function.

diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index bd41ce8..b5159c6 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -715,12 +715,6 @@ NetStream_as::decodeNextAudioFrame()
     return raw;
 }
 
-bool
-NetStream_as::decodeMediaFrame()
-{
-    return false;
-}
-
 void
 NetStream_as::seek(boost::uint32_t posSeconds)
 {
diff --git a/libcore/asobj/NetStream_as.h b/libcore/asobj/NetStream_as.h
index d867f76..6e94d29 100644
--- a/libcore/asobj/NetStream_as.h
+++ b/libcore/asobj/NetStream_as.h
@@ -499,10 +499,6 @@ private:
     /// and up to current timestamp
     void refreshAudioBuffer();
 
-    /// Used to decode and push the next available (non-FLV) frame to
-    /// the audio or video queue
-    bool decodeMediaFrame();
-
     /// Decode next video frame fetching it MediaParser cursor
     //
     /// @return 0 on EOF or error, a decoded video otherwise

http://git.savannah.gnu.org/cgit//commit/?id=2b94a40612018c4124f493b00d06419e37b41732


commit 2b94a40612018c4124f493b00d06419e37b41732
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Dec 8 10:00:03 2010 +0100

    Use NOTIFY_ERROR in Player too.

diff --git a/gui/Player.cpp b/gui/Player.cpp
index 0820538..918f8eb 100644
--- a/gui/Player.cpp
+++ b/gui/Player.cpp
@@ -74,7 +74,7 @@ public:
 
         switch (e.event()) {
 
-            case HostMessage::ERROR:
+            case HostMessage::NOTIFY_ERROR:
                 _gui.error(boost::any_cast<std::string>(e.arg()));
                 return boost::blank();
 

http://git.savannah.gnu.org/cgit//commit/?id=1e1e653cbe4cf092b671ba6b9e0e2164c9612522


commit 1e1e653cbe4cf092b671ba6b9e0e2164c9612522
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Dec 8 09:49:48 2010 +0100

    Don't use ERROR because some implementations incorrectly use it as
    a macro.
    Fix volume adjustment and document.

diff --git a/libcore/HostInterface.h b/libcore/HostInterface.h
index 5393327..1922dd9 100644
--- a/libcore/HostInterface.h
+++ b/libcore/HostInterface.h
@@ -161,7 +161,7 @@ public:
         /// - Argument type: std::string
         /// - Effects: notify the user of an error
         /// - Return: none
-        ERROR,
+        NOTIFY_ERROR,
 
         /// Ask a question
         /// - Argument type: std::string
diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index 4203767..bd41ce8 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -18,10 +18,14 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
+#include "NetStream_as.h"
 
+#include <functional>
+#include <algorithm>
+#include <boost/cstdint.hpp>
+#include <boost/thread/mutex.hpp>
 
 #include "RunResources.h"
-#include "NetStream_as.h"
 #include "CharacterProxy.h"
 #include "smart_ptr.h" // GNASH_USE_GC
 #include "log.h"
@@ -71,7 +75,14 @@ namespace {
     as_value netstream_send(const fn_call& fn);
 
     void attachNetStreamInterface(as_object& o);
-    
+
+    /// Transform the volume by the requested amount
+    //
+    /// @param data     The data to transform
+    /// @param size     The length of the array
+    /// @param volume   The volume in percent.
+    void adjustVolume(boost::int16_t* data, size_t size, int volume);
+
     // TODO: see where this can be done more centrally.
     void executeTag(const SimpleBuffer& _buffer, as_object& thisPtr);
 }
@@ -299,16 +310,6 @@ NetStream_as::startAdvanceTimer()
     getRoot(owner()).addAdvanceCallback(this);
 }
 
-
-// AS-volume adjustment
-void adjust_volume(boost::int16_t* data, int size, int volume)
-{
-    for (int i=0; i < size*0.5; i++) {
-        data[i] = data[i] * volume/100;
-    }
-}
-
-
 NetStream_as::~NetStream_as()
 {
 }
@@ -317,8 +318,8 @@ NetStream_as::~NetStream_as()
 void NetStream_as::pause(PauseMode mode)
 {
     log_debug("::pause(%d) called ", mode);
-    switch ( mode )
-    {
+    switch (mode) {
+
         case pauseModeToggle:
             if (_playHead.getState() == PlayHead::PLAY_PAUSED) {
                 unpausePlayback();
@@ -337,7 +338,8 @@ void NetStream_as::pause(PauseMode mode)
 
 }
 
-void NetStream_as::close()
+void
+NetStream_as::close()
 {
 
     // Delete any samples in the audio queue.
@@ -390,13 +392,11 @@ NetStream_as::play(const std::string& c_url)
     url = c_url;
 
     // Remove any "mp3:" prefix. Maybe should use this to mark as audio-only
-    if (url.compare(0, 4, std::string("mp3:")) == 0)
-    {
+    if (url.compare(0, 4, std::string("mp3:")) == 0) {
         url = url.substr(4);
     }
 
-    if (url.empty())
-    {
+    if (url.empty()) {
         log_error("Couldn't load URL %s", c_url);
         return;
     }
@@ -409,8 +409,7 @@ NetStream_as::play(const std::string& c_url)
     _inputStream = _netCon->getStream(url); 
 
     // We need to start playback
-    if (!startPlayback())
-    {
+    if (!startPlayback()) {
         log_error("NetStream.play(%s): failed starting playback", c_url);
         return;
     }
@@ -425,9 +424,9 @@ void
 NetStream_as::initVideoDecoder(const media::VideoInfo& info)
 {
     // Caller should check these:
-    assert ( _mediaHandler ); 
-    assert ( !_videoInfoKnown );
-    assert ( !_videoDecoder.get() );
+    assert (_mediaHandler); 
+    assert (!_videoInfoKnown);
+    assert (!_videoDecoder.get());
 
     _videoInfoKnown = true; 
 
@@ -443,7 +442,8 @@ NetStream_as::initVideoDecoder(const media::VideoInfo& info)
 
         // This is important enough to let the user know.
         movie_root& m = getRoot(owner());
-        m.callInterface(HostMessage(HostMessage::ERROR, 
std::string(e.what())));
+        m.callInterface(HostMessage(HostMessage::NOTIFY_ERROR,
+                std::string(e.what())));
     }
 
 }
@@ -467,11 +467,13 @@ NetStream_as::initAudioDecoder(const media::AudioInfo& 
info)
         _playHead.setAudioConsumerAvailable();
     }
     catch (const MediaException& e) {
-        log_error("Could not create Audio decoder: %s", e.what());
+        const std::string& err = e.what();
+
+        log_error("Could not create Audio decoder: %s", err);
 
         // This is important enough to let the user know.
         movie_root& m = getRoot(owner());
-        m.callInterface(HostMessage(HostMessage::ERROR, 
std::string(e.what())));
+        m.callInterface(HostMessage(HostMessage::NOTIFY_ERROR, err));
     }
 
 }
@@ -492,8 +494,7 @@ NetStream_as::startPlayback()
     // status notifications to be received (e.g. streamNotFound).
     startAdvanceTimer();
 
-    if ( ! _inputStream.get() )
-    {
+    if (!_inputStream.get()) {
         log_error(_("Gnash could not get stream '%s' from NetConnection"),
                 url);
         setStatus(streamNotFound);
@@ -503,8 +504,7 @@ NetStream_as::startPlayback()
     assert(_inputStream->tell() == static_cast<std::streampos>(0));
     inputPos = 0;
 
-    if (!_mediaHandler)
-    {
+    if (!_mediaHandler) {
         LOG_ONCE( log_error(_("No Media handler registered, can't "
             "parse NetStream input")) );
         return false;
@@ -512,8 +512,7 @@ NetStream_as::startPlayback()
     m_parser = _mediaHandler->createMediaParser(_inputStream);
     assert(!_inputStream.get());
 
-    if ( ! m_parser.get() )
-    {
+    if (!m_parser.get()) {
         log_error(_("Unable to create parser for NetStream input"));
         // not necessarily correct, the stream might have been found...
         setStatus(streamNotFound);
@@ -562,16 +561,15 @@ NetStream_as::getDecodedVideoFrame(boost::uint32_t ts)
     std::auto_ptr<image::GnashImage> video;
 
     assert(m_parser.get());
-    if ( ! m_parser.get() )
-    {
+    if (!m_parser.get()) {
         log_error("getDecodedVideoFrame: no parser available");
         return video; 
     }
 
     boost::uint64_t nextTimestamp;
     bool parsingComplete = m_parser->parsingCompleted();
-    if ( ! m_parser->nextVideoFrameTimestamp(nextTimestamp) )
-    {
+    if (!m_parser->nextVideoFrameTimestamp(nextTimestamp)) {
+
 #ifdef GNASH_DEBUG_DECODING
         log_debug("getDecodedVideoFrame(%d): "
             "no more video frames in input "
@@ -580,8 +578,7 @@ NetStream_as::getDecodedVideoFrame(boost::uint32_t ts)
             ts, parsingComplete);
 #endif 
 
-        if ( parsingComplete )
-        {
+        if (parsingComplete) {
             decodingStatus(DEC_STOPPED);
 #ifdef GNASH_DEBUG_STATUS
             log_debug("getDecodedVideoFrame setting playStop status "
@@ -593,8 +590,7 @@ NetStream_as::getDecodedVideoFrame(boost::uint32_t ts)
         return video;
     }
 
-    if ( nextTimestamp > ts )
-    {
+    if (nextTimestamp > ts) {
 #ifdef GNASH_DEBUG_DECODING
         log_debug("%p.getDecodedVideoFrame(%d): next video frame is in "
                 "the future (%d)", this, ts, nextTimestamp);
@@ -604,173 +600,163 @@ NetStream_as::getDecodedVideoFrame(boost::uint32_t ts)
     }
 
     // Loop until a good frame is found
-        while ( 1 )
-        {
-            video = decodeNextVideoFrame();
-            if ( ! video.get() )
-            {
-                log_error("nextVideoFrameTimestamp returned true (%d), "
-                    "but decodeNextVideoFrame returned null, "
-                    "I don't think this should ever happen", nextTimestamp);
-                break;
-            }
+    while (1) {
+        video = decodeNextVideoFrame();
+        if (!video.get()) {
+            log_error("nextVideoFrameTimestamp returned true (%d), "
+                "but decodeNextVideoFrame returned null, "
+                "I don't think this should ever happen", nextTimestamp);
+            break;
+        }
 
-            if ( ! m_parser->nextVideoFrameTimestamp(nextTimestamp) )
-            {
-                // the one we decoded was the last one
+        if (!m_parser->nextVideoFrameTimestamp(nextTimestamp)) {
+            // the one we decoded was the last one
 #ifdef GNASH_DEBUG_DECODING
-                log_debug("%p.getDecodedVideoFrame(%d): last video frame 
decoded "
-                    "(should set playback status to STOP?)", this, ts);
+            log_debug("%p.getDecodedVideoFrame(%d): last video frame decoded "
+                "(should set playback status to STOP?)", this, ts);
 #endif 
-                break;
-            }
-            if ( nextTimestamp > ts )
-            {
-                // the next one is in the future, we'll return this one.
+            break;
+        }
+        if (nextTimestamp > ts) {
+            // the next one is in the future, we'll return this one.
 #ifdef GNASH_DEBUG_DECODING
-                log_debug("%p.getDecodedVideoFrame(%d): "
-                    "next video frame is in the future, "
-                    "we'll return this one",
-                    this, ts);
+            log_debug("%p.getDecodedVideoFrame(%d): "
+                "next video frame is in the future, "
+                "we'll return this one",
+                this, ts);
 #endif 
-                break; 
-            }
+            break; 
         }
-
-        return video;
     }
 
-    std::auto_ptr<image::GnashImage> 
-    NetStream_as::decodeNextVideoFrame()
-    {
-        std::auto_ptr<image::GnashImage> video;
+    return video;
+}
 
-        if ( ! m_parser.get() )
-        {
-            log_error("decodeNextVideoFrame: no parser available");
-            return video; 
-        }
+std::auto_ptr<image::GnashImage> 
+NetStream_as::decodeNextVideoFrame()
+{
+    std::auto_ptr<image::GnashImage> video;
 
-        std::auto_ptr<media::EncodedVideoFrame> frame = 
m_parser->nextVideoFrame(); 
-        if ( ! frame.get() )
-        {
+    if (!m_parser.get()) {
+        log_error("decodeNextVideoFrame: no parser available");
+        return video; 
+    }
+
+    std::auto_ptr<media::EncodedVideoFrame> frame = 
m_parser->nextVideoFrame(); 
+    if (!frame.get()) {
 #ifdef GNASH_DEBUG_DECODING
-            log_debug("%p.decodeNextVideoFrame(): "
-                "no more video frames in input",
-                this);
+        log_debug("%p.decodeNextVideoFrame(): "
+            "no more video frames in input",
+            this);
 #endif 
-            return video;
-        }
-
-        assert( _videoDecoder.get() ); 
-        
-        // everything we push, we'll pop too..
-        assert( ! _videoDecoder->peek() ); 
-
-        _videoDecoder->push(*frame);
-        video = _videoDecoder->pop();
-        if ( ! video.get() )
-        {
-            // TODO: tell more about the failure
-            log_error(_("Error decoding encoded video frame in NetStream 
input"));
-        }
-
         return video;
     }
 
-    BufferedAudioStreamer::CursoredBuffer*
-    NetStream_as::decodeNextAudioFrame()
-    {
-        assert ( m_parser.get() );
+    assert(_videoDecoder.get()); 
+    
+    // everything we push, we'll pop too..
+    assert(!_videoDecoder->peek()); 
+
+    _videoDecoder->push(*frame);
+    video = _videoDecoder->pop();
+    if (!video.get()) {
+        // TODO: tell more about the failure
+        log_error(_("Error decoding encoded video frame in NetStream input"));
+    }
 
-        std::auto_ptr<media::EncodedAudioFrame> frame = 
m_parser->nextAudioFrame(); 
-        if ( ! frame.get() )
-        {
+    return video;
+}
+
+BufferedAudioStreamer::CursoredBuffer*
+NetStream_as::decodeNextAudioFrame()
+{
+    assert (m_parser.get());
+
+    std::auto_ptr<media::EncodedAudioFrame> frame = 
m_parser->nextAudioFrame(); 
+    if (!frame.get()) {
 #ifdef GNASH_DEBUG_DECODING
-            log_debug("%p.decodeNextAudioFrame: "
-                "no more video frames in input",
-                this);
+        log_debug("%p.decodeNextAudioFrame: "
+            "no more video frames in input",
+            this);
 #endif
-            return 0;
-        }
-
-        // TODO: make the buffer cursored later ?
-        BufferedAudioStreamer::CursoredBuffer* raw =
-            new BufferedAudioStreamer::CursoredBuffer();
-        raw->m_data = _audioDecoder->decode(*frame, raw->m_size);
+        return 0;
+    }
 
-        // TODO: let the sound_handler do this .. sounds cleaner
-        if ( _audioController ) 
-        {
-            DisplayObject* ch = _audioController->get();
-            if ( ch )
-            {
-                int vol = ch->getWorldVolume();
-                if ( vol != 100 )
-                {
-                    // NOTE: adjust_volume assumes samples 
-                    // are 16 bits in size, and signed.
-                    // Size is still given in bytes..
-                    
adjust_volume(reinterpret_cast<boost::int16_t*>(raw->m_data),
-                            raw->m_size, vol);
-                }
+    // TODO: make the buffer cursored later ?
+    BufferedAudioStreamer::CursoredBuffer* raw =
+        new BufferedAudioStreamer::CursoredBuffer();
+    raw->m_data = _audioDecoder->decode(*frame, raw->m_size);
+
+    // TODO: let the sound_handler do this .. sounds cleaner
+    if (_audioController) {
+        DisplayObject* ch = _audioController->get();
+        if (ch) {
+            const int vol = ch->getWorldVolume();
+            if (vol != 100) {
+                // NOTE: adjust_volume assumes samples 
+                // are 16 bits in size, and signed.
+                // Size is still given in bytes..
+                adjustVolume(reinterpret_cast<boost::int16_t*>(raw->m_data),
+                        raw->m_size / 2, vol);
             }
         }
+    }
 
 #ifdef GNASH_DEBUG_DECODING
-        log_debug("NetStream_as::decodeNextAudioFrame: "
-            "%d bytes of encoded audio "
-            "decoded to %d bytes",
-            frame->dataSize,
-            raw->m_size);
+    log_debug("NetStream_as::decodeNextAudioFrame: "
+        "%d bytes of encoded audio "
+        "decoded to %d bytes",
+        frame->dataSize,
+        raw->m_size);
 #endif 
 
-        raw->m_ptr = raw->m_data;
+    raw->m_ptr = raw->m_data;
 
-        return raw;
-    }
+    return raw;
+}
 
-    bool NetStream_as::decodeMediaFrame()
-    {
-        return false;
-    }
+bool
+NetStream_as::decodeMediaFrame()
+{
+    return false;
+}
 
-    void
-    NetStream_as::seek(boost::uint32_t posSeconds)
-    {
-        GNASH_REPORT_FUNCTION;
+void
+NetStream_as::seek(boost::uint32_t posSeconds)
+{
+    GNASH_REPORT_FUNCTION;
 
-        // We'll mess with the input here
-        if ( ! m_parser.get() )
-        {
-            log_debug("NetStream_as::seek(%d): no parser, no party", 
posSeconds);
-            return;
-        }
+    // We'll mess with the input here
+    if ( ! m_parser.get() )
+    {
+        log_debug("NetStream_as::seek(%d): no parser, no party", posSeconds);
+        return;
+    }
 
-        // Don't ask me why, but NetStream_as::seek() takes seconds...
-        boost::uint32_t pos = posSeconds*1000;
+    // Don't ask me why, but NetStream_as::seek() takes seconds...
+    boost::uint32_t pos = posSeconds*1000;
 
-        // We'll pause the clock source and mark decoders as buffering.
-        // In this way, next advance won't find the source time to 
-        // be a lot of time behind and chances to get audio buffer
-        // overruns will reduce.
-        // ::advance will resume the playbackClock if DEC_BUFFERING...
-        //
-        _playbackClock->pause();
+    // We'll pause the clock source and mark decoders as buffering.
+    // In this way, next advance won't find the source time to 
+    // be a lot of time behind and chances to get audio buffer
+    // overruns will reduce.
+    // ::advance will resume the playbackClock if DEC_BUFFERING...
+    //
+    _playbackClock->pause();
 
-        // Seek to new position
-        boost::uint32_t newpos = pos;
-        if ( ! m_parser->seek(newpos) )
-        {
+    // Seek to new position
+    boost::uint32_t newpos = pos;
+    if ( ! m_parser->seek(newpos) )
+    {
 #ifdef GNASH_DEBUG_STATUS
-            log_debug("Setting invalidTime status");
+        log_debug("Setting invalidTime status");
 #endif
-            setStatus(invalidTime);
-            // we won't be *BUFFERING*, so resume now
-            _playbackClock->resume(); 
-            return;
-        }
-        log_debug("m_parser->seek(%d) returned %d", pos, newpos);
+        setStatus(invalidTime);
+        // we won't be *BUFFERING*, so resume now
+        _playbackClock->resume(); 
+        return;
+    }
+    log_debug("m_parser->seek(%d) returned %d", pos, newpos);
 
         // cleanup audio queue, so won't be consumed while seeking
     _audioStreamer.cleanAudioQueue();
@@ -800,7 +786,7 @@ NetStream_as::parseNextChunk()
 void
 NetStream_as::refreshAudioBuffer()
 {
-    assert ( m_parser.get() );
+    assert (m_parser.get());
 
 #ifdef GNASH_DEBUG_DECODING
     // bufferLength() would lock the mutex (which we already hold),
@@ -811,8 +797,7 @@ NetStream_as::refreshAudioBuffer()
         parserTime > playHeadTime ? parserTime-playHeadTime : 0;
 #endif
 
-    if ( _playHead.getState() == PlayHead::PLAY_PAUSED )
-    {
+    if (_playHead.getState() == PlayHead::PLAY_PAUSED) {
 #ifdef GNASH_DEBUG_DECODING
         log_debug("%p.refreshAudioBuffer: doing nothing as playhead "
                 "is paused - bufferLength=%d/%d", this, bufferLength(),
@@ -821,8 +806,7 @@ NetStream_as::refreshAudioBuffer()
         return;
     }
 
-    if ( _playHead.isAudioConsumed() ) 
-    {
+    if (_playHead.isAudioConsumed()) {
 #ifdef GNASH_DEBUG_DECODING
         log_debug("%p.refreshAudioBuffer: doing nothing "
             "as current position was already decoded - "
@@ -851,8 +835,8 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
 {
     assert(m_parser.get());
 
-    if ( ! _audioDecoder.get() )
-    {
+    if (!_audioDecoder.get()) {
+
         // There are 3 possible reasons for _audioDecoder to not be here:
         //
         // 1: The stream does contain audio but we were unable to find
@@ -861,10 +845,9 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
         // 2: The stream does contain audio but we didn't try to construct
         //    a decoder for it yet.
         //
-        // 3: The stream does NOT contain audio yet
+        // 3: The stream does not contain audio yet
 
-        if ( _audioInfoKnown )
-        {
+        if (_audioInfoKnown) {
             // case 1: we saw the audio info already,
             //         but couldn't construct a decoder
 
@@ -875,8 +858,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
         }
 
         media::AudioInfo* audioInfo = m_parser->getAudioInfo();
-        if ( ! audioInfo )
-        {
+        if (!audioInfo) {
             // case 3: no audio found yet
             return;
         }
@@ -887,8 +869,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
         initAudioDecoder(*audioInfo);
 
         // Don't go ahead if audio decoder construction failed
-        if ( ! _audioDecoder.get() )
-        {
+        if (!_audioDecoder.get()) {
             // TODO: we should still flush any existing Audio frame
             //       in the encoded queue...
             //       (or rely on next call)
@@ -901,8 +882,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
     bool consumed = false;
 
     boost::uint64_t nextTimestamp;
-    while ( 1 )
-    {
+    while (1) {
 
         // FIXME: use services of BufferedAudioStreamer for this
         boost::mutex::scoped_lock lock(_audioStreamer._audioQueueMutex);
@@ -962,8 +942,8 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
 
         const unsigned int bufferLimit = 20;
         unsigned int bufferSize = _audioStreamer._audioQueue.size();
-        if ( bufferSize > bufferLimit )
-        {
+        if (bufferSize > bufferLimit) {
+
             // we won't buffer more then 'bufferLimit' frames in the queue
             // to avoid ending up with a huge queue which will take some
             // time before being consumed by audio mixer, but still marked
@@ -990,8 +970,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
         lock.unlock();
 
         bool parsingComplete = m_parser->parsingCompleted();
-        if ( ! m_parser->nextAudioFrameTimestamp(nextTimestamp) )
-        {
+        if (!m_parser->nextAudioFrameTimestamp(nextTimestamp)) {
 #ifdef GNASH_DEBUG_DECODING
             log_debug("%p.pushDecodedAudioFrames(%d): "
                 "no more audio frames in input "
@@ -999,8 +978,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
                 this, ts, parsingComplete);
 #endif 
 
-            if ( parsingComplete )
-            {
+            if (parsingComplete) {
                 consumed = true;
                 decodingStatus(DEC_STOPPED);
 #ifdef GNASH_DEBUG_STATUS
@@ -1014,8 +992,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
             break;
         }
 
-        if ( nextTimestamp > ts )
-        {
+        if (nextTimestamp > ts) {
 #ifdef GNASH_DEBUG_DECODING
             log_debug("%p.pushDecodedAudioFrames(%d): "
                 "next audio frame is in the future (%d)",
@@ -1028,8 +1005,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
         }
 
         BufferedAudioStreamer::CursoredBuffer* audio = decodeNextAudioFrame();
-        if ( ! audio )
-        {
+        if (!audio) {
             // Well, it *could* happen, why not ?
             log_error("nextAudioFrameTimestamp returned true (%d), "
                 "but decodeNextAudioFrame returned null, "
@@ -1037,8 +1013,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
             break;
         }
 
-        if ( ! audio->m_size )
-        {
+        if (!audio->m_size) {
             // Don't bother pushing an empty frame
             // to the audio Queue...
             log_debug("pushDecodedAudioFrames(%d): Decoded audio frame "
@@ -1061,8 +1036,7 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
 
     // If we consumed audio of current position, feel free to advance
     // if needed, resuming playbackClock too...
-    if ( consumed )
-    {
+    if (consumed) {
         // resume the playback clock, assuming the
         // only reason for it to be paused is we
         // put in pause mode due to buffer overrun
@@ -1083,10 +1057,9 @@ NetStream_as::pushDecodedAudioFrames(boost::uint32_t ts)
 void
 NetStream_as::refreshVideoFrame(bool alsoIfPaused)
 {
-    assert ( m_parser.get() );
+    assert (m_parser.get());
 
-    if ( ! _videoDecoder.get() )
-    {
+    if (!_videoDecoder.get()) {
         // There are 3 possible reasons for _videoDecoder to not be here:
         //
         // 1: The stream does contain video but we were unable to find
@@ -1095,11 +1068,10 @@ NetStream_as::refreshVideoFrame(bool alsoIfPaused)
         // 2: The stream does contain video but we didn't try to construct
         //    a decoder for it yet.
         //
-        // 3: The stream does NOT contain video yet
+        // 3: The stream does not contain video yet
         //
 
-        if ( _videoInfoKnown )
-        {
+        if (_videoInfoKnown) {
             // case 1: we saw the video info already,
             //         but couldn't construct a decoder
 
@@ -1110,8 +1082,7 @@ NetStream_as::refreshVideoFrame(bool alsoIfPaused)
         }
 
         media::VideoInfo* videoInfo = m_parser->getVideoInfo();
-        if ( ! videoInfo )
-        {
+        if (!videoInfo) {
             // case 3: no video found yet
             return;
         }
@@ -1122,8 +1093,7 @@ NetStream_as::refreshVideoFrame(bool alsoIfPaused)
         initVideoDecoder(*videoInfo);
 
         // Don't go ahead if video decoder construction failed
-        if ( ! _videoDecoder.get() )
-        {
+        if (!_videoDecoder.get()) {
             // TODO: we should still flush any existing Video frame
             //       in the encoded queue...
             //       (or rely on next call)
@@ -1667,19 +1637,17 @@ netstream_play(const fn_call& fn)
 {
     NetStream_as* ns = ensure<ThisIsNative<NetStream_as> >(fn);
 
-    if (!fn.nargs)
-    {
+    if (!fn.nargs) {
         IF_VERBOSE_ASCODING_ERRORS(
-        log_aserror(_("NetStream_as play needs args"));
+            log_aserror(_("NetStream_as play needs args"));
         );
         return as_value();
     }
 
-    if ( ! ns->isConnected() )
-    {
+    if (!ns->isConnected()) {
         IF_VERBOSE_ASCODING_ERRORS(
-        log_aserror(_("NetStream.play(%s): stream is not connected"),
-            fn.arg(0));
+            log_aserror(_("NetStream.play(%s): stream is not connected"),
+                fn.arg(0));
         );
         return as_value();
     }
@@ -1694,8 +1662,7 @@ netstream_seek(const fn_call& fn)
 {
     NetStream_as* ns = ensure<ThisIsNative<NetStream_as> >(fn);
     boost::uint32_t time = 0;
-    if (fn.nargs > 0)
-    {
+    if (fn.nargs > 0) {
         time = static_cast<boost::uint32_t>(toNumber(fn.arg(0), getVM(fn)));
     }
     ns->seek(time);
@@ -1706,22 +1673,18 @@ netstream_seek(const fn_call& fn)
 as_value
 netstream_setbuffertime(const fn_call& fn)
 {
-
-    //GNASH_REPORT_FUNCTION;
-
     NetStream_as* ns = ensure<ThisIsNative<NetStream_as> >(fn);
 
     // TODO: should we do anything if given no args ?
     //       are we sure setting bufferTime to 0 is what we have to do ?
     double time = 0;
-    if (fn.nargs > 0)
-    {
+    if (fn.nargs > 0) {
         time = toNumber(fn.arg(0), getVM(fn));
     }
 
     // TODO: don't allow a limit < 100 
 
-    ns->setBufferTime(boost::uint32_t(time*1000));
+    ns->setBufferTime(boost::uint32_t(time * 1000));
 
     return as_value();
 }
@@ -1809,8 +1772,7 @@ as_value
 netstream_bytesloaded(const fn_call& fn)
 {
     NetStream_as* ns = ensure<ThisIsNative<NetStream_as> >(fn);
-    if ( ! ns->isConnected() )
-    {
+    if (!ns->isConnected()) {
         return as_value();
     }
     long ret = ns->bytesLoaded();
@@ -1822,8 +1784,7 @@ as_value
 netstream_bytestotal(const fn_call& fn)
 {
     NetStream_as* ns = ensure<ThisIsNative<NetStream_as> >(fn);
-    if ( ! ns->isConnected() )
-    {
+    if (!ns->isConnected()) {
         return as_value();
     }
     long ret = ns->bytesTotal();
@@ -1835,8 +1796,7 @@ as_value
 netstream_currentFPS(const fn_call& fn)
 {
     NetStream_as* ns = ensure<ThisIsNative<NetStream_as> >(fn);
-    if ( ! ns->isConnected() )
-    {
+    if (!ns->isConnected()) {
         return as_value();
     }
 
@@ -1952,5 +1912,13 @@ executeTag(const SimpleBuffer& _buffer, as_object& 
thisPtr)
        callMethod(&thisPtr, funcKey, arg);
 }
 
+// AS-volume adjustment
+void
+adjustVolume(boost::int16_t* data, size_t size, int volume)
+{
+    std::transform(data, data + size, data,
+            boost::bind(std::multiplies<int>(), volume / 100.0, _1));
+}
+
 } // anonymous namespace
 } // gnash namespace

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


commit eb5023c7c315ea8acddee845de9f1bef1b9b5cbe
Author: Benjamin Wolsey <address@hidden>
Date:   Wed Dec 8 08:52:43 2010 +0100

    Use char.

diff --git a/libcore/asobj/System_as.cpp b/libcore/asobj/System_as.cpp
index f1f1755..dece542 100644
--- a/libcore/asobj/System_as.cpp
+++ b/libcore/asobj/System_as.cpp
@@ -43,7 +43,7 @@ namespace gnash {
 // Forward declarations.
 namespace {
 
-    inline std::string trueFalse(bool x) { return x ? "t" : "f"; }
+    inline char trueFalse(bool x) { return x ? 't' : 'f'; }
 
     std::string systemLanguage(as_object& proto);
 

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


commit a81f8f4746df4bfa11ceabba308c1e040ed190c6
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 17:07:05 2010 +0100

    Fix swapped arguments.

diff --git a/libcore/asobj/Mouse_as.cpp b/libcore/asobj/Mouse_as.cpp
index 7f44dc2..2db5abf 100644
--- a/libcore/asobj/Mouse_as.cpp
+++ b/libcore/asobj/Mouse_as.cpp
@@ -93,7 +93,7 @@ mouse_hide(const fn_call& fn)
 {
     movie_root& m = getRoot(fn);
     const int success =
-        m.callInterface<bool>(HostMessage(HostMessage::SHOW_MOUSE, true));
+        m.callInterface<bool>(HostMessage(HostMessage::SHOW_MOUSE, false));
 
     // returns 1 if mouse was visible before call.
     return as_value(success);
@@ -107,7 +107,7 @@ mouse_show(const fn_call& fn)
 {
     movie_root& m = getRoot(fn);
     const int success = 
-        m.callInterface<bool>(HostMessage(HostMessage::SHOW_MOUSE, false));
+        m.callInterface<bool>(HostMessage(HostMessage::SHOW_MOUSE, true));
 
     // returns 1 if Mouse was visible before call.
     return as_value(success);
diff --git a/utilities/processor.cpp b/utilities/processor.cpp
index 6dbfde6..ecbe1c4 100644
--- a/utilities/processor.cpp
+++ b/utilities/processor.cpp
@@ -180,7 +180,7 @@ public:
            if (event == HostMessage::SHOW_MOUSE) {
             bool state = mouseShown;
             mouseShown = boost::any_cast<bool>(ev.arg());
-            return state ? true : false ;
+            return state;
            }
            
            // Some fake values for consistent test results.

http://git.savannah.gnu.org/cgit//commit/?id=0425be7f8da72cb58adcfdb0c88987a98c5f99e2


commit 0425be7f8da72cb58adcfdb0c88987a98c5f99e2
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 16:58:42 2010 +0100

    Implement clipboard setting.

diff --git a/gui/Player.cpp b/gui/Player.cpp
index c0ccae2..0820538 100644
--- a/gui/Player.cpp
+++ b/gui/Player.cpp
@@ -27,7 +27,7 @@
 #include <iostream>
 #include <sstream>
 #include <boost/lexical_cast.hpp>
-#include <boost/variant.hpp>
+#include <boost/variant/static_visitor.hpp>
 #include <boost/any.hpp>
 #include <utility>
 #include <memory>
@@ -109,7 +109,7 @@ public:
                 return boost::blank();
 
             case HostMessage::SET_CLIPBOARD:
-                LOG_ONCE(log_unimpl("Setting clipboard not supported"));
+                _gui.setClipboard(boost::any_cast<std::string>(e.arg()));
                 return boost::blank();
 
             case HostMessage::RESIZE_STAGE:
diff --git a/gui/gtk/gtk.cpp b/gui/gtk/gtk.cpp
index 964c5d2..5decf51 100644
--- a/gui/gtk/gtk.cpp
+++ b/gui/gtk/gtk.cpp
@@ -333,6 +333,14 @@ GtkGui::error(const std::string& msg)
     gtk_box_pack_start(GTK_BOX(content), label, false, false, 0);
     gtk_widget_show_all(popup);
 } 
+    
+void
+GtkGui::setClipboard(const std::string& copy)
+{
+    GtkClipboard* cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+    gtk_clipboard_clear(cb);
+    gtk_clipboard_set_text(cb, copy.c_str(), copy.size());
+}
 
 void
 GtkGui::setFullscreen()
diff --git a/gui/gtk/gtksup.h b/gui/gtk/gtksup.h
index 1ccb560..ba49507 100644
--- a/gui/gtk/gtksup.h
+++ b/gui/gtk/gtksup.h
@@ -77,6 +77,8 @@ public:
     virtual double getPixelAspectRatio() const;
     virtual std::pair<int, int> screenResolution() const;
     virtual double getScreenDPI() const;
+
+    virtual void setClipboard(const std::string& copy);
     
     bool watchFD(int fd);
 
diff --git a/gui/gui.cpp b/gui/gui.cpp
index 329b20c..cc8b8f4 100644
--- a/gui/gui.cpp
+++ b/gui/gui.cpp
@@ -175,6 +175,12 @@ Gui::~Gui()
     }
 #endif
 }
+    
+void
+Gui::setClipboard(const std::string&)
+{
+    LOG_ONCE(log_unimpl(_("Clipboard not yet supported in this GUI")));
+}
 
 void
 Gui::setFullscreen()
diff --git a/gui/gui.h b/gui/gui.h
index 8b1190b..6f37a31 100644
--- a/gui/gui.h
+++ b/gui/gui.h
@@ -192,6 +192,8 @@ public:
     /// Sets the current mouse cursor for the Gui window.
     virtual void setCursor(gnash_cursor_type newcursor);
 
+    virtual void setClipboard(const std::string& copy);
+
     // Information for System.capabilities to be reimplemented in
     // each gui.
     virtual double getPixelAspectRatio() const { return 0; }
diff --git a/libcore/movie_root.h b/libcore/movie_root.h
index 92bbfa0..5846394 100644
--- a/libcore/movie_root.h
+++ b/libcore/movie_root.h
@@ -1098,8 +1098,8 @@ T
 movie_root::callInterface(const HostInterface::Message& e) const
 {
     if (!_interfaceHandler) {
-        log_error("Hosting application registered no callback for 
events/queries"
-            ", can't call %s(%s)");
+        log_error("Hosting application registered no callback for "
+                "messages, can't call %s(%s)");
         return T();
     }
 
diff --git a/utilities/processor.cpp b/utilities/processor.cpp
index 582c2b6..6dbfde6 100644
--- a/utilities/processor.cpp
+++ b/utilities/processor.cpp
@@ -28,7 +28,6 @@
 #include <ctime>
 #include <typeinfo>
 #include <boost/any.hpp>
-#include <boost/variant.hpp>
 
 #ifdef ENABLE_NLS
 # include <clocale>
@@ -168,11 +167,16 @@ public:
         log_debug(_("eventCallback: %s %s"), event);
 
            static bool mouseShown = true;
+           static std::string clipboard;
 
            if (event == HostMessage::QUERY) {
             return true;
         }
 
+           if (event == HostMessage::SET_CLIPBOARD) {
+            clipboard = boost::any_cast<std::string>(ev.arg());
+        }
+
            if (event == HostMessage::SHOW_MOUSE) {
             bool state = mouseShown;
             mouseShown = boost::any_cast<bool>(ev.arg());

http://git.savannah.gnu.org/cgit//commit/?id=06cfeb10bf99b790031ad7e0be84cae5d0c1f281


commit 06cfeb10bf99b790031ad7e0be84cae5d0c1f281
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 16:37:17 2010 +0100

    Const correct and improve interface.

diff --git a/gui/Player.cpp b/gui/Player.cpp
index c962c9f..c0ccae2 100644
--- a/gui/Player.cpp
+++ b/gui/Player.cpp
@@ -29,6 +29,9 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/variant.hpp>
 #include <boost/any.hpp>
+#include <utility>
+#include <memory>
+#include <vector>
 
 #include "gui.h"
 #include "NullGui.h"
@@ -149,8 +152,7 @@ public:
                 return boost::blank();
 
             case HostMessage::SCREEN_RESOLUTION:
-                return std::make_pair(_gui.getScreenResX(),
-                        _gui.getScreenResY());
+                return _gui.screenResolution();
 
             case HostMessage::SCREEN_DPI:
                 return _gui.getScreenDPI();
diff --git a/gui/gtk/gtk.cpp b/gui/gtk/gtk.cpp
index 484785c..964c5d2 100644
--- a/gui/gtk/gtk.cpp
+++ b/gui/gtk/gtk.cpp
@@ -503,33 +503,29 @@ GtkGui::showMenu(bool show)
 }
 
 double
-GtkGui::getPixelAspectRatio()
+GtkGui::getPixelAspectRatio() const
 {
     GdkScreen* screen = gdk_screen_get_default();
 
+    const std::pair<int, int> res = screenResolution();
+
     // Screen size / number of pixels = pixel size.
     // The physical size of the screen may be reported wrongly by gdk (from X),
     // but it's the best we have. This method agrees with the pp in my case.
     double pixelAspectRatio =
-        (gdk_screen_get_height_mm(screen) / 
static_cast<double>(getScreenResY())) / 
-        (gdk_screen_get_width_mm(screen) / 
static_cast<double>(getScreenResX()));
+        (gdk_screen_get_height_mm(screen) / static_cast<double>(res.first)) / 
+        (gdk_screen_get_width_mm(screen) / static_cast<double>(res.second));
     return pixelAspectRatio;
 }
 
-int
-GtkGui::getScreenResX()
-{
-    return gdk_screen_width();
-}
-
-int
-GtkGui::getScreenResY()
+std::pair<int, int>
+GtkGui::screenResolution() const
 {
-    return gdk_screen_height(); 
+    return std::make_pair(gdk_screen_width(), gdk_screen_height());
 }
 
 double
-GtkGui::getScreenDPI()
+GtkGui::getScreenDPI() const
 {
 #if GTK_CHECK_VERSION(2,10,0)
     GdkScreen* screen = gdk_screen_get_default();
diff --git a/gui/gtk/gtksup.h b/gui/gtk/gtksup.h
index 5f30229..1ccb560 100644
--- a/gui/gtk/gtksup.h
+++ b/gui/gtk/gtksup.h
@@ -24,6 +24,7 @@
 #endif
 
 #include <string>
+#include <utility>
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 
@@ -73,10 +74,9 @@ public:
     virtual void hideMenu();
 
     /// For System.capabilities information.
-    virtual double getPixelAspectRatio();
-    virtual int getScreenResX();
-    virtual int getScreenResY();
-    virtual double getScreenDPI();
+    virtual double getPixelAspectRatio() const;
+    virtual std::pair<int, int> screenResolution() const;
+    virtual double getScreenDPI() const;
     
     bool watchFD(int fd);
 
diff --git a/gui/gui.h b/gui/gui.h
index 574cc09..8b1190b 100644
--- a/gui/gui.h
+++ b/gui/gui.h
@@ -28,6 +28,7 @@
 #include <boost/function.hpp>
 #include <string>
 #include <map>
+#include <utility>
 
 #include "SWFRect.h"  // for composition
 #include "snappingrange.h"  // for InvalidatedRanges
@@ -193,17 +194,22 @@ public:
 
     // Information for System.capabilities to be reimplemented in
     // each gui.
-    virtual double getPixelAspectRatio() { return 0; }
-    virtual int getScreenResX() { return 0; }
-    virtual int getScreenResY() { return 0; }
-    virtual double getScreenDPI() { return 0; }
+    virtual double getPixelAspectRatio() const { return 0; }
+
+    virtual std::pair<int, int> screenResolution() const {
+        return std::make_pair(0, 0);
+    }
+
+    virtual double getScreenDPI() const { return 0; }
 
     /// Get the screen color type.
     //
     /// The choice is between "color" and something designating
     /// monochrome (not sure what). If this isn't implemented in the
     /// gui we return "color".
-    virtual std::string getScreenColor() { return "color"; }
+    virtual std::string getScreenColor() const {
+        return "color";
+    }
 
     /// @return Whether or not the movie should be looped indefinitely.
     bool loops() const { return _loop; }
@@ -429,10 +435,10 @@ public:
     virtual bool yesno(const std::string& question);
 
     /// Width of a window pixel, in stage pseudopixel units.
-    float getXScale() { return _xscale; };
+    float getXScale() const { return _xscale; };
 
     /// Height of a window pixel, in stage pseudopixel units.
-    float getYScale() { return _yscale; };
+    float getYScale() const { return _yscale; };
 
 protected:
 
@@ -480,10 +486,10 @@ protected:
 
 
     /// Determines if playback should restart after the movie ends.
-    bool            _loop;
+    bool _loop;
 
     /// The X Window ID to attach to. If zero, we create a new window.
-    unsigned long   _xid;
+    unsigned long _xid;
 
     // This would be 0,0,_width,_height, so maybe
     // we should not duplicate the info with those

http://git.savannah.gnu.org/cgit//commit/?id=59eb09bad652bb6141fb0eb2c9b2503affef7331


commit 59eb09bad652bb6141fb0eb2c9b2503affef7331
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 16:36:47 2010 +0100

    Include required headers.

diff --git a/gui/Player.h b/gui/Player.h
index eb21862..bd9e943 100644
--- a/gui/Player.h
+++ b/gui/Player.h
@@ -24,6 +24,12 @@
 #include "gnashconfig.h"
 #endif
 
+#include <boost/intrusive_ptr.hpp>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <map>
+#include <memory>
+
 #include "sound_handler.h"
 #include "MediaHandler.h" 
 #include "gui.h"
@@ -31,11 +37,6 @@
 #include "movie_root.h"
 #include "RunResources.h"
 
-#include <boost/intrusive_ptr.hpp>
-#include <string>
-#include <boost/shared_ptr.hpp>
-#include <map>
-
 // Forward declarations
 namespace gnash {
     class MovieClip;

http://git.savannah.gnu.org/cgit//commit/?id=6238c4d97126dfe65fc251b0761f24ab9b37436f


commit 6238c4d97126dfe65fc251b0761f24ab9b37436f
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 16:28:04 2010 +0100

    Use the pp's order for System.capabilities, more for easier checking
    than compatibility.

diff --git a/libcore/asobj/System_as.cpp b/libcore/asobj/System_as.cpp
index f2f45cd..f1f1755 100644
--- a/libcore/asobj/System_as.cpp
+++ b/libcore/asobj/System_as.cpp
@@ -246,33 +246,33 @@ attachSystemCapabilitiesInterface(as_object& o)
     const int flags = PropFlags::dontDelete
         | PropFlags::dontEnum | PropFlags::readOnly;
 
-    o.init_member("version", version, flags);
-    o.init_member("playerType", playerType, flags);
-    o.init_member("os", os, flags);
-    o.init_member("manufacturer", manufacturer, flags);
-    o.init_member("language", language, flags);
-    o.init_member("hasAudio", hasAudio, flags);
-    o.init_member("screenResolutionX", resX, flags);
-    o.init_member("screenResolutionY", resY, flags);
+    o.init_member("hasAccessibility", hasAccessibility, flags);
+    o.init_member("pixelAspectRatio", pixelAspectRatio, flags);
     o.init_member("screenColor", screenColor, flags);
     o.init_member("screenDPI", screenDPI, flags);
-    o.init_member("pixelAspectRatio", pixelAspectRatio, flags);
-    o.init_member("serverString", serverString.str(), flags);
-    o.init_member("avHardwareDisable", avHardwareDisable, flags);
+    o.init_member("screenResolutionY", resY, flags);
+    o.init_member("screenResolutionX", resX, flags);
+    o.init_member("hasTLS", hasTLS, flags);
+    o.init_member("hasVideoEncoder", hasVideoEncoder, flags);
     o.init_member("hasAudioEncoder", hasAudioEncoder, flags);
-    o.init_member("hasEmbeddedVideo", hasEmbeddedVideo, flags);
     o.init_member("hasMP3", hasMP3, flags);
-    o.init_member("hasPrinting", hasPrinting, flags);
-    o.init_member("hasScreenBroadcast", hasScreenBroadcast, flags);
-    o.init_member("hasScreenPlayback", hasScreenPlayback, flags);
+    o.init_member("hasAudio", hasAudio, flags);
+    o.init_member("serverString", serverString.str(), flags);
+    o.init_member("version", version, flags);
     o.init_member("hasStreamingAudio", hasStreamingAudio, flags);
     o.init_member("hasStreamingVideo", hasStreamingVideo, flags);
-    o.init_member("hasVideoEncoder", hasVideoEncoder, flags);
-    o.init_member("hasAccessibility", hasAccessibility, flags);
+    o.init_member("hasEmbeddedVideo", hasEmbeddedVideo, flags);
+    o.init_member("hasPrinting", hasPrinting, flags);
+    o.init_member("hasScreenPlayback", hasScreenPlayback, flags);
+    o.init_member("hasScreenBroadcast", hasScreenBroadcast, flags);
     o.init_member("isDebugger", isDebugger, flags);
+    o.init_member("playerType", playerType, flags);
+    o.init_member("avHardwareDisable", avHardwareDisable, flags);
     o.init_member("localFileReadDisable", localFileReadDisable, flags);
-    o.init_member("hasTLS", hasTLS, flags);
     o.init_member("windowlessDisable", windowlessDisable, flags);
+    o.init_member("os", os, flags);
+    o.init_member("manufacturer", manufacturer, flags);
+    o.init_member("language", language, flags);
 }
 
 void

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


commit fb4f789a1f262d3b836b877e4fc698702eeeabd1
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 16:19:57 2010 +0100

    Return "color" by default.

diff --git a/gui/gui.h b/gui/gui.h
index 9afc5f8..574cc09 100644
--- a/gui/gui.h
+++ b/gui/gui.h
@@ -197,7 +197,13 @@ public:
     virtual int getScreenResX() { return 0; }
     virtual int getScreenResY() { return 0; }
     virtual double getScreenDPI() { return 0; }
-    virtual std::string getScreenColor() { return ""; }
+
+    /// Get the screen color type.
+    //
+    /// The choice is between "color" and something designating
+    /// monochrome (not sure what). If this isn't implemented in the
+    /// gui we return "color".
+    virtual std::string getScreenColor() { return "color"; }
 
     /// @return Whether or not the movie should be looped indefinitely.
     bool loops() const { return _loop; }

http://git.savannah.gnu.org/cgit//commit/?id=17046db1a33994cf2ad43dea8a0fabe7f946e3f6


commit 17046db1a33994cf2ad43dea8a0fabe7f946e3f6
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 16:19:46 2010 +0100

    Add a note on pixel aspect ratio.

diff --git a/libcore/asobj/System_as.cpp b/libcore/asobj/System_as.cpp
index 04a156f..f2f45cd 100644
--- a/libcore/asobj/System_as.cpp
+++ b/libcore/asobj/System_as.cpp
@@ -152,6 +152,8 @@ attachSystemCapabilitiesInterface(as_object& o)
     const double aspectRatio = m.callInterface<double>(HostMessage(
                 HostMessage::PIXEL_ASPECT_RATIO));
 
+    // Note that the pp uses the current locale to display the
+    // ratio (for the decimal separator).
     std::ostringstream s;
     s << std::setprecision(7) << aspectRatio;
     const std::string pixelAspectRatio = s.str();

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


commit 3ef126b594e6857a5991ecece5e0626321cdd0c1
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 15:38:48 2010 +0100

    Add new host interface.

diff --git a/gui/Player.cpp b/gui/Player.cpp
index 88a1e65..c962c9f 100644
--- a/gui/Player.cpp
+++ b/gui/Player.cpp
@@ -26,8 +26,9 @@
 
 #include <iostream>
 #include <sstream>
-#include <iomanip>
 #include <boost/lexical_cast.hpp>
+#include <boost/variant.hpp>
+#include <boost/any.hpp>
 
 #include "gui.h"
 #include "NullGui.h"
@@ -51,6 +52,7 @@
 #include "ScreenShotter.h"
 #include "GnashSystemIOHeaders.h" // for write() 
 #include "log.h"
+#include "HostInterface.h"
 
 using namespace gnash;
 
@@ -58,6 +60,123 @@ namespace {
     gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance();
 }
 
+namespace {
+
+class MessageHandler : public boost::static_visitor<boost::any>
+{
+public:
+    explicit MessageHandler(Gui& g) : _gui(g) {}
+
+    boost::any operator()(const HostMessage& e) {
+
+        switch (e.event()) {
+
+            case HostMessage::ERROR:
+                _gui.error(boost::any_cast<std::string>(e.arg()));
+                return boost::blank();
+
+            case HostMessage::QUERY:
+                return _gui.yesno(boost::any_cast<std::string>(e.arg()));
+
+            case HostMessage::SHOW_MOUSE:
+            {
+                // Must return a bool, true if the mouse was visible before.
+                return _gui.showMouse(boost::any_cast<bool>(e.arg()));   
+            }
+
+            case HostMessage::SET_DISPLAYSTATE:
+            {
+                const movie_root::DisplayState s =
+                    boost::any_cast<movie_root::DisplayState>(e.arg());
+                if (s == movie_root::DISPLAYSTATE_FULLSCREEN) {
+                    _gui.setFullscreen();
+                }
+                else if (s == movie_root::DISPLAYSTATE_NORMAL) {
+                    _gui.unsetFullscreen();
+                }
+                return boost::blank();
+            }
+
+            case HostMessage::UPDATE_STAGE:
+                _gui.updateStageMatrix();
+                return boost::blank();
+
+            case HostMessage::SHOW_MENU:
+                _gui.showMenu(boost::any_cast<bool>(e.arg()));
+                return boost::blank();
+
+            case HostMessage::SET_CLIPBOARD:
+                LOG_ONCE(log_unimpl("Setting clipboard not supported"));
+                return boost::blank();
+
+            case HostMessage::RESIZE_STAGE:
+            {
+                if (_gui.isPlugin()) {
+                    log_debug("Player doing nothing on Stage.resize as we're a 
plugin");
+                    return boost::blank();
+                }
+
+                typedef std::pair<int, int> Dimensions;
+                const Dimensions i = boost::any_cast<Dimensions>(e.arg());
+                _gui.resizeWindow(i.first, i.second);
+                return boost::blank();
+            }
+            case HostMessage::EXTERNALINTERFACE_ISPLAYING:
+                return (_gui.isStopped()) ? false : true;
+
+            case HostMessage::EXTERNALINTERFACE_PAN:
+                log_unimpl("GUI ExternalInterface.Pan event");
+                return boost::blank();
+
+            case HostMessage::EXTERNALINTERFACE_PLAY:
+                _gui.play();
+                return boost::blank();
+
+            case HostMessage::EXTERNALINTERFACE_REWIND:
+                _gui.restart();
+                return boost::blank();
+
+            case HostMessage::EXTERNALINTERFACE_SETZOOMRECT:
+                log_unimpl("GUI ExternalInterface.SetZoomRect event");
+                return boost::blank();
+
+            case HostMessage::EXTERNALINTERFACE_STOPPLAY:
+                _gui.pause();
+                return boost::blank();
+
+            case HostMessage::EXTERNALINTERFACE_ZOOM:
+                log_unimpl("GUI ExternalInterface.Zoom event");
+                return boost::blank();
+
+            case HostMessage::SCREEN_RESOLUTION:
+                return std::make_pair(_gui.getScreenResX(),
+                        _gui.getScreenResY());
+
+            case HostMessage::SCREEN_DPI:
+                return _gui.getScreenDPI();
+
+            case HostMessage::SCREEN_COLOR:
+                return _gui.getScreenColor();
+
+            case HostMessage::PIXEL_ASPECT_RATIO:
+                return _gui.getPixelAspectRatio();
+
+            case HostMessage::PLAYER_TYPE:
+                return std::string(_gui.isPlugin() ? "PlugIn" : "StandAlone");
+        }
+        log_error(_("Unhandled callback %s with arguments %s"), +e.event());
+        return boost::blank();
+    }
+
+    boost::any operator()(const CustomMessage& /*e*/) {
+        return boost::blank();
+    }
+private:
+    Gui& _gui;
+};
+
+}
+
 void
 Player::setFlashVars(const std::string& varstr)
 {
@@ -168,7 +287,7 @@ Player::init_sound()
             return;
 #endif
 
-        } catch (SoundException& ex) {
+        } catch (const SoundException& ex) {
             log_error(_("Could not create sound handler: %s."
                 " Will continue w/out sound."), ex.what());
         }
@@ -539,137 +658,17 @@ Player::CallbacksHandler::exit()
     _gui.quit();
 }
 
-void
-Player::CallbacksHandler::error(const std::string& msg)
-{
-    _gui.error(msg);
-}
-
-bool
-Player::CallbacksHandler::yesNo(const std::string& query)
+boost::any
+Player::CallbacksHandler::call(const HostInterface::Message& e)
 {
-    return _gui.yesno(query);
-}
-
-std::string
-Player::CallbacksHandler::call(const std::string& event, const std::string& 
arg)
-{
-    StringNoCaseEqual noCaseCompare;
-        
-    if (event == "Mouse.hide") {
-        return _gui.showMouse(false) ? "true" : "false";
-    }
-
-    if (event == "Mouse.show") {
-        return _gui.showMouse(true) ? "true" : "false";
-    }
-    
-    if (event == "Stage.displayState") {
-        if (arg == "fullScreen") _gui.setFullscreen();
-        else if (arg == "normal") _gui.unsetFullscreen();
-        return "";
-    }
-
-    if (event == "Stage.scaleMode" || event == "Stage.align" ) {
-        _gui.updateStageMatrix();
-        return "";
-    }
-
-    if (event == "Stage.showMenu") {
-        if (noCaseCompare(arg, "true")) _gui.showMenu(true);
-        else if (noCaseCompare(arg, "false")) _gui.showMenu(false);
-        return "";
-    }
-
-    if (event == "Stage.resize") {
-        if ( _gui.isPlugin() ) {
-            log_debug("Player doing nothing on Stage.resize as we're a 
plugin");
-            return "";
-        }
-
-        // arg contains WIDTHxHEIGHT
-        log_debug("Player got Stage.resize(%s) message", arg);
-        int width, height;
-        std::sscanf(arg.c_str(), "%dx%d", &width, &height);
-        _gui.resizeWindow(width, height);
-
-        return "";
-    }
-
-    if (event == "ExternalInterface.Play") {
-        _gui.play();
-        return "";
-    }
-
-    if (event == "ExternalInterface.StopPlay") {
-        _gui.pause();
-        return "";
-    }
-
-    if (event == "ExternalInterface.Rewind") {
-        _gui.restart();
-        return "";
-    }
-
-    if (event == "ExternalInterface.Pan") {
-        // FIXME: the 3 args are encoded as 1:2:0
-        log_unimpl("ExternalInterface.Pan");
-        return "";
-    }
-
-    if (event == "ExternalInterface.IsPlaying") {
-        return (_gui.isStopped()) ? "false" : "true";
-    }
-
-    if (event == "ExternalInterface.SetZoomRect") {
-        // FIXME: the 4 arguments are encoded as 1:2:0:1
-        log_unimpl("ExternalInterface.SetZoomRect");
-        return "";
-    }
-
-    if (event == "ExternalInterface.Zoom") {
-        // The 1 argument is a percentage to zoom
-        const int percent = std::strtol(arg.c_str(), NULL, 0);
-        log_unimpl("ExternalInterface.Zoom(%d)", percent);
-        return "";
-    }
-
-    if (event == "System.capabilities.screenResolutionX") {
-        std::ostringstream ss;
-        ss << _gui.getScreenResX();
-        return ss.str();
-    }
-
-    if (event == "System.capabilities.screenResolutionY") {
-        std::ostringstream ss;
-        ss << _gui.getScreenResY();
-        return ss.str();
-    }
-
-    if (event == "System.capabilities.pixelAspectRatio") {
-        std::ostringstream ss;
-        // Whether the pp actively limits the precision or simply
-        // gets a slightly different result isn't clear.
-        ss << std::setprecision(7) << _gui.getPixelAspectRatio();
-        return ss.str();
-    }
-
-    if (event == "System.capabilities.screenDPI") {
-        std::ostringstream ss;
-        ss << _gui.getScreenDPI();
-        return ss.str();
+    MessageHandler v(_gui);
+    try {
+        return boost::apply_visitor(v, e);
     }
-
-    if (event == "System.capabilities.screenColor") {
-        return _gui.getScreenColor();
+    catch (const boost::bad_any_cast&) {
+        log_error(_("Got unexpected argument type for message %1%"), e);
+        return boost::blank();
     }
-
-    if (event == "System.capabilities.playerType") {
-        return _gui.isPlugin() ? "PlugIn" : "StandAlone";
-    }
-
-    log_error(_("Unhandled callback %s with arguments %s"), event, arg);
-    return "";
 }
 
 void
diff --git a/gui/Player.h b/gui/Player.h
index a7ab972..eb21862 100644
--- a/gui/Player.h
+++ b/gui/Player.h
@@ -37,14 +37,11 @@
 #include <map>
 
 // Forward declarations
-namespace gnash
-{
+namespace gnash {
     class MovieClip;
 }
 
-
-namespace gnash
-{
+namespace gnash {
 
 /// This class is an attempt at simplifying the code required
 /// to simply start the SWF player. The idea was to use it
@@ -215,8 +212,7 @@ private:
     /// being the default.
     std::string _renderer;
 
-    class CallbacksHandler : public movie_root::AbstractIfaceCallback,
-                             public movie_root::AbstractFsCallback
+    class CallbacksHandler : public HostInterface, public FsCallback
     {
     public:
         CallbacksHandler(Gui& gui, const Player& player)
@@ -226,11 +222,7 @@ private:
         {
         }
         
-        std::string call(const std::string& event, const std::string& arg);
-        
-        bool yesNo(const std::string& query);
-        
-        void error(const std::string& msg);
+        boost::any call(const HostInterface::Message& e);
 
         void exit();
         
diff --git a/libcore/HostInterface.cpp b/libcore/HostInterface.cpp
new file mode 100644
index 0000000..66c3e02
--- /dev/null
+++ b/libcore/HostInterface.cpp
@@ -0,0 +1,103 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 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 "HostInterface.h"
+
+#include <boost/variant.hpp>
+#include <boost/any.hpp>
+#include <string>
+#include <ostream>
+
+namespace gnash {
+
+namespace {
+
+struct MessageOutput : public boost::static_visitor<std::ostream&>
+{
+    MessageOutput(std::ostream& os) : _os(os) {}
+    std::ostream& operator()(const HostMessage& e) const {
+        return _os << e.event();
+    }
+    std::ostream& operator()(const CustomMessage& e) const {
+        return _os << e.name();
+    }
+private:
+    std::ostream& _os;
+};
+
+}
+
+std::ostream&
+operator<<(std::ostream& os, const HostInterface::Message& e)
+{
+    return boost::apply_visitor(MessageOutput(os), e);
+}
+
+std::ostream&
+operator<<(std::ostream& os, HostMessage::KnownEvent e)
+{
+    struct Wrapper {
+        Wrapper(std::ostream& os) : _os(os << "<") {}
+        ~Wrapper() { _os << ">"; }
+        std::ostream& _os;
+    } a(os);
+
+    switch (e) {
+        case HostMessage::SHOW_MOUSE:
+            return os << "show mouse";
+        case HostMessage::RESIZE_STAGE:
+            return os << "resize stage";
+        case HostMessage::SHOW_MENU:
+            return os << "show menu";
+        case HostMessage::UPDATE_STAGE:
+            return os << "update stage";
+        case HostMessage::SET_DISPLAYSTATE:
+            return os << "set display state";
+        case HostMessage::SET_CLIPBOARD:
+            return os << "set clipboard";
+        case HostMessage::SCREEN_RESOLUTION:
+            return os << "screen resolution";
+        case HostMessage::SCREEN_DPI:
+            return os << "screen DPI";
+        case HostMessage::PIXEL_ASPECT_RATIO:
+            return os << "pixel aspect ratio";
+        case HostMessage::PLAYER_TYPE:
+            return os << "player type";
+        case HostMessage::SCREEN_COLOR:
+            return os << "screen color";
+        case HostMessage::EXTERNALINTERFACE_ISPLAYING:
+            return os << "ExternalInterface.isPlaying";
+        case HostMessage::EXTERNALINTERFACE_PAN:
+            return os << "ExternalInterface.pan";
+        case HostMessage::EXTERNALINTERFACE_PLAY:
+            return os << "ExternalInterface.play";
+        case HostMessage::EXTERNALINTERFACE_REWIND:
+            return os << "ExternalInterface.rewind";
+        case HostMessage::EXTERNALINTERFACE_SETZOOMRECT:
+            return os << "ExternalInterface.setZoomRect";
+        case HostMessage::EXTERNALINTERFACE_STOPPLAY:
+            return os << "ExternalInterface.stopPlay";
+        case HostMessage::EXTERNALINTERFACE_ZOOM:
+            return os << "ExternalInterface.zoom";
+        default:
+            return os << "Unknown event " << +e;
+    }
+}
+
+} // namespace gnash
+
diff --git a/libcore/HostInterface.h b/libcore/HostInterface.h
new file mode 100644
index 0000000..5393327
--- /dev/null
+++ b/libcore/HostInterface.h
@@ -0,0 +1,239 @@
+// 
+//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 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
+
+/// \page interface Host Interface
+///
+/// The core Gnash libraries support a flexible way of interacting with
+/// hosting applications. This is necessary for ActionScript execution, as
+/// well as for user notifications.
+///
+/// 1. The hosting application may ignore any message without dangerous
+///    side effects.
+///
+/// 2. A set of expected messages exist, which should be supported for
+///    proper ActionScript compatibility.
+///
+/// 3. Users must return the exact type expected (see KnownEvent), as
+///    no implicit conversion is used. This means, for instance, that
+///    where a std::string is expected, a const char* may not be used.
+///
+/// 4. There is the possibility to add custom messages for use in
+///    ActionScript extensions.
+///
+/// The rationale for the current design is that hosting applications
+/// should be able to support as many of the expected messages types as
+/// they choose using a single interface: gnash::HostInterface::call(). This
+/// should support various types of argument and various types of
+/// return, so that the different 
+///
+/// The drawback of this flexibility is that there is no compile-time
+/// check for the correct use of the interface. Within the core
+/// libraries, this host interface is accessed only through
+/// gnash::movie_root::callInterface(),
+/// ensuring that any mistakes in the hosting application are handled
+/// safely and logged.
+
+#ifndef GNASH_HOST_INTERFACE_H
+#define GNASH_HOST_INTERFACE_H
+
+#include <boost/variant.hpp>
+#include <boost/any.hpp>
+#include <string>
+#include <ostream>
+
+namespace gnash {
+
+/// A custom form of communication with the host application.
+//
+/// This comprises a string and any type of argument.
+class CustomMessage
+{
+public:
+    explicit CustomMessage(const std::string& s,
+            const boost::any& arg = boost::blank())
+        :
+        _name(s),
+        _arg(arg)
+    {}
+    const std::string& name() const { return _name; }
+    const boost::any& arg() const { return _arg; }
+private:
+    std::string _name;
+    boost::any _arg;
+};
+
+/// Built-in forms of communication with the host application.
+//
+/// These messages should be supported for ActionScript compatibility.
+class HostMessage
+{
+public:
+
+    /// The messages that a hosting application should handle.
+    //
+    /// 
+    enum KnownEvent {
+
+        /// Whether to display a mouse pointer
+        /// - Argument type: bool
+        /// - Effects: show mouse if true, hide if false
+        /// - Return: boolean, true if the mouse was visible before
+        SHOW_MOUSE,
+
+        /// Resize the stage
+        /// - Argument type: std::pair<int, int>(x, y)
+        /// - Effects: resize stage to x pixels by y pixels
+        /// - Return: none
+        RESIZE_STAGE,
+
+        /// Update the stage
+        /// - Argument type: none
+        /// - Effects: update the stage
+        /// - Return: none
+        UPDATE_STAGE,
+
+        /// Whether to show the menu or not
+        /// - Argument type: bool 
+        /// - Effects: show menu if true, hide if false
+        /// - Return: none
+        /// @todo   This is probably insufficient.
+        SHOW_MENU,
+
+        /// Whether to show in fullscreen or not
+        /// - Argument type: movie_root::DisplayState
+        /// - Effects: display fullscreen if 
movie_root::DISPLAYSTATE_FULLSCREEN,
+        ///            otherwise normal
+        /// - Return: none
+        SET_DISPLAYSTATE,
+
+        /// Set system clipboard
+        /// - Argument type: std::string
+        /// - Effects: set system clipboard
+        /// - Return: none
+        SET_CLIPBOARD,
+
+        /// Get screen resolution
+        /// - Argument type: none
+        /// - Effects: get screen resolution
+        /// - Return: std::pair<int, int>(x, y)
+        SCREEN_RESOLUTION,
+
+        /// Get screen DPI.
+        /// - Argument type: none
+        /// - Effects: get screen DPI
+        /// - Return: double
+        SCREEN_DPI,
+
+        /// Get pixel aspect ratio
+        /// - Argument type: none
+        /// - Effects: return pixel aspect ratio
+        /// - Return: double
+        PIXEL_ASPECT_RATIO,
+
+        /// Get player type
+        /// - Argument type: none
+        /// - Effects: return "Plugin" or "StandAlone"
+        /// - Return: std::string
+        PLAYER_TYPE,
+
+        /// Get screen color
+        /// - Argument type: none
+        /// - Effects: return "Color" or something else
+        /// - Return: std::string
+        SCREEN_COLOR,
+
+        /// Notify an error
+        /// - Argument type: std::string
+        /// - Effects: notify the user of an error
+        /// - Return: none
+        ERROR,
+
+        /// Ask a question
+        /// - Argument type: std::string
+        /// - Effects: get the answer to a question
+        /// - Return: bool
+        QUERY,
+
+        /// @todo check if the following types are appropriate.
+        EXTERNALINTERFACE_ISPLAYING,
+        EXTERNALINTERFACE_PAN,
+        EXTERNALINTERFACE_PLAY,
+        EXTERNALINTERFACE_REWIND,
+        EXTERNALINTERFACE_SETZOOMRECT,
+        EXTERNALINTERFACE_STOPPLAY,
+        EXTERNALINTERFACE_ZOOM
+    };
+
+    explicit HostMessage(KnownEvent e, const boost::any& arg = boost::blank())
+        :
+        _event(e),
+        _arg(arg)
+    {}
+
+    KnownEvent event() const { return _event; }
+    const boost::any& arg() const { return _arg; }
+
+private:
+    KnownEvent _event;
+    boost::any _arg;
+};
+
+/// Abstract base class for FS handlers
+class FsCallback
+{
+public:
+    virtual void notify(const std::string& cmd, const std::string& arg) = 0;
+    virtual ~FsCallback() {}
+};
+
+/// Abstract base class for hosting app handler
+class HostInterface
+{
+public:
+
+    virtual ~HostInterface() {}
+
+    typedef boost::variant<HostMessage, CustomMessage> Message;
+
+    /// Pass a message to the hosting application with an optional return
+    //
+    /// The core library should access this function through
+    /// movie_root::callInterface() or movie_root::callInterface<>()
+    //
+    /// @param e    The message to pass
+    /// @return     A return of any type. Both callers and users
+    ///             should know the expected type.
+    virtual boost::any call(const Message& e) = 0;
+
+    /// Instruct the hosting application to exit.
+    //
+    /// The hosting application may ignore this: do not rely on it
+    /// to exit the program.
+    virtual void exit() = 0;
+
+};
+
+/// Stream a description of any host interface message type.
+std::ostream& operator<<(std::ostream& os, const HostInterface::Message& e);
+
+/// Stream a description of an expected message.
+std::ostream& operator<<(std::ostream& os, HostMessage::KnownEvent e);
+
+} // namespace gnash
+
+#endif
diff --git a/libcore/Makefile.am b/libcore/Makefile.am
index b3f4ca4..9adace6 100644
--- a/libcore/Makefile.am
+++ b/libcore/Makefile.am
@@ -77,6 +77,7 @@ libgnashcore_la_SOURCES = \
        parser/filter_factory.cpp \
        InteractiveObject.cpp \
        ExternalInterface.cpp \
+       HostInterface.cpp \
        SWFMatrix.cpp \
        SWFMovie.cpp \
        movie_root.cpp \
@@ -161,6 +162,7 @@ noinst_HEADERS = \
        SWFMovie.h \
        SWFStream.h \
        MovieLibrary.h \
+       HostInterface.h \
        ExternalInterface.h \
        swf/tag_loaders.h \
        swf/DefineBitsTag.h \
diff --git a/libcore/asobj/Mouse_as.cpp b/libcore/asobj/Mouse_as.cpp
index c9a9b7d..7f44dc2 100644
--- a/libcore/asobj/Mouse_as.cpp
+++ b/libcore/asobj/Mouse_as.cpp
@@ -92,7 +92,8 @@ as_value
 mouse_hide(const fn_call& fn)
 {
     movie_root& m = getRoot(fn);
-    const int success = (m.callInterface("Mouse.hide") == "true") ? 1 : 0;
+    const int success =
+        m.callInterface<bool>(HostMessage(HostMessage::SHOW_MOUSE, true));
 
     // returns 1 if mouse was visible before call.
     return as_value(success);
@@ -105,7 +106,8 @@ as_value
 mouse_show(const fn_call& fn)
 {
     movie_root& m = getRoot(fn);
-    const int success = (m.callInterface("Mouse.show") == "true") ? 1 : 0;
+    const int success = 
+        m.callInterface<bool>(HostMessage(HostMessage::SHOW_MOUSE, false));
 
     // returns 1 if Mouse was visible before call.
     return as_value(success);
diff --git a/libcore/asobj/NetStream_as.cpp b/libcore/asobj/NetStream_as.cpp
index 3506811..4203767 100644
--- a/libcore/asobj/NetStream_as.cpp
+++ b/libcore/asobj/NetStream_as.cpp
@@ -443,7 +443,7 @@ NetStream_as::initVideoDecoder(const media::VideoInfo& info)
 
         // This is important enough to let the user know.
         movie_root& m = getRoot(owner());
-        m.errorInterface(e.what());
+        m.callInterface(HostMessage(HostMessage::ERROR, 
std::string(e.what())));
     }
 
 }
@@ -471,7 +471,7 @@ NetStream_as::initAudioDecoder(const media::AudioInfo& info)
 
         // This is important enough to let the user know.
         movie_root& m = getRoot(owner());
-        m.errorInterface(e.what());
+        m.callInterface(HostMessage(HostMessage::ERROR, 
std::string(e.what())));
     }
 
 }
diff --git a/libcore/asobj/System_as.cpp b/libcore/asobj/System_as.cpp
index 5f273d5..04a156f 100644
--- a/libcore/asobj/System_as.cpp
+++ b/libcore/asobj/System_as.cpp
@@ -22,6 +22,8 @@
 
 #include <sstream>
 #include <string>
+#include <iomanip>
+#include <boost/tuple/tuple.hpp>
 
 #include "movie_root.h" // interface callback
 #include "log.h"
@@ -33,6 +35,7 @@
 #include "VM.h" // for getPlayerVersion() 
 #include "GnashAlgorithm.h"
 #include "RunResources.h"
+#include "HostInterface.h"
 
 namespace gnash {
 
@@ -42,9 +45,6 @@ namespace {
 
     inline std::string trueFalse(bool x) { return x ? "t" : "f"; }
 
-    template<typename T> inline void convertValue(const std::string& in,
-                                                  T& val);
-
     std::string systemLanguage(as_object& proto);
 
     as_value system_security_allowdomain(const fn_call& fn);
@@ -140,25 +140,28 @@ attachSystemCapabilitiesInterface(as_object& o)
 
     const movie_root& m = vm.getRoot();
 
-    int screenResolutionX;
-    convertValue(m.callInterface("System.capabilities.screenResolutionX"),
-            screenResolutionX);
-    int screenResolutionY;
-    convertValue(m.callInterface("System.capabilities.screenResolutionY"),
-            screenResolutionY);
-    int screenDPI;
-    convertValue(m.callInterface("System.capabilities.screenDPI"), screenDPI);
-        
-    // Documented to be a number, but is in fact a string.
-    const std::string pixelAspectRatio = 
-        m.callInterface("System.capabilities.pixelAspectRatio");
+    int resX;
+    int resY;
+
+    boost::tie(resX, resY) = m.callInterface<std::pair<int, int> >(
+            HostMessage(HostMessage::SCREEN_RESOLUTION));
+
+    const double screenDPI = m.callInterface<double>(HostMessage(
+                HostMessage::SCREEN_DPI));
+
+    const double aspectRatio = m.callInterface<double>(HostMessage(
+                HostMessage::PIXEL_ASPECT_RATIO));
+
+    std::ostringstream s;
+    s << std::setprecision(7) << aspectRatio;
+    const std::string pixelAspectRatio = s.str();
 
     // "StandAlone", "External", "PlugIn", "ActiveX" (get from GUI)
-    const std::string playerType =
-        m.callInterface("System.capabilities.playerType");
+    const std::string playerType = m.callInterface<std::string>(HostMessage(
+                HostMessage::PLAYER_TYPE));
 
-    const std::string screenColor =
-        m.callInterface("System.capabilities.screenColor");
+    const std::string screenColor = m.callInterface<std::string>(HostMessage(
+                HostMessage::SCREEN_COLOR));
 
     //
     // Media
@@ -224,18 +227,18 @@ attachSystemCapabilitiesInterface(as_object& o)
                  << "&SP="     << trueFalse(hasScreenPlayback) 
                  << "&SB="     << trueFalse(hasScreenBroadcast) 
                  << "&DEB="    << trueFalse(isDebugger)
-                 << "&V="       << URL::encode(version)
-                 << "&M="       << URL::encode(manufacturer)
-                 << "&R="       << screenResolutionX << "x" << 
screenResolutionY
+                 << "&V="   << URL::encode(version)
+                 << "&M="   << URL::encode(manufacturer)
+                 << "&R="   << resX << "x" << resY
                  << "&DP="     << screenDPI
                  << "&COL="    << screenColor                                  
-                 << "&AR="      << pixelAspectRatio
-                 << "&OS="      << URL::encode(os)
-                 << "&L="       << language                    
-                 << "&PT="      << playerType
+                 << "&AR="  << pixelAspectRatio
+                 << "&OS="  << URL::encode(os)
+                 << "&L="   << language                        
+                 << "&PT="  << playerType
                  << "&AVD="    << trueFalse(avHardwareDisable) 
                  << "&LFD="    << trueFalse(localFileReadDisable)
-                 << "&WD="      << trueFalse(windowlessDisable)
+                 << "&WD="  << trueFalse(windowlessDisable)
                  << "&TLS="    << trueFalse(hasTLS);
     
     const int flags = PropFlags::dontDelete
@@ -247,8 +250,8 @@ attachSystemCapabilitiesInterface(as_object& o)
     o.init_member("manufacturer", manufacturer, flags);
     o.init_member("language", language, flags);
     o.init_member("hasAudio", hasAudio, flags);
-    o.init_member("screenResolutionX", screenResolutionX, flags);
-    o.init_member("screenResolutionY", screenResolutionY, flags);
+    o.init_member("screenResolutionX", resX, flags);
+    o.init_member("screenResolutionY", resY, flags);
     o.init_member("screenColor", screenColor, flags);
     o.init_member("screenDPI", screenDPI, flags);
     o.init_member("pixelAspectRatio", pixelAspectRatio, flags);
@@ -270,16 +273,6 @@ attachSystemCapabilitiesInterface(as_object& o)
     o.init_member("windowlessDisable", windowlessDisable, flags);
 }
 
-/// Convert a string to the type passed in, making sure the target variable
-/// is initialized.
-template<typename T>
-inline void
-convertValue(const std::string& in, T& val)
-{
-    std::istringstream is(in);
-    if (!(is >> val)) val = T();
-} 
-
 void
 attachSystemInterface(as_object& proto)
 {
@@ -338,9 +331,16 @@ system_security_loadpolicyfile(const fn_call& /*fn*/)
 }
 
 as_value
-system_setClipboard(const fn_call& /*fn*/)
+system_setClipboard(const fn_call& fn)
 {
-    LOG_ONCE(log_unimpl("System.setClipboard"));
+    if (!fn.nargs) {
+        return as_value();
+    }
+
+    const std::string& s = fn.arg(0).to_string();
+    movie_root& m = getRoot(fn);
+    m.callInterface(HostMessage(HostMessage::SET_CLIPBOARD, s));
+
     return as_value();
 }
 
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index a0531bd..3ecf5f6 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -230,12 +230,13 @@ movie_root::setRootMovie(Movie* movie)
     cleanupAndCollect();
 }
 
-/*private*/
 void
 movie_root::handleActionLimitHit(const std::string& msg)
 {
     bool disable = true;
-    if (_interfaceHandler) disable = _interfaceHandler->yesNo(msg);
+    if (_interfaceHandler) {
+        disable = callInterface<bool>(HostMessage(HostMessage::QUERY, msg));
+    }
     else {
         log_error("No user interface registered, assuming 'Yes' answer to "
             "question: %s", msg);
@@ -305,9 +306,9 @@ movie_root::setLevel(unsigned int num, Movie* movie)
 
             // notify  stage replacement
             if (_interfaceHandler) {
-                std::stringstream ss;
-                ss << _stageWidth << "x" << _stageHeight;
-                _interfaceHandler->call("Stage.resize", ss.str());
+                const HostMessage e(HostMessage::RESIZE_STAGE,
+                        std::make_pair(_stageWidth, _stageHeight));
+                _interfaceHandler->call(e);
             }
         }
 
@@ -1144,7 +1145,7 @@ void
 movie_root::setStageAlignment(short s)
 {
     _alignMode = s;
-    callInterface("Stage.align");
+    callInterface(HostMessage(HostMessage::UPDATE_STAGE));
 }
 
 /// The mode is one of never, always, with sameDomain the default
@@ -1197,7 +1198,7 @@ movie_root::setShowMenuState(bool state)
     //   or shows the menubar. Flash expects this option to disable some 
     //   context menu items.
     // callInterface is the proper handler for this
-    callInterface("Stage.showMenu", (_showMenu) ? "true" : "false"); 
+    callInterface(HostMessage(HostMessage::SHOW_MENU, _showMenu)); 
 }
 
 /// Returns the string representation of the current align mode,
@@ -1242,7 +1243,7 @@ movie_root::setStageScaleMode(ScaleMode sm)
     }
 
     _scaleMode = sm;
-    callInterface("Stage.align");    
+    callInterface(HostMessage(HostMessage::UPDATE_STAGE));
 
     if (notifyResize) {
         as_object* stage = getBuiltinObject(*this, NSV::CLASS_STAGE);
@@ -1265,15 +1266,8 @@ movie_root::setStageDisplayState(const DisplayState ds)
 
     if (!_interfaceHandler) return; // No registered callback
     
-    switch (_displayState)
-    {
-        case DISPLAYSTATE_FULLSCREEN:
-            callInterface("Stage.displayState", "fullScreen");
-            break;
-        case DISPLAYSTATE_NORMAL:
-            callInterface("Stage.displayState", "normal");
-            break;
-    }   
+    HostMessage e(HostMessage::SET_DISPLAYSTATE, _displayState);
+    callInterface(e);
 }
 
 void
@@ -1517,9 +1511,10 @@ movie_root::processInvoke(ExternalInterface::invoke_t 
*invoke)
         log_unimpl("ExternalInterface::GotoFrame()");
     // GotoFrame doesn't send a response
     } else if (invoke->name == "IsPlaying") {
-        std::string result = callInterface("ExternalInterface.IsPlaying");
-        as_value val((result == "true") ? true : false);
-    ss << ExternalInterface::toXML(val);    
+        const bool result = 
+            
callInterface<bool>(HostMessage(HostMessage::EXTERNALINTERFACE_ISPLAYING));
+        as_value val(result);
+        ss << ExternalInterface::toXML(val);    
     } else if (invoke->name == "LoadMovie") {
         log_unimpl("ExternalInterface::LoadMovie()");
     // LoadMovie doesn't send a response
@@ -1531,7 +1526,7 @@ movie_root::processInvoke(ExternalInterface::invoke_t 
*invoke)
         arg += invoke->args[1].to_string();
         arg += ":";
         arg += invoke->args[2].to_string();
-        callInterface("ExternalInterface.Pan", arg);
+        callInterface(HostMessage(HostMessage::EXTERNALINTERFACE_PAN, arg));
     // Pan doesn't send a response
     } else if (invoke->name == "PercentLoaded") {
         MovieClip *mc = getLevel(0);
@@ -1541,10 +1536,10 @@ movie_root::processInvoke(ExternalInterface::invoke_t 
*invoke)
         // PercentLoaded sends the percentage
         ss << ExternalInterface::toXML(val);    
     } else if (invoke->name == "Play") {
-        callInterface("ExternalInterface.Play");
+        callInterface(HostMessage(HostMessage::EXTERNALINTERFACE_PLAY));
     // Play doesn't send a response
     } else if (invoke->name == "Rewind") {
-        callInterface("ExternalInterface.Rewind");
+        callInterface(HostMessage(HostMessage::EXTERNALINTERFACE_REWIND));
     // Rewind doesn't send a response
     } else if (invoke->name == "SetZoomRect") {
         std::string arg = invoke->args[0].to_string();
@@ -1556,14 +1551,14 @@ movie_root::processInvoke(ExternalInterface::invoke_t 
*invoke)
         arg += invoke->args[2].to_string();
         arg += ":";
         arg += invoke->args[3].to_string();
-        callInterface("ExternalInterface.SetZoomRect", arg);
+        callInterface(HostMessage(HostMessage::EXTERNALINTERFACE_SETZOOMRECT, 
arg));
     // SetZoomRect doesn't send a response
     } else if (invoke->name == "StopPlay") {
-        callInterface("ExternalInterface.StopPlay");
+        callInterface(HostMessage(HostMessage::EXTERNALINTERFACE_STOPPLAY));
     // StopPlay doesn't send a response
     } else if (invoke->name == "Zoom") {
         std::string var = invoke->args[0].to_string();
-        callInterface("ExternalInterface.Zoom", var);
+        callInterface(HostMessage(HostMessage::EXTERNALINTERFACE_ZOOM, var));
     // Zoom doesn't send a response
     } else if (invoke->name == "TotalFrames") {
         MovieClip *mc = getLevel(0);
@@ -2216,23 +2211,6 @@ movie_root::handleFsCommand(const std::string& cmd, 
const std::string& arg)
     if (_fsCommandHandler) _fsCommandHandler->notify(cmd, arg);
 }
 
-void
-movie_root::errorInterface(const std::string& msg) const
-{
-    if (_interfaceHandler) _interfaceHandler->error(msg);
-}
-
-std::string
-movie_root::callInterface(const std::string& cmd, const std::string& arg) const
-{
-    if (_interfaceHandler) return _interfaceHandler->call(cmd, arg);
-
-    log_error("Hosting application registered no callback for events/queries"
-        ", can't call %s(%s)", cmd, arg);
-
-    return "<no iface to hosting app>";
-}
-
 bool
 isLevelTarget(int version, const std::string& name, unsigned int& levelno)
 {
@@ -2364,6 +2342,18 @@ movie_root::LoadCallback::processLoad()
     return true;
 }
 
+void
+movie_root::callInterface(const HostInterface::Message& e) const
+{
+    if (!_interfaceHandler) {
+        log_error("Hosting application registered no callback for 
events/queries"
+            ", can't call %s(%s)");
+        return;
+    }
+    _interfaceHandler->call(e);
+}
+
+
 inline bool
 movie_root::testInvariant() const
 {
@@ -2384,7 +2374,6 @@ namespace {
 bool
 generate_mouse_button_events(movie_root& mr, MouseButtonState& ms)
 {
-
     // Did this event trigger any action that needs redisplay ?
     bool need_redisplay = false;
 
diff --git a/libcore/movie_root.h b/libcore/movie_root.h
index c16e187..92bbfa0 100644
--- a/libcore/movie_root.h
+++ b/libcore/movie_root.h
@@ -77,6 +77,7 @@
 #include <boost/array.hpp>
 #include <boost/ptr_container/ptr_deque.hpp>
 #include <boost/noncopyable.hpp>
+#include <boost/any.hpp>
 
 #include "smart_ptr.h" // GNASH_USE_GC
 #include "dsodefs.h" // DSOEXPORT
@@ -91,6 +92,8 @@
 #include "ExternalInterface.h"
 #include "GC.h"
 #include "VM.h"
+#include "HostInterface.h"
+#include "log.h"
 
 #ifdef USE_SWFTREE
 # include "tree.hh"
@@ -696,16 +699,14 @@ public:
 
     /// Set a filedescriptor to use for host application requests
     /// (for browser communication mostly)
-    void setHostFD(int fd)
-    {
+    void setHostFD(int fd) {
         assert(fd >= 0);
         _hostfd = fd;
     }
 
     /// Set a filedescriptor to use for host application requests
     /// (for browser communication mostly)
-    void setControlFD(int fd)
-    {
+    void setControlFD(int fd) {
         _controlfd = fd;
     }
 
@@ -713,24 +714,14 @@ public:
     /// (for browser communication mostly)
     ///
     /// @return -1 if no filedescriptor is provided by host app.
-    int getHostFD() const
-    {
+    int getHostFD() const {
         return _hostfd;
     }
 
-    int getControlFD() const
-    {
+    int getControlFD() const {
         return _controlfd;
     }
 
-
-    /// Abstract base class for FS handlers
-    class AbstractFsCallback {
-    public:
-        virtual void notify(const std::string& cmd, const std::string& arg)=0;
-        virtual ~AbstractFsCallback() {}
-    };
-
     /// ActionScript embedded in a movie can use the built-in
     /// fscommand() function to send data back to the host
     /// application.  If you are interested in this data, register
@@ -740,8 +731,7 @@ public:
     /// The handler gets the MovieClip* that the script is
     /// embedded in, and the two string arguments passed by the
     /// script to fscommand().
-    DSOEXPORT void registerFSCommandCallback(AbstractFsCallback* handler)
-    {
+    DSOEXPORT void registerFSCommandCallback(FsCallback* handler) {
         _fsCommandHandler = handler;
     }
 
@@ -749,58 +739,31 @@ public:
     DSOEXPORT void handleFsCommand(const std::string& cmd,
             const std::string& arg) const;
     
-    /// Abstract base class for hosting app handler
-    class AbstractIfaceCallback
-    {
-    public:
-
-        /// Get Gui-related information for the core.
-        //
-        /// This should be used for occasional AS calls, such as for
-        /// Mouse.hide, System.capabilities etc. The return can be
-        /// various types, so it is passed as a string.
-        virtual std::string call(const std::string& cmd,
-                const std::string& arg = std::string()) = 0;
-
-        /// Ask the hosting application for a yes / no answer to
-        /// a question.
-        virtual bool yesNo(const std::string& cmd) = 0;
-
-        /// Instruct the hosting application to exit.
-        virtual void exit() = 0;
-
-        /// Send an error message to the hosting application.
-        //
-        /// This does not have to be implemented; the default is a no-op.
-        virtual void error(const std::string& /*msg*/) {}
-
-        virtual ~AbstractIfaceCallback() {}
-    };
-
     /// A callback to the GUI (or whatever is listening) for sending
     /// events and receiving replies. Used for ActionScript interface
     /// with the gui (Mouse visibility, Stage alignment etc and System
     /// information, for instance).
     ///
     /// See callInterface method
-    DSOEXPORT void registerEventCallback(AbstractIfaceCallback* handler)
-    {
+    DSOEXPORT void registerEventCallback(HostInterface* handler) {
         _interfaceHandler = handler;
     }
 
-    /// Call into the hosting application
-    ///
-    /// Will use callback set with registerEventCallback
-    DSOEXPORT std::string callInterface(const std::string& cmd,
-            const std::string& arg = std::string()) const;
+    /// Call the hosting application without expecting a reply.
+    //
+    /// @param e    The message to send to the interface.
+    void callInterface(const HostInterface::Message& e) const;
 
-    /// Send an error message to the hosting application.
+    /// Call the hosting application, ensuring a return of the requested type.
     //
-    /// @param msg  A message to send describing the error.
+    /// If the return type is other than the requested type, this represents
+    /// a bug in the hosting application. An error is logged and the default
+    /// constructed type T is returned. This may unexpected
+    /// ActionScript behaviour, but is otherwise safe.
     //
-    /// The hosting app decides what to do with the message, or whether it
-    /// wants to do anything at all. It may show a popup box.
-    DSOEXPORT void errorInterface(const std::string& msg) const;
+    /// @tparam T   The return type expected. 
+    /// @param e    The message to send to the interface.
+    template<typename T> T callInterface(const HostInterface::Message& e) 
const;
 
     /// Called from the ScriptLimits tag parser to set the
     /// global script limits. It is expected behaviour that
@@ -821,8 +784,7 @@ public:
     
     /// Get the current global recursion limit for this movie: it can
     /// be changed by loaded movies.
-    boost::uint16_t getRecursionLimit() const
-    {
+    boost::uint16_t getRecursionLimit() const {
         return _recursionLimit;
     }
 
@@ -996,10 +958,10 @@ private:
     VM _vm;
 
     /// Registered Interface command handler, if any
-    AbstractIfaceCallback* _interfaceHandler;
+    HostInterface* _interfaceHandler;
 
     /// Registered FsCommand handler, if any
-    AbstractFsCallback* _fsCommandHandler;
+    FsCallback* _fsCommandHandler;
 
     /// A list of AdvanceableCharacters
     //
@@ -1131,6 +1093,27 @@ bool isLevelTarget(int version, const std::string& name, 
unsigned int& levelno);
 
 DSOEXPORT short stringToStageAlign(const std::string& s);
 
+template<typename T>
+T
+movie_root::callInterface(const HostInterface::Message& e) const
+{
+    if (!_interfaceHandler) {
+        log_error("Hosting application registered no callback for 
events/queries"
+            ", can't call %s(%s)");
+        return T();
+    }
+
+    try {
+        return boost::any_cast<T>(_interfaceHandler->call(e));
+    }
+    catch (const boost::bad_any_cast&) {
+        log_error(_("Unexpected type from host interface when requesting "
+                "%1%"), e); 
+        return T();
+    }
+}
+
+
 } // namespace gnash
 
 #endif // GNASH_MOVIE_ROOT_H
diff --git a/utilities/processor.cpp b/utilities/processor.cpp
index f1d3142..582c2b6 100644
--- a/utilities/processor.cpp
+++ b/utilities/processor.cpp
@@ -17,23 +17,24 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-
 #ifdef HAVE_CONFIG_H
 #include "gnashconfig.h"
 #endif
 
-#include "NullSoundHandler.h"
-
 #include <ios>
 #include <iostream>
 #include <cstdio>
 #include <cstdlib>
 #include <ctime>
+#include <typeinfo>
+#include <boost/any.hpp>
+#include <boost/variant.hpp>
 
 #ifdef ENABLE_NLS
 # include <clocale>
 #endif
 
+#include "NullSoundHandler.h"
 #include "MovieFactory.h"
 #include "swf/TagLoadersTable.h"
 #include "swf/DefaultTagLoaders.h"
@@ -54,6 +55,7 @@
 #include "GnashSleep.h" // for usleep comptibility.
 #include "StreamProvider.h"
 #include "RunResources.h"
+#include "HostInterface.h"
 
 #ifdef RENDERER_AGG
 #include "Renderer.h"
@@ -141,7 +143,7 @@ secondsSinceLastAdvance()
 //
 static int quitrequested = false;
 
-class FsCommandExecutor: public movie_root::AbstractFsCallback {
+class FsCommandExecutor: public FsCallback {
 public:
        void notify(const std::string& command, const std::string& args)
        {
@@ -153,60 +155,52 @@ public:
        }
 };
 
-class EventCallback: public movie_root::AbstractIfaceCallback
+class EventCallback: public HostInterface
 {
 public:
-       std::string call(const std::string& event, const std::string& arg)
+    boost::any call(const HostInterface::Message& e)
        {
-           log_debug(_("eventCallback: %s %s"), event, arg);
+        if (e.type() != typeid(HostMessage)) return boost::blank();
+
+        const HostMessage& ev = boost::get<HostMessage>(e);
+        const HostMessage::KnownEvent event = ev.event();
+
+        log_debug(_("eventCallback: %s %s"), event);
 
            static bool mouseShown = true;
 
-           // These should return "true" if the mouse was visible before
-           // the call.
-           if ( event == "Mouse.hide" ) {
-            bool state = mouseShown;
-            mouseShown = false;
-            return state ? "true" : "false";
-           }
+           if (event == HostMessage::QUERY) {
+            return true;
+        }
 
-           if ( event == "Mouse.show" ) {
+           if (event == HostMessage::SHOW_MOUSE) {
             bool state = mouseShown;
-            mouseShown = true;
-            return state ? "true" : "false" ;
+            mouseShown = boost::any_cast<bool>(ev.arg());
+            return state ? true : false ;
            }
            
            // Some fake values for consistent test results.
            
-           if ( event == "System.capabilities.screenResolutionX" ) {
-            return "800";
+           if (event == HostMessage::SCREEN_RESOLUTION) {
+            return std::make_pair(800, 640);
            }
 
-           if ( event == "System.capabilities.screenResolutionY" ) {
-            return "640";
-           } 
-
-           if ( event == "System.capabilities.screenDPI" ) {
-            return "72";
+           if (event == HostMessage::SCREEN_DPI) {
+            return 72.0;
            }        
 
-           if ( event == "System.capabilities.screenColor" ) {
+           if (event == HostMessage::SCREEN_COLOR) {
             return "Color";
            } 
 
-           if ( event == "System.capabilities.playerType" ) {
+           if (event == HostMessage::PLAYER_TYPE) {
             return "StandAlone";
            } 
 
-           return "";
+           return boost::blank();
 
        }
 
-    bool yesNo(const std::string& /*query*/)
-    {
-        return true;
-    }
-
     void exit() {
         std::exit(EXIT_SUCCESS);
     }

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


commit 3cee7f1b50f5d0ec3ed29089d9394ee908e9c29d
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 15:38:01 2010 +0100

    There is no page

diff --git a/libsound/sound_handler.h b/libsound/sound_handler.h
index 6d4acdb..1f3444c 100644
--- a/libsound/sound_handler.h
+++ b/libsound/sound_handler.h
@@ -16,12 +16,6 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-
-/// \page sound_handler_intro Sound handler introduction
-///
-/// The implementation of this class *must* be thread safe!
-///
-
 #ifndef SOUND_HANDLER_H
 #define SOUND_HANDLER_H
 

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


commit b6c2fe0648119e0a29737086cf73220d0e56b7ce
Author: Benjamin Wolsey <address@hidden>
Date:   Tue Dec 7 15:37:51 2010 +0100

    Put clocktime under Gnash namespace

diff --git a/libbase/ClockTime.cpp b/libbase/ClockTime.cpp
index 9bb2cd8..4168cb4 100644
--- a/libbase/ClockTime.cpp
+++ b/libbase/ClockTime.cpp
@@ -1,4 +1,4 @@
-// Time.cpp: clock and local time functions for Gnash
+// ClockTime.cpp: clock and local time functions for Gnash
 // 
 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
 //   Foundation, Inc
@@ -17,71 +17,10 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/// \page wall_clock_time Wall clock time
-///
-/// Gnash has three time implementations: one using boost::date_time,
-/// which handles portability itself, one for POSIX systems and one for 
-/// Win32.
-///
-/// Namespace clocktime contains a unified source for wall clock time: this
-/// is used mainly for the timing of movie advances and in the ActionScript
-/// Date class. FPS profiling also uses clocktime:: for a relatively high
-/// resolution, robust timer.
-///
-/// The boost::date_time has the great advantage of handling portability 
itself,
-/// as well as being able to handle a much larger range of true dates. Its
-/// disadvantage is that date_time requires not only header files, but also
-/// a run-time library, and thus increases the requirements.
-///
-/// @todo review this page, some bits seem obsoleted
-
 #include <boost/cstdint.hpp>
 #include "ClockTime.h"
 #include "log.h"
 
-// Define USE_BOOST_DATE_TIME to use boost as the basis for all
-// clock time functions. The function getTimeZoneOffset() is not
-// yet implemented for boost, but will only affect the Date class.
-#undef USE_BOOST_DATE_TIME
-
-#ifdef USE_BOOST_DATE_TIME
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/microsec_time_clock.hpp>
-
-using namespace boost::posix_time;
-
-boost::uint64_t
-clocktime::getTicks()
-{
-
-    // Midnight, 1st January 1970: the Epoch.
-    static const posix_time::ptime epoch (from_time_t(0));
-    
-    // Time between now and the Epoch.
-    posix_time::time_duration elapsed = (microsec_clock::local_time() - epoch);
-    
-    // Divisor to convert ticks to milliseconds
-    const int denominator = time_duration::ticks_per_second() / 1000.0;
-    
-    return elapsed.ticks() / denominator;
-}
-
-boost::int32_t
-clocktime::getTimeZoneOffset()
-{
-    // Obviously this doesn't work yet. Using this method
-    // may come up against the problem that boost won't handle
-    // dates outside its limits. However, ActionScript seems
-    // not to regard dates later than 2037 as having dst (this
-    // may depend on a machine-specific tz database) and there
-    // could also be a lower limit.
-
-    return 0;
-}
-
-#else // not using boost::date_time
-
 #include <ctime> // for time_t, localtime
 
 #ifdef HAVE_FTIME
@@ -102,6 +41,7 @@ extern long timezone;   // for tzset()/long timezone;
 #  include <windows.h>
 #  include <mmsystem.h>
 
+namespace gnash {
 
 boost::uint64_t
 clocktime::getTicks()
@@ -110,9 +50,13 @@ clocktime::getTicks()
     return timeGetTime();
 }
 
+}
+
 # else // not _WIN32
 #  include <sys/time.h>
 
+namespace gnash {
+
 boost::uint64_t
 clocktime::getTicks()
 {
@@ -129,8 +73,12 @@ clocktime::getTicks()
     return static_cast<boost::uint64_t>(result / 1000.0);
 }
 
+}
+
 # endif // not WIN32
 
+namespace gnash {
+
 /// Common non-boost function to return the present time offset.
 /// This all seems like a terrible hack. It was moved from Date.cpp,
 /// whence the following explanation also comes.
@@ -283,6 +231,5 @@ clocktime::getTimeZoneOffset(double time)
 #endif // No gmoff
 }
 
+} // namespace gnash
 
-
-#endif // Not using boost::date_time
diff --git a/libbase/ClockTime.h b/libbase/ClockTime.h
index 1f64b8d..ed516b8 100644
--- a/libbase/ClockTime.h
+++ b/libbase/ClockTime.h
@@ -24,8 +24,9 @@
 #include <boost/cstdint.hpp>
 #include "dsodefs.h"
 
-namespace clocktime
-{
+namespace gnash {
+
+namespace clocktime {
     /// Wall clock timer, returns current POSIX time in milliseconds.
        DSOEXPORT boost::uint64_t getTicks();
 
@@ -34,6 +35,7 @@ namespace clocktime
        /// cannot be regarded as reliable.
        DSOEXPORT boost::int32_t getTimeZoneOffset(double time);
 
-}
+} // namespace clocktime
+} // namespace gnash
 
 #endif

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


commit ebb410b630e22ec5ee576e27f5d9480c0ac6dd9b
Merge: 8656e9d 277d8f0
Author: Benjamin Wolsey <address@hidden>
Date:   Mon Dec 6 12:07:39 2010 +0100

    Merge branch 'master' of git.sv.gnu.org:/srv/git/gnash


http://git.savannah.gnu.org/cgit//commit/?id=8656e9d2bc656253fbfa3d6971fb52090dc4d37d


commit 8656e9d2bc656253fbfa3d6971fb52090dc4d37d
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Dec 5 19:30:26 2010 +0100

    Reorder includes.

diff --git a/gui/Player.cpp b/gui/Player.cpp
index 707b427..88a1e65 100644
--- a/gui/Player.cpp
+++ b/gui/Player.cpp
@@ -22,17 +22,21 @@
 #include "gnashconfig.h"
 #endif
 
+#include "Player.h"
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <boost/lexical_cast.hpp>
+
 #include "gui.h"
 #include "NullGui.h"
-
 #include "MovieFactory.h"
 #include "movie_definition.h"
 #include "sound_handler.h" // for set_sound_handler and create_sound_handler_*
 #include "MovieClip.h" // for setting FlashVars
 #include "movie_root.h" 
-#include "Player.h"
 #include "StreamProvider.h"
-
 #include "swf/TagLoadersTable.h"
 #include "swf/DefaultTagLoaders.h"
 #include "NamingPolicy.h"
@@ -45,13 +49,8 @@
 #include "SystemClock.h"
 #include "ExternalInterface.h"
 #include "ScreenShotter.h"
-
 #include "GnashSystemIOHeaders.h" // for write() 
 #include "log.h"
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-#include <boost/lexical_cast.hpp>
 
 using namespace gnash;
 

http://git.savannah.gnu.org/cgit//commit/?id=4650458f903d0d847f7036975536bed115f67270


commit 4650458f903d0d847f7036975536bed115f67270
Author: Benjamin Wolsey <address@hidden>
Date:   Sun Dec 5 19:12:23 2010 +0100

    Drop odd define and use std:: for stdlib functions.

diff --git a/gui/Player.cpp b/gui/Player.cpp
index c3d2ea6..707b427 100644
--- a/gui/Player.cpp
+++ b/gui/Player.cpp
@@ -22,10 +22,6 @@
 #include "gnashconfig.h"
 #endif
 
-#ifndef DEFAULT_GUI
-# define DEFAULT_GUI "NULL"
-#endif
-
 #include "gui.h"
 #include "NullGui.h"
 
@@ -595,7 +591,7 @@ Player::CallbacksHandler::call(const std::string& event, 
const std::string& arg)
         // arg contains WIDTHxHEIGHT
         log_debug("Player got Stage.resize(%s) message", arg);
         int width, height;
-        sscanf(arg.c_str(), "%dx%d", &width, &height);
+        std::sscanf(arg.c_str(), "%dx%d", &width, &height);
         _gui.resizeWindow(width, height);
 
         return "";
@@ -617,25 +613,25 @@ Player::CallbacksHandler::call(const std::string& event, 
const std::string& arg)
     }
 
     if (event == "ExternalInterface.Pan") {
-       // FIXME: the 3 args are encoded as 1:2:0
-       log_unimpl("ExternalInterface.Pan");
+        // FIXME: the 3 args are encoded as 1:2:0
+        log_unimpl("ExternalInterface.Pan");
         return "";
     }
 
     if (event == "ExternalInterface.IsPlaying") {
-       return (_gui.isStopped()) ? "false" : "true";
+        return (_gui.isStopped()) ? "false" : "true";
     }
 
     if (event == "ExternalInterface.SetZoomRect") {
-       // FIXME: the 4 arguments are encoded as 1:2:0:1
-       log_unimpl("ExternalInterface.SetZoomRect");
+        // FIXME: the 4 arguments are encoded as 1:2:0:1
+        log_unimpl("ExternalInterface.SetZoomRect");
         return "";
     }
 
     if (event == "ExternalInterface.Zoom") {
-       // The 1 argument is a percentage to zoom
-       int percent = strtol(arg.c_str(), NULL, 0);
-       log_unimpl("ExternalInterface.Zoom(%d)", percent);
+        // The 1 argument is a percentage to zoom
+        const int percent = std::strtol(arg.c_str(), NULL, 0);
+        log_unimpl("ExternalInterface.Zoom(%d)", percent);
         return "";
     }
 
diff --git a/gui/Player.h b/gui/Player.h
index eb16da4..a7ab972 100644
--- a/gui/Player.h
+++ b/gui/Player.h
@@ -226,8 +226,7 @@ private:
         {
         }
         
-        std::string call(const std::string& event,
-                         const std::string& arg);
+        std::string call(const std::string& event, const std::string& arg);
         
         bool yesNo(const std::string& query);
         

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

Summary of changes:
 gui/Player.cpp                 |  276 +++++++++++++-------------
 gui/Player.h                   |   28 +--
 gui/gtk/gtk.cpp                |   30 ++--
 gui/gtk/gtksup.h               |   10 +-
 gui/gui.cpp                    |    6 +
 gui/gui.h                      |   32 ++-
 libbase/ClockTime.cpp          |   75 +------
 libbase/ClockTime.h            |    8 +-
 libcore/HostInterface.cpp      |  103 ++++++++++
 libcore/HostInterface.h        |  239 ++++++++++++++++++++++
 libcore/Makefile.am            |    2 +
 libcore/asobj/Mouse_as.cpp     |    6 +-
 libcore/asobj/NetStream_as.cpp |  432 ++++++++++++++++++----------------------
 libcore/asobj/NetStream_as.h   |    4 -
 libcore/asobj/System_as.cpp    |  118 ++++++------
 libcore/movie_root.cpp         |   77 +++----
 libcore/movie_root.h           |  107 ++++------
 libsound/sound_handler.h       |    6 -
 utilities/processor.cpp        |   64 +++---
 19 files changed, 928 insertions(+), 695 deletions(-)
 create mode 100644 libcore/HostInterface.cpp
 create mode 100644 libcore/HostInterface.h


hooks/post-receive
-- 
Gnash



reply via email to

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