gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash/doc/C/usermanual/installation amf.xml as_...


From: Rob Savoye
Subject: [Gnash-commit] gnash/doc/C/usermanual/installation amf.xml as_...
Date: Sat, 01 Mar 2008 15:04:43 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    08/03/01 15:04:43

Added files:
        doc/C/usermanual/installation: amf.xml as_value.xml 
                                       codestyle.xml internals.xml 
                                       logging.xml main.xml memory.xml 
                                       new_as_class.xml object.xml 
                                       plugin.xml revisions.xml rtmp.xml 

Log message:
        Moved from user manual.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/amf.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/as_value.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/codestyle.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/internals.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/logging.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/main.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/memory.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/new_as_class.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/object.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/plugin.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/revisions.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/usermanual/installation/rtmp.xml?cvsroot=gnash&rev=1.1

Patches:
Index: amf.xml
===================================================================
RCS file: amf.xml
diff -N amf.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ amf.xml     1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,132 @@
+<sect1 id="amf">
+  <title>AMF Format</title>
+  
+  <para>
+    The AMF format is used in the LocalConnection, SharedObject,
+    NetConnection, and NetStream ActionScript classes. This is a means
+    of binary data interchange between Flash movies, or between a
+    Flash player and a Flash server.
+  </para>
+  
+  <para>
+    Like the RTMP messages, an AMF packet header can be of a variable
+    size. The size is either the same as the initial header of the
+    RTMP message, or a 1 byte header, which is commonly used for
+    streaming audio or video data.
+  </para>
+
+  <para>
+    The body of an AMF packet may look something like this
+    example. The spaces have been added for clarity.
+    
+    <screen>
+      02  0007 636f6e6e656374
+    </screen>
+
+    <variablelist>
+      <varlistentry>
+       <term>02</term>
+       <listitem>
+         <para>
+           This is a single byte header. The value of the first 2
+           bits is 0x3, and the AMF index is also 0x3.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0007</term>
+       <listitem>
+         <para>
+           This is the length in bytes of the string.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>63 6f 6e 6e 65 63 74</term>
+       <listitem>
+         <para>
+           This is the string. Note that there is no null terminator
+           since the length is specified.
+         </para>
+       </listitem>
+      </varlistentry>
+
+    </variablelist>
+
+  </para>
+
+<!--
+  <para>
+    These data types are used to exchange data between Flash
+    movies. The data part of a message is one of the ActionScript data
+    types.
+
+    <variablelist>
+      <varlistentry>
+       <term>Byte</term>
+       <listitem>
+         <para>
+           A single byte.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>Int</term>
+       <listitem>
+         <para>
+           Two bytes (a short).
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>MediumInt</term>
+       <listitem>
+         <para>
+           Three bytes.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>Long</term>
+       <listitem>
+         <para>
+           Four bytes (an int).
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>Double</term>
+       <listitem>
+         <para>
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>UTF8</term>
+       <listitem>
+         <para>
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term></term>
+       <listitem>
+         <para>
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>LongUTF8</term>
+       <listitem>
+         <para>
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist>    
+  </para>
+-->
+
+</sect1>
+  

Index: as_value.xml
===================================================================
RCS file: as_value.xml
diff -N as_value.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ as_value.xml        1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,75 @@
+    <sect1 id="as_value">
+      <title>The <emphasis>as_value</emphasis> Object Type</title>
+      <para>
+        The <emphasis>as_value</emphasis> class is used throughout
+        the interpreter to create generic objects to hold data.
+      </para>
+
+      <sect2 id="data_types">
+        <title>Data Types</title>
+        <para>
+          The following data types are supported:
+          <emphasis>NULLTYPE</emphasis>,
+          <emphasis>BOOLEAN</emphasis>, <emphasis>STRING</emphasis>,
+          <emphasis>NUMBER</emphasis>, <emphasis>OBJECT</emphasis>,
+          <emphasis>AS_FUNCTION</emphasis>, and 
+          <emphasis>MOVIECLIP</emphasis> (sprite).  
+          The type <emphasis>C_FUNCTION</emphasis> is being deprecated.
+        </para>
+      </sect2>
+
+      <sect2 id="is_methods">
+        <title>Determining the Type</title>
+        <para>
+          Several methods allow you to determine if a value stored in
+          <emphasis>as_value</emphasis> is of a specific type.  These
+          follow the form of <emphasis>is_TYPE</emphasis>, for example
+          <emphasis>is_as_function()</emphasis> and 
+          <emphasis>is_number()</emphasis>.  In general, the type names
+          match the <link linkend="data_types">data types</link> listed
+          above, with the exception of the type <emphasis>MOVIECLIP</emphasis>
+          which has a method <emphasis>is_sprite()</emphasis>.
+        </para>
+      </sect2>
+
+      <sect2 id="to_methods">
+        <title>Fetching the Value</title>
+        <para>
+          Another set of methods will return a representation of
+          the value as a particular type.  They follow the
+          <emphasis>to_TYPE</emphasis> naming convention.  Examples
+          are <emphasis>to_number()</emphasis> and
+          <emphasis>to_bool()</emphasis>.  The type names are as 
+          <link linkend="data_types">listed</link> earlier, except for
+          <emphasis>MOVIECLIP</emphasis>, which uses 
+          <emphasis>to_sprite()</emphasis>.
+        </para>
+      </sect2>
+
+      <sect2 id="set_methods">
+        <title>Setting the Value and Type</title>
+        <para>
+          Finally, there is the <emphasis>set_TYPE</emphasis> series
+          of methods.  They change the type to the type specified in
+          the method name, and set the value to the one given as an
+          argument.  It is also possible to accomplish the same thing
+          with the <emphasis>=</emphasis> operator.  Again, type names
+          match those <link linkend="data_types">named earlier</link>,
+          except in the case of <emphasis>MOVIECLASS</emphasis>.  Its
+          method is called <emphasis>set_sprite()</emphasis>.
+        </para>
+      </sect2>
+
+      <sect2 id="further_as_value_reading">
+        <title>Further Reading</title>
+        <para>
+          Please refer to <emphasis>as_value.h</emphasis> or the
+          Doxygen documentation (see 'Processing The Documentation'
+          in the &appname; manual for instructions on generating
+          documents with Doxygen) for more information
+          about which methods are available for the
+          <emphasis>as_value</emphasis> object.
+        </para>
+      </sect2>
+
+    </sect1>

Index: codestyle.xml
===================================================================
RCS file: codestyle.xml
diff -N codestyle.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ codestyle.xml       1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,167 @@
+<sect1 id="appendix">
+  <title>Appendix</title>
+  
+  <sect2 id="codestyle">
+    <title>Code Style</title>
+
+    <para>
+      I know any discussion of coding styles leads to strong opinions,
+      so I'll state simply I follow the <ulink type="http"
+      url="http://www.gnu.org/prep/standards/standards.html";>GNU
+      Coding Standards</ulink>. Where there is some flexibility as to
+      the location of braces, I prefer mine on the end of a line when
+      using an <emphasis>if</emphasis>, <emphasis>while</emphasis>, or 
<emphasis>do</emphasis>
+      statement. I find this more compact style easier to read and
+      parse by eye. I'm also a big fan of always using
+      braces around <emphasis>if</emphasis> statements, even if they're one
+      liners.
+    </para>
+
+    <para>
+      Here's my tweaked style settings for <emphasis>Emacs</emphasis>, the one
+      true editor to rule them all.
+
+      <programlisting>
+      (defconst my-style
+          '((c-tab-always-indent   . t)
+           (c-auto-newline        . t)
+           (c-hanging-braces-alist . (
+                                  (brace-list-intro)
+                                  (namespace-open)
+                                  (inline-open)
+                                  (block-open)
+                                  (brace-list-open)
+                                  (brace-list-close)
+                                  (brace-entry-open)
+                                  (brace-else-brace)
+                                  (brace-elseif-brace)
+                                  (class-open after)
+                                  (class-close)
+                                  (defun-open after)
+                                  (defun-close)
+                                  (extern-lang-open)
+                                  (inexpr-class-open)
+                                  (statement-open)
+                                  (substatement-open)
+                                  (inexpr-class-close)))
+            (c-hanging-colons-alist . ((member-init-intro before)
+                                   (inher-intro)
+                                   (case-label after)
+                                   (label after)
+                                   (access-label after)))
+            (c-offsets-alist   . (
+                                  (innamespace . 0)
+                                   (case-label  . 2)
+                                  ))
+            (c-cleanup-list    . (
+                                  (scope-operator)
+                                  (empty-defun-braces)
+                                  (brace-else-brace)
+                                  (brace-elseif-brace)
+                                  (defun-close-semi)
+                                  (list-close-comma)
+                                  )
+                               )
+    ;; no automatic newlines after ';' if following line non-blank or inside
+    ;; one-line inline methods
+    (add-to-list 'c-hanging-semi&amp;comma-criteria
+                'c-semi&amp;comma-no-newlines-before-nonblanks)
+    (add-to-list 'c-hanging-semi&amp;comma-criteria
+                'c-semi&amp;comma-no-newlines-for-oneline-inliners)
+;    (knr-argdecl-intro . -)
+    (c-echo-syntactic-information-p . t)
+    )
+  "My GNU Programming Style")
+    </programlisting>
+
+    </para>
+    
+    <para>
+      Another coding consideration: comments are good!  Over
+      commenting isn't good.  Here is an over commented example:
+
+      <programlisting>
+       counter++;              // increment counter
+      </programlisting>
+      
+      Gnash also uses <ulink type="http"
+      url="http://www.doxygen.org";>Doxygen</ulink> style
+      comments. These are processed by Doxygen when building a cross
+      reference of all the classes, and is a good way to help push
+      internals documentation from the depths of the code into
+      documentation where it can be seen by others.
+    </para>
+
+    <para>
+      <emphasis>Doxygen</emphasis> style comments for <emphasis>C++</emphasis> 
code involves
+      simply using three slashes <emphasis>///</emphasis> instead of the
+      standard two slashes <emphasis>//</emphasis> used for C++
+      comments. Here's a short comment block for the
+      <emphasis>XML::cloneNode()</emphasis> method:
+
+      <programlisting>
+       /// \brief copy a node
+       ///
+       /// Method; constructs and returns a new XML node of the same type,
+       /// name, value, and attributes as the specified XML object. If deep
+       /// is set to true, all child nodes are recursively cloned, resulting
+       /// in an exact copy of the original object's document tree.
+       XMLNode &amp;
+       XML::cloneNode(XMLNode &amp;newnode, bool deep) {
+       ...
+       }
+      </programlisting> 
+    </para>
+    
+    <para>
+      The <emphasis>\brief</emphasis> keyword means that the 
+      text becomes associated
+      when listing all the classes on the generated web pages. The
+      text after the blank link becomes the detailed description which
+      appears on the generated web page for that class and method.
+    </para>
+  </sect2>
+
+  &rtmp;
+
+<!--
+  <sect2 id="opcodes">
+    <title>Shockwave Movie Opcodes</title>
+
+    <sect3 id="v5">
+      <title>Version 5</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+    <sect3 id="v6">
+      <title>Version 6</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+    <sect3 id="v7">
+      <title>Version 7</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+    <sect3 id="v8">
+      <title>Version 8</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+    <sect3 id="v9">
+      <title>Version 9</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+
+  </sect2>
+-->
+
+</sect1>
+
+

Index: internals.xml
===================================================================
RCS file: internals.xml
diff -N internals.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ internals.xml       1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,1095 @@
+<sect1 id="internals">
+  <title>Software Internals</title>
+  
+  <sect2 id="tour">
+    <title>A Tour of Gnash</title>
+    
+    <para>
+      The top level of Gnash has several libraries, 
<emphasis>libgnashbase</emphasis>,
+      <emphasis>libgnashgeo</emphasis>, <emphasis>libgnashserver</emphasis>,
+      <emphasis>libgnashasobjs</emphasis> and
+      <emphasis>libgnashbackend</emphasis>. There are two utility programs 
+      included for debug parsing and processing of Flash movie files
+      which test the Actionscript interpreter. There is also a standalone
+      flash movie player.
+    </para>
+
+    <sect3 id="The Libraries">
+      <title>The Libraries</title>
+      
+      <sect4 id="libbase">
+       <title>libgnashbase</title>
+       
+       <para>
+         Libgnashbase contains support classes used by the rest of the
+         code. Among these classes is a small and efficient STL library
+         clone that uses smart pointers. A current goal is to replace
+         this small STL clone with standard STL containers to reduce
+         the amount of code which has to be maintained, and to add
+         functionality not currently in the smaller
+         implementation.
+       </para>
+
+       <para>
+         Gnash makes heavy use of smart pointers, so memory allocations
+         are freed up automatically by the interpreter.
+       </para>
+       
+      </sect4>
+      
+      <sect4 id="libgnashgeo">
+       <title>libgnashgeo</title>
+       
+       <para>
+         Libgnashgeo contains code for device independent graphics routines.
+       </para>
+       
+      </sect4>
+
+      <sect4 id="libgnashgui">
+       <title>libgnashgui</title>
+       
+       <para>
+         Libgnashgui contains code for a portable GUI class that
+         supports using GTK2, a framebuffer, SDL, or KDE.
+       </para>
+       
+      </sect4>
+
+      <sect4 id="libgnashserver">
+       <title>libgnashserver</title>
+       <para>
+         Libgnashserver is the guts of the interpreter itself. This is where
+         the main code for the interpreter lives. 
+       </para>
+      </sect4>
+
+      <sect4 id="libgnashasobjs">
+       <title>libgnashasobjs</title>
+       <para>
+         Libgnashasobjs contains all the ActionScript classes used by
+         the interpreter.
+       </para>
+      </sect4>
+
+      <sect4 id="libgnashamf">
+       <title>libgnashamf</title>
+       <para>
+         AMF is the data format used internally by Flash. This is
+         Gnash's support library to handle AMF data. This is
+         currently unused, but when the LocalConnection class is more
+         fully implemented, this will be used to transfer data
+         between flash movies.
+       </para>
+      </sect4>
+      
+      <sect4 id="libgnashbackend">
+       <title>libgnashbackend</title>
+       
+       <para>
+         Libgnashbackend is a small library containing OpenGL and SDL
+         code that glues this display to the Gnash display.
+       </para>
+       
+      </sect4>
+      <sect4 id="libgnashpluin">
+       <title>libgnashplugin</title>
+       
+       <para>
+         Libgnashplugin is the Mozilla/Firefox plugin.
+       </para>
+       
+      </sect4>
+      <sect4 id="libklashpart">
+       <title>libklashpart</title>
+       
+       <para>
+         Libklashpart is the Konqueror plugin.
+       </para>
+       
+      </sect4>
+    </sect3>
+
+
+    <sect3 id="apps">
+      <title>The Applications</title>
+      
+      <para>
+       There are currently a few standalone programs in Gnash,
+        which serve to either assist with Gnash development or play flash
+        movies.
+      </para>
+
+      <sect4 id="Gnash">
+       <title>The Standalone Player</title>
+       
+       <para>
+         This is the standalone OpenGL back-end used to play
+         movies. There are several command-line options and keyboard
+         control keys used by Gnash which <link linkend="usage"> are
+         documented here.</link> 
+       </para>
+
+      </sect4>
+
+      <sect4 id="parser">
+       <title>Gparser</title>
+       
+       <para>
+         Gparser uses the Gnash parser to disassemble the flash
+         movie, and dumps the object types, the depth, and other
+         information to make sure Gnash is parsing the file
+         correctly.
+       </para>
+
+      </sect4>
+      <sect4 id="processor">
+       <title>Gprocesser</title>
+       
+       <para>
+         Gprocesser is used to print out the actions (using the -va
+         option) or the parsing (using the -vp option) of a flash
+         movie. It is also used to produce the <emphasis>.gsc</emphasis>
+         files that Gnash uses to cache data, thereby speeding up the
+         loading of files.
+       </para>
+
+      </sect4>
+    </sect3>
+    
+    <sect3 id="plugin">
+      <title>The Plugin</title>
+
+      <para>
+       The plugin is designed to work within Mozilla or Firefox,
+       although there is Konqueror support as well. The plugin uses
+       the Mozilla NSPR plugin API to be cross platform, and is
+       portable, as well as being well integrated into Mozilla based
+       browsers.
+      </para>
+
+      <para>
+       One future thought for the plugin is to use the new Firefox
+       1.0.5 or greater version of Firefox. This version has added a
+        GTK drawable window which supports hardware acceleration, and
+       is designed to support things like rendering directly into the
+       window without needing OpenGL. 
+      </para>
+
+      <sect4 id="pluginstatus">
+       <title>Current Status</title>
+       <para>
+         As of March 30, 2006, the plugin works! This works in a
+         fashion similar to MozPlugger in that the standalone player
+         is used instead of using a thread. This gets around the
+         issue of having to maintain a separate player to support the
+         plugin. It also gets around the other issues that Gnash
+         itself is not thread safe at this time.
+       </para>
+       <para>
+         There are a few limitations in the current implementation,
+         but it works well enough to be used for web surfing. The
+         main limitations are the SDL version has no event handling,
+         and sound doesn't work yet.
+       </para>
+      </sect4>
+
+      <sect4 id="gui">
+       <title>GUI Support</title>
+
+       <para>
+         Any plugin that wants to display in a browser window needs
+         to be tied into the windowing system of the platform being
+         used. On GNU/Linux systems, Firefox is a GTK2+ application.
+         There is also KDE support through the use of the Klash
+         plugin.
+       </para>
+
+       <para>
+         Gnash can use either SDL or GTK now to create the window,
+         and to handle events for the standalone player. Work is
+         underway to add a portable interface for more windowing
+         toolkits to allow better embedded device support when
+         running in framebuffer only devices.
+       </para>
+       
+       <para>
+         The SDL version is more limited, but runs on all
+         platforms, including win32. It has no support for event
+         handling, which means mouse clicks, keyboard presses, and
+         window resizing doesn't work. I personally find the default
+         event handler slow and unresponsive. Gnash has support to
+         use fast events, (currently not enabled) which is an SDL
+         hack using a background thread to pump events into the SDL
+         event queue at a much higher rate.
+       </para>
+
+       <para>
+         There are a variety of development libraries that build a GUI
+         widget system on top of SDL and OpenGL. The use of these to
+         add menus and dialog boxes to the SDL version is being
+         considered. 
+       </para>
+
+       <para>
+         The GTK support is currently the most functional, and the
+         best integrated into Firefox. The performance of this
+         version is better than the SDL version because of the more
+         efficient event handling within GTK. For the best end user
+         experience, use the GTK enabled version.
+       </para>
+
+       <para>
+         GTK also allows Gnash to have menus and dialog
+         boxes. Currently this is only being utilized in a limited
+         fashion for now. There is a right mouse button menu that
+         allows the user to control the movie being player the same
+         way the existing keyboard commands do.
+       </para>
+
+      </sect4>
+      
+      <sect4 id="mozplugger">
+       <title>Mozplugger</title>
+
+       <para>
+         <ulink type="http"
+        url="http://mozplugger.mozdev.org/";>Mozplugger</ulink> is a
+         <emphasis>Mozilla/Firefox</emphasis> plugin that uses external
+         programs to play video, audio, and other multimedia content
+         in the browser. With some support added to the external
+         application, it's possible to force the external program to
+         use the internal window in the browser where this plugin is
+         supposed to display. This enables one to then run the
+         standalone player and display its output in the browser.
+       </para>
+
+       <para>
+         While this is not an optimal solution, it does enable one to
+         use Gnash as the flash player when browsing. The main issue
+         appears to be that the Flash movie being played doesn't get
+         any mouse or keyboard input. That may be a mozplugger
+         configuration issue, however.
+       </para>
+
+       <para>
+         Use of MozPlugger is obsolete now that the Gnash plugin
+         works. Still, this may be useful still on some platforms.
+       </para>
+
+       <para>
+         Add this to your <emphasis>$(HOME)/.mozilla/mozpluggerrc</emphasis>
+         file to enable this:
+
+         <programlisting>
+           application/x-shockwave-flash:swf:Shockwave Gnash
+        nokill embed noisy ignore_errors hidden fill swallow(Gnash) loop: 
gnash -v "$file" -x $window
+        : gnash -v "$file" -x $window
+         </programlisting>
+       </para>
+
+       <para>
+         Once this is added, you must delete the
+         <emphasis>$(HOME)/.mozilla/firefox/pluginreg.dat</emphasis> file to
+         force Firefox to register the plugins again. This is an
+         ASCII text file, so if the patch has been added correctly,
+         you'll see an entry for <emphasis>swf</emphasis> files after it is
+         recreated. You will need to restart Firefox to recreate this
+         file.
+       </para>
+
+       <para>
+         This file is not recreated immediately when restarting
+         Firefox, but waits till the first time a plugin is used. You
+         can force creation of this file by typing
+         <emphasis>about:plugins</emphasis> into the URL entry of the browser
+         window. The output will also contain information about the
+         mozplugger. You should see an entry for Gnash now.
+       </para>
+       
+      </sect4>
+
+      <sect4 id="Klash">
+       <title>Klash</title>
+       <para>
+         Klash is MozPlugger type support for KDE's Konqueror web
+         browser. Klash makes Gnash a <emphasis>kpart</emphasis>, so it's
+         integrated into KDE better than when using MozPlugger. Klash
+         uses the standalone player, utilizing Gnash's "-x" window
+         plugin command line option.
+       </para>
+
+       <para>
+         By default, Klash is not built. To enable building Klash,
+         use the <emphasis>--enable-klash</emphasis> option when
+         configuring. Other than installing, there is nothing else
+         that needs to be done to install Klash.
+       </para>
+      </sect4>
+
+      &plugin;
+
+    </sect3>
+
+    &logging;
+
+  </sect2>
+
+  <sect2 id="engine">
+    <title>The Interpreter Engine</title>
+    <para>
+      FIXME:
+    </para>
+    
+    <sect3 id="loop">
+      <title>The Main Loop</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+    
+    <sect3 id="io">
+      <title>I/O Processing</title>
+      <para>
+       FIXME:
+      </para>
+    </sect3>
+  </sect2>
+
+  <sect2 id="soundhandlers">
+    <title>Sound handling in Gnash</title>
+
+    <para>
+      When a SWF-file contains audio Gnash uses its sound handlers to play it.
+      At the moment there are two sound handlers, but it is likely that more 
+      will be made.
+    </para>
+
+    <para>
+      There are two different settings related to sound support:
+      <emphasis><link linkend="pluginsound">pluginsound</link></emphasis> and 
+      <emphasis><link linkend="standalonesound">sound</link></emphasis>. 
+      This was done in order to allow the plugin to be independently 
+      configured, for instance to block sound from advertisements.
+    </para>
+
+    <sect3 id="soundtypes">
+      <title>Sound types</title>
+      <para>
+        Sounds can be divided into two groups: event-sounds and soundstreams.
+       Event-sounds are contained in a single SWF frame, but the playtime can
+       span multiple frames. Soundstreams can be (and normally are) divided
+       between the SWF frames the soundstreams spans. This means that if a
+       gotoframe-action jumps to a frame which contains data for a soundstream,
+       playback of the stream can be picked up from there. 
+      </para>
+    </sect3>
+
+     <sect3 id="soundparsing">
+      <title>Sound parsing</title>
+      <para>
+        When Gnash parses a SWF-file, it creates a sound handler if possible
+       and hands over the sounds to it. Since the event-sounds are contained 
+       in one frame, the entire event-sound is retrieved at once, while a 
+       soundstream maybe not be completely retrieved before the entire 
+       SWF-file has been parsed. But since the entire soundstream doesn't need
+       to be present when playback starts, it is not necessary to wait. 
+      </para>
+    </sect3>
+
+    <sect3 id="soundplayback">
+      <title>Sound playback</title>
+      <para>
+       When a sound is about to be played Gnash calls the sound handler, which
+       then starts to play the sound and return. All the playing is done by
+       threads (in both SDL and Gstreamer), so once 
+       started the audio and graphics are not sync'ed with each other, which
+       means that we have to trust both the graphic backend and the audio
+       backend to play at correct speed. 
+      </para>
+    </sect3>
+
+    <sect3 id="sdlsound">
+      <title>The SDL sound backend</title>
+      <para>
+       The current SDL sound backend has replaced the original sound 
+       handler, based on SDL_mixer, which by design had some limitations, 
+       making it difficult to implement needed features such as support 
+       for soundstreams. 
+       The SDL sound backend supports both event-sounds and soundstreams,
+       using Gnash's internal ADPCM, and optionally MP3 support, using
+       either FFMPEG or LIBMAD.
+       When it receives sound data it is stored without being decoded, unless
+       it is ADPCM, which is decoded in the parser. When playing, backend
+       relies on a function callback for retrieving output sound, which is 
+       decoded and re-sampled if needed, and all sound output is mixed 
together.
+       The current SDL sound backend was made since Gnash needed a working
+       sound backend as soon as possible, and since the gstreamer backend at
+       the time suffered from bugs and/or lack of features in gstreamer. The
+       result was the most complete and best sound handler so far.
+       The advantages of the SDL sound handler is speed, and ease of use,
+       while its only real disadvantage is that it has to be compiled with
+       MP3 support, which some Linux distributions will probably not like...
+      </para>
+    </sect3>
+ 
+   <sect3 id="gstreamer">
+      <title>The Gstreamer backend</title>
+      <para>
+       The Gstreamer backend, though not complete, supports both soundstreams
+       and event-sounds. When receiving sound data it stores it compressed,
+       unless if it's ADPCM event-sounds, which it decodes by the parser.
+        When the playback starts, the backend sets up a
+       Gstreamer bin containing a decoder (and other things needed) and places
+       it in a Gstreamer pipeline, which plays the audio. All the sound data is
+       not passed at once, but in small chunks, and via callbacks the
+       pipeline gets fed. The advantages of the Gstreamer backend is that it
+        supports both kinds of sound, it avoids all the legal MP3-stuff, and it
+       should be relatively easy to add VORBIS support. The drawbacks are that
+       it has longer "reply delay" when starting the playback of a sound, and
+       it suffers under some bugs in Gstreamer that are yet to be fixed. 
+      </para>
+    </sect3>
+
+    <sect3 id="audio-future">
+      <title>Future audio backends</title>
+      <para>
+       It would probably be desirable to make more backends in the future,
+       either because other and better backend systems are brought to our
+       attention, or perhaps because an internal sound handling is better
+       suited for embedded platform with limited software installed. 
+      </para>
+    </sect3>
+
+    <sect3 id="gstreamer-details">
+      <title>Detailed description of the Gstreamer backend</title>
+      <para>
+       Gstreamer uses pipelines, bins and elements. Pipelines are the
+       main bin, where all other bins or elements are places. Visually the
+       audio pipeline in Gnash looks like this: 
+      </para>
+
+      <programlisting>
+        ___
+       |Bin|_
+       |___| \
+        ___   \ _____       ____________
+       |Bin|___|Adder|_____|Audio output|
+       |___|   |_____|     |____________|
+        ___   /
+       |Bin|_/
+       |___|
+
+      </programlisting>
+
+      <para>
+       There is one bin for each sound which is being played. If a sound is
+       played more the once at the same time, multiple bins will be made. The
+       bins contains: 
+      </para>
+
+      <programlisting>
+
+       
|source|---|capsfilter|---|decoder|---|aconverter|---|aresampler|---|volume|
+
+      </programlisting>
+
+      <para>
+       In the source element we place parts of the undecoded sound data, and
+       when playing the pipeline will pull the data from the element. Via
+       callbacks it is refilled if needed. In the capsfilter the data is
+       labeled with the format of the data. The decoder (surprise!) decodes
+       the data. The audioconverter converts the now raw sound data into a
+       format accepted by the adder, all input to the adder must in the same
+       format. The audio re-sampler re-samples the raw sound data into a sample
+       accepted by the adder, all input to the adder must in the same
+       sample rate. The volume element makes it possible to control the volume
+       of each sound. 
+      </para>
+
+      <para>
+       When a sound is done being played it emits a End-Of-Stream-signal
+       (EOS), which is caught by an event-handler-callback, which then makes
+       sure that the bin in question is removed from the pipeline. When a
+       sound is told by Gnash to stop playback before it has ended playback,
+       we do something (not yet finally implemented), which makes the bin emit
+       an EOS, and the event-handler-callback will remove the sound from the
+       pipeline. Unfortunately Gstreamer currently has a bug which causes the
+       entire pipeline to stop playing when unlinking an element from the
+       pipeline; so far no fix is known. 
+      </para>
+
+      <para>
+       Gstreamer also contains a bug concerning linking multiple elements to
+       the adder in rapid succession, which causes to adder to "die" and stop
+       the playback. 
+      </para>
+    </sect3>
+
+
+  </sect2>
+
+  <sect2 id="testing">
+    <title>Testing </title>
+
+     <para>
+       <link linkend="runtests">Instructions on running tests</link>
+       can be found in the section on building Gnash.
+     </para>
+
+    <sect3 id="testtools">
+      <title>Testing Tools</title>
+
+      <para>
+       Currently Gnash uses three other tools to help with
+       testing. Two of these are free compilers for the Flash
+       format. This lets us write simple test cases for Gnash to test
+       specific features, and to see how the features operate.
+      </para>
+
+      <para>
+       The primary compiler used at this time is <ulink type="http"
+       url="http://ming.sf.net";>Ming</ulink>. Since release 0.3,
+       <emphasis>Ming</emphasis> includes a command-line compiler,
+       <emphasis>makeswf</emphasis>. This allows test case development
+        to be done entirely with free tools.
+      </para>
+      
+      <para>
+        The other tools are optional.  
+       <ulink type="http"
+              url="http://www.gnu.org/software/dejagnu";>DejaGnu</ulink>
+       is used to run multiple test cases in an automated
+       manner. <emphasis>DejaGnu</emphasis> is used by many other <ulink
+       type="http" url="http://www.gnu.org";>GNU</ulink> projects like 
+       <ulink type="http" url="http://gcc.gnu.org";>GCC</ulink> and 
+       <ulink type="http" url="http://www.samba.org";>Samba</ulink>.
+      </para>
+      
+    </sect3>
+
+    <sect3 id="testcases">
+      <title>Test Cases</title>
+      
+      <para>
+       ActionScript test cases are located under testsuite/actionscript.all/;
+       these are organized in one file for the ActionScript class.
+       Other Ming-generated tests are under testsuite/ming-misc.all/;
+       these are typically used to test specific tag types.
+       Full movies are located in testsuite/movies.all/ and
+       sample movies are found in testsuite/samples/.
+       Other directories in testsuite/ are (or shall be) used for other
+       kind of tests.
+      </para>
+      
+    </sect3>
+
+    <sect3 id="writeastests">
+      <title>Writing ActionScript Tests</title>
+
+      <para>
+       Writing ActionScript tests is very simple. The
+       <emphasis>makeswf</emphasis> compiler makes use of the C preprocessor,
+       thus allowing the inclusion of definitions for macros and external 
+       files. We use these feature to provide common utilities
+       for test units.
+      </para>
+      
+      <para>
+       Each test unit sets an <emphasis>rcsid</emphasis> variable, includes the
+       <emphasis>check.as</emphasis> file and performs some checks using
+       the provided macros. Here is an example:
+       
+       <programlisting>
+
+         // This variable will be used by check.as
+         // to show testcase info as part of the test runs.
+         rcsid="Name and version of this testcase, usually the RCS id";
+         
+         #include "check.as"
+         
+         // Test object creation
+         check(new Object() instanceOf Object);
+         
+         // Test parseInt
+         check(isNaN(parseInt('none')));
+
+         // Test assignment
+         var a = 1;
+         check_equals(a, 1);
+         
+         // .. your tests here ...
+       </programlisting>
+      </para>
+      
+      <para>
+       The check(expr) macro will <emphasis>trace</emphasis> PASSED or FAILED
+       together with the expression being evaluated and the line number
+       of the check. This is the format expected by DejaGnu.
+      </para>
+
+      <para>
+       The <emphasis>check_equals(obtained, expected)</emphasis> macro uses 
equality operator
+       <emphasis>==</emphasis> to check for equality. When possible, use of the
+       <emphasis>check_equals()</emphasis> macro is preferred over 
<emphasis>check()</emphasis>
+       because it shows what the actual result was in case of a failure. 
+      </para>
+      
+      <para>
+       Additionally, the check.as file provides a transparent way to send
+       results to a TextField rather then using trace. This is very useful
+       when you use a flash player without tracing support.
+      </para>
+      
+      <para>
+       Test units are built by running <emphasis>make 
TestName-v#.swf</emphasis>.
+       This will use TestName.as as source and the value of # as target 
version.
+       Allowed target version are from 5 to 8 (inclusive).
+      </para>
+      
+      <para>
+       Note that if you get a syntax error from the compiler, the line
+       number will refer to the pre-processed file. This file is called
+       <emphasis>TestName.as.pp</emphasis> or 
<emphasis>TestName-v#.swf.frame#.pp</emphasis>
+       (depending on Ming version) and it's not thrown away by
+       <emphasis>makeswf</emphasis> to make debugging easier.
+      </para>
+
+      <para>
+       Sometimes an expression is only supported by a specific SWF
+       version, or it's evaluated differently by different SWF versions.
+       For this purpose the framework provides an OUTPUT_VERSION macro
+       that you can use to switch code based on output version. For example:
+
+       <programlisting>
+
+         #if OUTPUT_VERSION &gt;= 7
+         check(_root.getSWFVersion == OUTPUT_VERSION);
+         #endif
+         
+       </programlisting>
+      </para>
+    </sect3>
+
+    <sect3 id="writemingtests">
+      <title>Writing Ming-based self-contained SWF tests</title>
+
+      <para>
+       Ming-based test cases are located in testsuite/misc-ming.all
+       and contain a test generator and a test runner.
+       The test generator (usually a C program) is used to produce the SWF 
+        file, while the test runner (a C++ program) will run it using a 
+       MovieTester class.
+       Note that only the test generator needs Ming, not the test
+       runner, so if Ming isn't installed on the user's host,
+       the test cases can still be run as long as SWF has been distributed.
+      </para>
+      
+      <para>
+       Producing tests using Ming has the advantage that you can easily see
+       and modify the full source code for the SWF movie, and you can use
+       some <link linkend="ming_testgenerator_facilities">facilities</link>
+       provided by the Gnash testing framework to easily run tests.
+      </para>
+
+      <para>
+       For generic Ming API documentation, see <ulink type="http"
+       url="http://www.libming.org/";>http://www.libming.org</ulink>. 
+      </para>
+
+      <sect4 id="ming_testgenerator_facilities">
+      <title>Using Ming-based test generators facilities</title>
+
+      <para>
+       Ming-based test generator facilities, which might be moved into
+       a loadable SWF in the future, can be currently used by your test
+       generator by including the ming_utils.h file and calling the
+       appropriate functions.
+      </para>
+
+      <para>
+       The most useful facility provided for Ming-based SWF test generators
+       is a Dejagnu-like TestState ActionScript class.
+       In order to use this facility you must call 'add_dejagnu_functions()'
+       right after Movie creation.
+       The function takes an SWFMovie object and some parameters specifying
+       depth and location of the "visual" trace textfield; it instantiates
+       a global 'TestState' ActionScript object to keep track of test's state.
+      </para>
+
+      <para>
+        You will <emphasis>not</emphasis> need to directly invoke the
+       TestState object created by the 'add_dejagnu_functions()' routine,
+       rather you will be using C macros hiding its complexity:
+       
+       <programlisting>
+
+       check(SWFMovie mo, const char* expr)
+
+               Evaluate an ActionScript expression.
+
+       xcheck(SWFMovie mo, const char* expr)
+
+               Evaluate an ActionScript expression.
+               A failure is expected
+               (for cases where the call exposes a known bug).
+
+       check_equals(SWFMovie mo, const char* obtained, const char* expected)
+
+               Evaluate an ActionScript expression against an expected output.
+
+       xcheck_equals(SWFMovie mo, const char* obtained, const char* expected)
+
+               Evaluate an ActionScript expression against an expected output.
+               A failure is expected (for cases where the call exposes a known 
bug).
+
+       print_tests_summary(SWFMovie mo)
+
+                This will print a summary of tests run, and should be
+               called as the last step in your SWF generator.
+
+       </programlisting>
+       
+      </para>
+      
+       <para>
+       Test cases generated using Ming and the provided
+       <link linkend="ming_testgenerator_facilities">facilities</link>
+       will be self-contained, which means they can be used as tests
+       by simply running them with whatever Player you might have.
+       Any 'check' or 'check_equals' result will be both traced and
+       printed in a textfield. You can use 'gprocessor -v' to have
+       Gnash use them as tests.
+       </para>
+
+       <para>
+       See section <link linkend="writing_test_runners">Writing Test 
Runners</link>
+       for information about writing SWF test runners.
+       </para>
+
+
+    </sect4>
+
+    </sect3>
+
+    <sect3 id="writing_dejagnu_so_tests">
+      <title>Writing self-contained SWF tests with other compilers</title>
+
+       <para>
+       If you want/need to use a different compiler for your test cases 
(there's
+       plenty of open source tools for generating SWF out there), you can still
+       make use of a loadable SWF utility provided as part of the Gnash 
testsuite
+       to let your test consistent with the rest of the suite.
+       </para>
+
+       <para>
+       The loadable module is called <code>Dejagnu.swf</code> and is built 
during
+       <code>make check</code> under testsuite/misc-ming.all. In order to use 
it
+       you will need to load it into your SWF. We currently load it with an 
IMPORT
+       tag for our ActionScript based test cases, but you can probably also use
+       loadMovie or whatever works in the target SWF you're generating. Just 
make
+       sure that the module is initialized before using it. You can check this 
by
+       inspecting the <code>dejagnu_module_initialized</code> variable, which 
will
+       be set to 'true' when all initialization actions contained in the
+       <code>Dejagnu.swf</code> file are executed. 
+       </para>
+
+       <para>
+       Once the module is loaded you will be able to invoke the following 
functions,
+       all registered against the <code>_root</code> sprite (effects of 
<code>_lockroot</code>
+       untested):
+       <programlisting>
+
+       check(expression, [message]);
+
+               Evaluate the expression.
+               Trace result (PASSED: expression / FAILED: expression).
+               If fails, *visually* trace the failure.
+               If second argument is given, it will be used instead of
+               'expression' for printing results.
+
+       check_equals(obtained, expected)
+
+               Evaluate an expression against an expected output.
+               Trace result (PASSED: obtained == expected / FAILED: expected 
X, obtained Y)
+               If fails, *visually* trace the failure.
+
+       xcheck(expression, [message]);
+
+               Evaluate the expression.
+               Trace result (XPASSED: expression / XFAILED: expression).
+               If fails, *visually* trace the failure.
+               If second argument is given, it will be used instead of
+               'expression' for printing results.
+
+       xcheck_equals(obtained, expected)
+
+               Evaluate an expression against an expected output.
+               Trace result (XPASSED: obtained == expected / XFAILED: expected 
X, obtained Y)
+               If fails, *visually* trace the failure.
+
+       note(string)
+
+               Print string, both as debugging and *visual* trace.
+
+       totals()
+
+                Print a summary of tests run, both as debugging and *visual* 
traces.
+
+       </programlisting>
+       </para>
+
+       <para>
+       Visual traces are lines of text pushed to a textarea defined by the 
<code>Dejagnu.swf</code> module.
+       The textarea is initially placed at <code>0, 50</code> and is 
<code>600x800</code> in size.
+       You can resize/move the clip after loading it.
+       Also, you can completely make the clip invisible if that bothers you. 
The important thing is the
+       *debuggin* trace (call to the trace function). The latter will be used 
by the testing framework.
+       </para>
+
+       <para>
+       See section <link linkend="writing_test_runners">Writing Test 
Runners</link>
+       for information about writing a test runners for your self-contained 
tests.
+       </para>
+
+    </sect3>
+
+    <sect3 id="writing_test_runners">
+    <title>Writing Test Runners</title>
+
+       <para>
+       Test runners are executables that run one or more tests,
+       writing results in Dejagnu form to standard output.
+       </para>
+
+       <para>
+        The Dejagnu form uses a standard set of labels when printing test 
+        results.  These are:
+        <informaltable frame="all">
+        <?dbhtml table-width="75%" ?>
+        <tgroup cols="2">
+          <thead>
+            <row>
+              <entry valign="top">
+                <para>Label</para>
+              </entry>
+              <entry valign="top">
+                <para>Meaning</para>
+              </entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry valign="top" align="left">
+                <para>PASSED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>The test succeeded.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>FAILED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>The test failed.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>XPASSED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>The test succeeded, but was expected to fail.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>XFAILED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>The test failed, and was expected to fail.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>UNRESOLVED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>The results of the test could not be automatically 
+                      parsed.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>UNTESTED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>This test case is not complete.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>UNSUPPORTED</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>The test case relies on a conditional feature which 
+                      is not present in your environment.</para>
+              </entry>
+            </row>
+           </tbody>
+          </tgroup>
+         </informaltable>
+       </para>
+
+        <para>
+        The following labels may also appear:
+        <informaltable frame="all">
+        <?dbhtml table-width="75%" ?>
+        <tgroup cols="2">
+          <thead>
+            <row>
+              <entry valign="top">
+                <para>Label</para>
+              </entry>
+              <entry valign="top">
+                <para>Meaning</para>
+              </entry>
+            </row>
+          </thead>
+          <tbody>
+            <row>
+              <entry valign="top" align="left">
+                <para>ERROR</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>There was a serious error in running the test. </para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>WARNING</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>There may have been a problem with running the
+                      test.</para>
+              </entry>
+            </row>
+            <row>
+              <entry valign="top" align="left">
+                <para>NOTE</para>
+              </entry>
+              <entry valign="top" align="left">
+                <para>There was some additional information given about
+                      the test.</para>
+              </entry>
+            </row>
+           </tbody>
+          </tgroup>
+         </informaltable>
+       </para>
+
+        <sect4 id="generic_test_runner">
+        <title>Using the generic test runner for self-contained SWF 
tests</title>
+
+       <para>
+       The simplest test runner is one that simply invokes Gnash
+       in verbose mode against a self-contained SWF test movie.
+       Self-contained SWF test movies are the ones that print
+       the PASSED/FAILED etc. lines using ActionScript (traces).
+       By invoking Gnash in verbose mode this movie will behave
+       as a compliant "Test Runner".
+       </para>
+
+       <para>
+       A generator for simple test runners can be found in
+       <code>testsuite/generic-testrunner.sh</code>.
+       The script can be invoked by passing it <code>$(top_builddir)</code>
+       as the first argument and the name of the SWF file (without the path)
+       as the second argument. This will create a specific runner for your
+       test in the current build directory.
+       A simple Makefile.am rule for doing this follows:
+       <programlisting>
+MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
+        sh $(srcdir)/../generic-testrunner.sh $(top_builddir) MyTest.swf > $@
+        chmod +x $@
+       </programlisting>
+       </para>
+
+       <para>
+       By default, the generated test runner will play the movie up to the
+       last frame. If you want the movie to be played more then once (maybe
+       because you're exactly testing loop features) you can use the -r switch
+       to the generic-testrunner.sh call. The following will create a runner
+       playing the movie twice:
+       <programlisting>
+MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
+        sh $(srcdir)/../generic-testrunner.sh -r2 $(top_builddir) MyTest.swf > 
$@
+        chmod +x $@
+       </programlisting>
+       </para>
+
+       <para>
+       In case your test movie stops before the last frame, or you want to 
control the
+       exact number of times to call the frame advancement routine, you can 
use the 
+       -f switch to control that.
+       <programlisting>
+MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
+        sh $(srcdir)/../generic-testrunner.sh -f10 $(top_builddir) MyTest.swf 
> $@
+        chmod +x $@
+       </programlisting>
+       When both -f and -r are given, the first exit condition reached will 
take effect.
+       </para>
+
+       </sect4>
+       
+       <sect4 id="writing_movie_testers">
+         <title>Writing Movie testers</title>
+         
+         <para>
+           There are some parts of Gnash that can NOT be tested
+           by only using ActionScript tests. Examples include: frame
+           advancements, actual actions execution, gui events and so on.
+         </para>
+         
+         <para>
+           In this case you might want to use the MovieTester class to
+           implement a C++ test runner. Be aware that you can *mix* tests in
+           the MovieTester-based class with *self-contained*
+           tests in the SWF file as long as you activate verbosity for
+           the debug logfile. This is done, for example, for the
+           DefineEditTextVariableNameTest.swf file. The corresponding
+           test runner (DefineEditTextVariableNameTest-Runner) is a C++
+           runner based on MovieTester class. If you run the runner you
+           see two kinds of test results: the ones coming from the ActionScript
+           engine, and the ones coming from the test runner. You can
+           distinguish between the two because the former contains an 
additional
+           timestamp and the latter does not. Also, you'll see two final
+           summaries for the two test sets. The 'make check' rule, which uses
+           the testsuite/simple.exp output parser as its work-horse, will
+           count test results from both test sets.
+         </para>
+         
+         
+         <para>
+           Movie testers are executables which load an SWF, generate events
+           (both user or system) on it, and check its state using
+           a standard interface.
+         </para>
+         
+         <para>
+           To help this process a MovieTester class is defined in the
+           testsuite/MovieTester.{h,cpp} files; see Doxygen documentation
+           for more information.
+         </para>
+         
+         <para>
+           Note that you do NOT need access to the SWF source code in order
+           to implement a Movie tester for it.  Some knowledge about the 
+           expected behavior suffices.
+         </para>
+       </sect4>
+    </sect3>
+  </sect2>
+</sect1>
+

Index: logging.xml
===================================================================
RCS file: logging.xml
diff -N logging.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ logging.xml 1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,207 @@
+<sect2 id="logging">
+  <title>The Debug Logging System</title>
+
+  <para>
+    Gnash supports a debug logging system which supports both C and C++
+    natively. This means you can use both <emphasis>printf()</emphasis> style
+    debug messages and C++ <emphasis>iostreams</emphasis> style, where you can
+    print C++ objects directly as you would when using
+    <emphasis>cout</emphasis>.
+  </para>
+  
+  <para>
+    In the beginning, Gnash only supported the C API for debug
+    logging, so it is the most heavily used in Gnash. This API was used in
+    the <emphasis>log_msg()</emphasis> and <emphasis>log_error()</emphasis> 
functions,
+    and used a callback to set them up.
+  </para>
+  
+  <para>
+    It became apparent one day the callback was never needed, and I
+    got tired of having to use <emphasis>c_str()</emphasis> on string data
+    just to print them out.
+  </para>
+  
+  <para>
+    If a filename is not specified at object construction time, a
+    default name of <emphasis>gnash-dbg.log</emphasis> is used. If Gnash is
+    started from the command line, the debug log will be created in
+    the current directory. When executing Gnash from a launcher under
+    <emphasis>GNOME</emphasis> or <emphasis>KDE</emphasis> the debug file goes 
in your
+    home directory, since that's considered the current directory.
+  </para>
+
+  <para>
+    There is common functionality between using the C or C++
+    API. Optional output is based on flags that can be set or
+    unset. Multiple levels of verbosity are supported, so you can get
+    more output by supplying multiple <emphasis>-v</emphasis> options on the
+    command line. You can also disable the creation of the debug log.
+  </para>
+
+  <sect3 id="capi">
+    <title>Logging System C API</title>
+
+    <para>
+      These functions are clones of the originals as they were used
+      for Gnash. These function the same as always except output can
+      be logged to disk now as well. These currently print no
+      timestamp with the output, which is the older functionality. As
+      these functions are implemented on top of the C++ API now, they
+      can be used without corrupting the output buffers.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+       <term>void log_msg(const char* fmt, ...)</term>
+       <listitem>
+         <para>
+           Display a message if verbose output is enabled. By default
+           the messages are always written to the disk file, but
+           optionally displayed in the terminal.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>log_error(const char* fmt, ...)</term>
+       <listitem>
+         <para>
+           Display an error message if verbose output is enabled. By
+           default the error messages are always written to the disk
+           file, but optionally displayed in the terminal.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>log_warning(const char* fmt, ...)</term>
+       <listitem>
+         <para>
+           Display a warning message if verbose output is enabled. By
+           default the error messages are always written to the disk
+           file, but optionally displayed in the terminal.
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+      
+  </sect3>
+
+  <sect3 id="cppapi">
+    <title>Logging System C++ API</title>
+
+    <para>
+      This is the new C++ streams based API that can be used to print
+      C++ objects natively. All output lines are timestamped.       
+    </para>
+
+    <para>
+      There are two macros used for program tracing. these can be used
+      in both C or C++ code with one little difference. Since C
+      doesn't have destructors, you must call
+      <emphasis>GNASH_REPORT_RETURN</emphasis> at the end of a function to
+      display the function returning message.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+       <term>GNASH_REPORT_FUNCTION;</term>
+       <listitem>
+         <para>
+           When this is included in a C++ method, a message is
+           printed when entering and exiting this method by hooking
+           into the constructor and destructor. These are always
+           written to the disk file, but optionally written to the
+           screen only at the highest levels of verbosity.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>GNASH_REPORT_RETURN;</term>
+       <listitem>
+         <para>
+           This is used by C functions to print the returning from
+           function debug message. For C++, this macro is executed
+           automatically by the destructor.
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>
+      This is the main API for the logging system. By default
+      everything is setup to write to the default
+      <emphasis>gnash-dbg.log</emphasis> file whenever a verbose option is
+      supplied. Optionally it is possible to open a log file with a
+      specified name, allowing multiple output files.
+    </para>
+    
+    <variablelist>
+      <varlistentry>
+       <term>openLog(const char *filespec)</term>
+       <listitem>
+         <para>
+           Open the debug file with the name specified by
+           <emphasis>filespec</emphasis>. This file goes in the current
+           directory, or your home directory if using a menu based
+           launcher.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>closeLog(void)</term>
+       <listitem>
+         <para>
+           Close a debug log. The disk file remains.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>removeLog(void)</term>
+       <listitem>
+         <para>
+           Delete the debug log file from disk.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>setVerbosity(void)</term>
+       <listitem>
+         <para>
+           Increment the verbosity level.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>setVerbosity(int)</term>
+       <listitem>
+         <para>
+           Set the verbosity level.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>setStamp(bool flag)</term>
+       <listitem>
+         <para>
+           If <emphasis>flag</emphasis> is <emphasis>true</emphasis>, then 
print a
+           timestamp prefixed to every output line. If
+           <emphasis>flag</emphasis> is <emphasis>false</emphasis>, then don't 
print
+           a timestamp.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>setWriteDisk(bool flag)</term>
+       <listitem>
+         <para>
+           If <emphasis>flag</emphasis> is <emphasis>true</emphasis>, then 
create the
+           disk file. If <emphasis>flag</emphasis> is 
<emphasis>false</emphasis>,
+           then don't create the disk file.
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+
+  </sect3>
+
+</sect2>

Index: main.xml
===================================================================
RCS file: main.xml
diff -N main.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ main.xml    1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,29 @@
+    <sect1 id="introduction">
+      <title>Introduction</title>
+
+      <para>
+        In this document, the term 'ActionScript class' refers to the
+        C++ class which is instantiated by Gnash when some ActionScript
+        code instantiates a corresponding class.  The C++ class
+        stores instance data and implements the methods which are 
+        called on the object in the ActionScript code.
+      </para>
+
+      <sect2 id="overview">
+        <title>Object Creation Overview</title>
+          <para>
+            When Gnash starts, the <emphasis>class_init()</emphasis> method 
+            for each ActionScript class (listed in Global.cpp) is called.
+            This method constructs a prototype, which is implemented as an
+            <emphasis>as_object</emphasis>.  In addition, the method
+            registers the constructor to be used for future object creation,
+            and attaches methods and properties to the prototype.
+          </para>
+
+          <para>
+            When a new object is needed, instance data is added to
+            the methods and properties inherited from the prototype.
+          </para>
+      </sect2>
+    </sect1>
+

Index: memory.xml
===================================================================
RCS file: memory.xml
diff -N memory.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ memory.xml  1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,51 @@
+  <sect1 id="spec-memory">
+    <title>Memory Management</title>
+    
+    <para>
+      One of the new features of &app; &appversion; is the garbage
+      collector.  The garbage collector manages complex &AS; variables,
+      which are the only ones that are shared by references.  In &app;,
+      these are <command>as_object</command> class instances created by &AS;
+      (i.e. not those created by playhead control:
+      <command>placeobject</command>/<command>removeobject</command>). 
+    </para>
+    
+    <para>
+      Collected objects are those allocated due to &AS; explicit or implicit
+      calls.  Explicit all are any user-defined statements that allocate new
+      objects, such as arrays, Objects, or script-created movieclips.
+      Implicit calls are the built-in functions that can be deleted by
+      arbitrary user calls. 
+    </para>
+    
+    <para>
+      Any object that is a candidate for garbage collecting is stored in a
+      list owned by the collector.  This list is filled by an executing
+      action context whenever a collectible object is allocated on the
+      heap. 
+    </para>
+    
+    <para>
+      The garbage collector starts at the very end of an execution context,
+      rather than using a threshold to trigger it.  At this point, the
+      virtual machine is in a "stable" state; any still-reachable object has
+      its roots in one of the currently live character instances (stage
+      characters). 
+    </para>
+    
+    <para>
+      The collector is a conservative collector.  Any object on the
+      collectibles list is marked as <guilabel>UNREACHABLE</guilabel>, an
+      iterative scan starting from the roots marks any still-reachable
+      object, and a final purge releases all
+      still-<guilabel>UNREACHABLE</guilabel> resources. 
+    </para>
+    
+    <para>
+      This garbage collector has reduced the memory footprint of &app;.
+      However, the most current, available test data indicated the following
+      runtime memory footprint: 
+    </para>
+    
+  </sect1>
+  

Index: new_as_class.xml
===================================================================
RCS file: new_as_class.xml
diff -N new_as_class.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ new_as_class.xml    1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,204 @@
+    <sect1 id="newclass">
+      <title>Adding New ActionScript Class</title>
+
+      <para>
+        Adding a new ActionScript class is relatively simple, but the
+        process is complicated by the fact that the interface has evolved
+        over time and the current code base represents several different
+        formats.  This document describes the current interface.  The
+        Boolean class should be considered the authoritative example of
+        a modern ActionScript class.
+      </para>
+
+      <para>
+        ActionScript classes contain a header file and a C++
+        implementation.  The name is usually the name of the
+        class as it is called in the ActionScript specifications;
+        for instance <emphasis>Boolean.cpp</emphasis> for the Boolean class.
+      </para>
+
+      <sect2 id="prototype">
+        <title>Prototype</title>
+
+       <para>
+          In ActionScript, a prototype is a base object which contains
+          all the methods that an instantiated object will contain.
+          In short, it contains every part of the class except for
+          the portions dealing with the storage of instance data.
+       </para>
+       <para>
+          In Gnash, the prototype of an ActionScript object is 
+          implemented as an <emphasis>as_object</emphasis>.
+          At startup, the methods and properties of the ActionScript class
+          are attached to the <emphasis>as_object</emphasis>.  The
+          following example demonstrates how methods can be attached:
+         <programlisting>
+            static void
+            attachBooleanInterface(as_object&amp; o) 
+            {
+                o.init_member("toString", new 
builtin_function(boolean_tostring));
+                o.init_member("valueOf", new 
builtin_function(boolean_valueof));
+            }
+         </programlisting>
+       </para>
+       <para>
+          Static properties can also be added to the ActionScript prototype
+          (<link linkend="properties">dynamic properties</link> 
+          are addressed later).  They are attached in a similar way:
+          <programlisting>
+           o.init_member("myProperty", as_value("HelloWorld"));
+         </programlisting>
+       </para>
+       <para>
+          Properties which have been added in this manner can be
+          directly accessed in ActionScript code without a function
+          call, as this piece of ActionScript code compiled by Ming's
+          <emphasis>makeswf</emphasis> compiler demonstrates:
+           <programlisting>
+             // Get the value of the myProperty property
+             if (node.myProperty == "HelloWorld") {
+                 trace("MATCHED");
+             }
+           </programlisting>
+       </para>
+      </sect2>
+
+      <sect2 id="declaration">
+       <title>Declaration</title>
+
+       <para>
+          A new class should derive from <emphasis>as_object</emphasis>,
+          which is the base class of every ActionScript object in Gnash.
+       </para>
+      </sect2>
+      
+      <sect2 id="instantiation">
+       <title>Instantiation</title>
+
+       <para>
+          The class should contain an init method.
+       </para>
+       <para>
+          The init method should be called in the constructor in
+          <emphasis>Global.cpp</emphasis>, where all other ActionScript
+          classes are similarly referenced.
+       </para>
+      </sect2>
+
+      <sect2 id="methods">
+       <title>Methods</title>
+
+        <para>
+          Every method you implement and 
+          <link linkend="prototype">attach</link> will receive an
+          &fn_call; data structure as an argument when it is called.
+        </para>
+
+        <sect3 id="arguments">
+          <title>Accessing Arguments</title>
+          <para>
+            The arguments stored in &fn_call;
+            should be accessed using <emphasis>arg()</emphasis>.  For
+            instance, the first element can be popped with
+            <emphasis>fn.arg(0)</emphasis>.
+         </para>
+          <para>
+            The element popped off the stack is an 
+            <link linkend="as_value"><emphasis>as_value</emphasis>
+            object</link>.
+          </para>
+        </sect3>
+
+        <sect3 id="return">
+          <title>Returning a Value to ActionScript</title>
+          <para>
+            The return value should be an
+            <link linkend="as_value"><emphasis>as_value</emphasis> 
+            object</link>.  For example:
+            <programlisting>
+              return as_value('Goodbye, cruel world.');
+            </programlisting>
+          </para>
+        </sect3>
+
+        <sect3 id="additional_fn_call">
+          <title>Additional &fn_call; Members</title>
+          <para>
+            There are two other useful members of the &fn_call;
+            structure, namely <emphasis>this_ptr</emphasis> and
+            <emphasis>nargs</emphasis>.  The former points to the
+            class which is invoking this method, while the latter
+            is a count of the number of 
+            <link linkend="arguments">arguments in the stack</link>.
+         </para>
+         <para>
+            You may also see instances of the <emphasis>env</emphasis>
+            pointer being used.   This is being deprecated.  Instances
+            which could be replaced with
+            <link linkend="arguments"><emphasis>arg()</emphasis></link>
+            are already deprecated; other uses will be deprecated
+            in the near future.
+         </para>
+          <para>
+            Beyond the <emphasis><link 
+            linkend="arguments">arg()</link></emphasis> method, there
+            is one method of note.  <emphasis>dump_args()</emphasis>
+            can be used in debugging to output the entire argument
+            stack.
+         </para>
+        </sect3>
+      </sect2>
+
+      <sect2 id="properties">
+       <title>Dynamic Properties</title>
+        <para>
+          This section describes accessors to dynamic properties.
+          Read-only properties are described
+          in the <link linkend="prototype">prototype</link> section.
+        </para>
+        <para>
+          Accessors should be written as a single get/set method.
+         Previously this was done by overriding
+         <emphasis>get_member()</emphasis> and 
+          <emphasis>set_member()</emphasis>, but this practice
+          is deprecated.  
+        </para>
+        <para> 
+          The accessor is written so that it sets the property
+          if it is called with an argument, and puts the property in
+          the <link linkend="methods">&fn_call;</link>
+          <link linkend="return">result pointer</link>.  For instance:
+          <programlisting>
+            void
+            MyClass::myProperty_getset(const fn_call&amp; fn)
+            {
+
+                boost::intrusive_ptr&lt;MyClass&gt; ptr = 
ensureType&lt;MyClass&gt;(fn.this_ptr);
+
+                // setter
+                if ( fn.nargs > 0 )
+                {
+                    bool h = fn.arg(0).to_bool();
+                    ptr->MyMethod(h);
+                    return;
+                }
+
+                // getter
+                bool h = ptr->MyMethod();
+                fn.result->set_bool(h);
+            }
+          </programlisting>
+        </para>
+        <para> 
+          It has not yet been decided whether properties should be set
+          in the <link linkend="prototype">exported interface</link> 
+          or attached to instances of the class.  A property is attached
+          in the following manner:
+          <programlisting>
+            boost::intrusive_ptr&lt;builtin_function&gt; gettersetter;
+            gettersetter = new 
builtin_function(&amp;MyClass::myProperty_getset, NULL);
+            o.init_property("myProperty", *gettersetter, *gettersetter);
+          </programlisting>
+        </para>
+      </sect2>
+    </sect1>

Index: object.xml
===================================================================
RCS file: object.xml
diff -N object.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ object.xml  1 Mar 2008 15:04:42 -0000       1.1
@@ -0,0 +1,318 @@
+<sect4 id="asobject">
+  <title>Object ActionScript Class</title>
+
+  <para>
+    This class implements an Object object.
+  </para>
+
+  <sect5 id="objectmethods">
+    <title>The Methods of the  Class</title>
+    <para>
+      <variablelist>
+
+       <varlistentry>
+         <term>addProperty()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>registerClass()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>toString()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>unwatch()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>valueOf()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>watch()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>Sharedclear()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>Sharedflush()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>SharedgetLocal()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>SharedgetSize()</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+    </para>
+  </sect5>
+  <sect5 id="objectprops">
+    <title>The Properties of the Object Class</title>
+    
+    <para>
+      <variablelist>
+
+       <varlistentry>
+         <term>constructor</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>__proto__</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>__resolve</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>Shareddata</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+       <varlistentry>
+         <term>SharedonStatus</term>
+         <listitem>
+           <para>
+           </para>
+         </listitem>
+       </varlistentry>
+
+      </variablelist>
+    </para>
+  </sect5>
+
+  <sect5 id="objectconf">
+    <title>Object Class Conformance</title>
+    
+    <para>
+      <informaltable frame="all">
+       <?dbhtml table-width="75%" ?>
+       <tgroup cols="2">
+         <thead>
+           <row>
+             <entry valign="top">
+               <para>Class Name</para>
+             </entry>
+             <entry valign="top">
+               <para>Conformance</para>
+             </entry>
+           </row>
+         </thead>
+         <tbody>
+           <row>
+             <entry valign="top" align="left">
+               <para>addProperty()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>registerClass()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>toString()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>unwatch()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>valueOf()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>watch()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>Sharedclear()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>Sharedflush()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>SharedgetLocal()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>SharedgetSize()</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This method has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>constructor</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This property has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>__proto__</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This property has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>__resolve</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This property has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>Shareddata</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This property has an unknown status.
+               </para>
+             </entry>
+           </row>
+           <row>
+             <entry valign="top" align="left">
+               <para>SharedonStatus</para>
+             </entry>
+             <entry valign="top" align="center">
+               <para>
+                 This property has an unknown status.
+               </para>
+             </entry>
+           </row>
+         </tbody>
+       </tgroup>
+      </informaltable>
+    </para>
+  </sect5>  
+</sect4>

Index: plugin.xml
===================================================================
RCS file: plugin.xml
diff -N plugin.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ plugin.xml  1 Mar 2008 15:04:43 -0000       1.1
@@ -0,0 +1,353 @@
+<sect4 id="mozplugin">
+  <title>Mozilla/Firefox Plugin</title>
+
+  <para>
+    The Mozilla SDK has two API layers for plugins. The older layer is
+    documented in the <ulink type="http"
+    url="http://www.gnu.org/software/gnash/manual/plugin.pdf";>
+    Geeko Plugin API Reference</ulink>, and the newer layer doesn't
+    appear to be documented. The new API is simpler, and is portable
+    across multiple versions of Mozilla or Firefox. The new API is
+    just a layer on top of the older one, so this manual still
+    applies.
+  </para>
+
+  <para>
+    Most of the programming of a plugin is filling in real emphasis for
+    the standard API functions and methods. Firefox uses these to
+    create the plugin, and to send it data.
+  </para>
+
+  <para>
+    When initializing or destroying a plugin, no matter how many
+    instances are being used, the C API is used. These functions are
+    typically called once for each plugin that is loaded.
+  </para>
+    
+  <sect5 id="plugincapi">
+    <title>Plugin C API</title>
+
+    <para>
+      The lower layer is a C based API which is used by Firefox to
+      initialize and destroy a plugin. This is so a plugin can be
+      portable across multiple systems, since C++ emphasis is not portable
+      between most C++ compilers. This is where most of the behind the
+      scenes work is done in a plugin. For Gnash, the sources this
+      lower layer are in <emphasis>plugin/mozilla-sdk</emphasis>. They were
+      added to the Gnash source tree so it wouldn't be necessary to
+      have the Mozilla development packages installed to compile the
+      Gnash plugin.
+    </para>
+
+    <para>
+      This is also the older API used for plugins, so is usually the
+      one used if you dig around for plugin examples on the web. These
+      are the main functions which have to be implemented in a plugin
+      for it to be recognized by the browser, and to be initialized
+      and destroyed.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+       <term>NS_PluginInitialize</term>
+       <listitem>
+         <para>
+           This C function gets called once when the plugin is
+           loaded, regardless of how many instantiations there are
+           actually playing movies. So this is where all the one
+           time only initialization stuff goes that is shared by all
+           the threads.
+         </para>
+         
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>NS_NewPluginInstance</term>
+       <listitem>
+         <para>
+           This instantiates a new object for the browser. Returning
+           a pointer to the C++ plugin object is what ties the C++
+           and C emphasis parts of the API together.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>NS_DestroyPluginInstance</term>
+       <listitem>
+         <para>
+           This destroys our instantiated object when the browser is
+           done.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>NS_PluginShutdown</term>
+       <listitem>
+         <para>
+           This is called when a plugin is shut down, so this is
+           where all the one time only shutdown stuff goes.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>NPP_GetMIMEDescription</term>
+       <listitem>
+         <para>
+           This is called to get the MIME types the plugin supports.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>NS_PluginGetValue</term>
+       <listitem>
+         <para>
+           This is used by Firefox to query information from the
+           plugin, like the supported MIME type, the version number,
+           and a description.
+         </para>
+       </listitem>
+      </varlistentry>      
+    </variablelist>
+  </sect5>
+
+  <sect5 id="plugincppapi">
+    <title>Plugin C++ API</title>
+
+    <para>
+      The higher level layer is the one we are most concerned
+      with. This is an instantiation of the
+      <emphasis>nsPluginInstanceBase</emphasis> class, as defined by the
+      Mozilla SDK, for our plugin. With this API, a plugin is mostly
+      defining the standard entry points for Firefox, and the emphasis
+      that implements the glue between the Firefox and our plugin.
+    </para>
+
+    <para>
+      These are called for each instantiation of plugin. If there are
+      three Flash movies on a web page, then three instances are
+      created. Unfortunately for plugin programmers, these functions
+      may randomly be called more than once, so it's good to use
+      initialization flags for things that should only be done one per
+      thread. For instance, <emphasis>nsPluginInstance::init()</emphasis> and
+      <emphasis>nsPluginInstance::SetWindow()</emphasis> are called more than
+      once, so the plugin must protect against actions that could be
+      destructive.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+       <term>nsPluginInstance::nsPluginInstance</term>
+       <listitem>
+         <para>
+           Create a new plugin object.
+         </para>
+       </listitem>
+      </varlistentry>
+    
+      <varlistentry>
+       <term>nsPluginInstance::init</term>
+       <listitem>
+         <para>
+           This methods initializes the plugin object, and is
+           called for every movie which gets played. This is where
+           the thread-specific information goes.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::SetWindow</term>
+       <listitem>
+         <para>
+           This sets up the window the plugin is supposed to render
+           into. This calls passes in various information used by
+           the plugin to setup the window. This may get called
+           multiple times by each instantiated object, so it can't
+           do much but window specific setup here. This is where the
+           main emphasis is that sets up the window for the plugin.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::NewStream</term>
+       <listitem>
+         <para>
+           Opens a new incoming data stream, which is the flash
+           movie we want to play. A URL can be pretty ugly, like in
+           this example:
+           
http://www.sickwave.com/swf/navbar/navbar_sw.swf?atfilms=http%3a//www.atm.com/af/home/&amp;shickwave=http%3a//www.sickwave.com&amp;gblst=http%3a//gbst.sickwave.com/gb/gbHome.jsp&amp;known=0
 
../flash/gui.swf?ip_addr=foobar.com&amp;ip_port=3660&amp;show_cursor=true&amp;path_prefix=../flash/&amp;trapallkeys=true"
+           So this is where we parse the URL to get all the options
+           passed in when invoking the plugin.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::Write</term>
+       <listitem>
+         <para>
+           Read the data stream from Mozilla/Firefox.  For now we
+           read the bytes and write them to a disk file.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::WriteReady</term>
+       <listitem>
+         <para>
+           Return how many bytes we can read into the buffer.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::DestroyStream</term>
+       <listitem>
+         <para>
+           Destroy the data stream we've been reading. For Gnash,
+           when the stream is destroyed means we've grabbed the
+           entire movie. So we signal the thread to start reading and
+           playing the movie.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::shut</term>
+       <listitem>
+         <para>
+           This is where the movie playing specific shutdown emphasis goes.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::~nsPluginInstance</term>
+       <listitem>
+         <para>
+           This destroys our plugin object.
+         </para>
+       </listitem>
+      </varlistentry>
+    
+      <varlistentry>
+       <term>NS_PluginInitialize::initGL</term>
+       <listitem>
+         <para>
+           This is a Gnash internal function that sets up OpenGL.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>NS_PluginInitialize::destroyContext</term>
+       <listitem>
+         <para>
+           This is a Gnash internal function that destroys a GLX
+           context. 
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>nsPluginInstance::getVersion</term>
+       <listitem>
+         <para>
+           This returns the version of Mozilla this plugin supports.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::GetValue</term>
+       <listitem>
+         <para>
+           This returns information to the browser about the plugin's
+           name and description.
+         </para>
+       </listitem>
+      </varlistentry>
+      
+      <varlistentry>
+       <term>nsPluginInstance::URLNotify</term>
+       <listitem>
+         <para>
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist> 
+  </sect5>
+
+  <sect5 id="glthread">
+    <title>OpenGL and Threads</title>
+    <para>
+      Neither OpenGL nor X11 has any built-in support for threads. Most
+      actions aren't even atomic, so care has to be made to not corrupt
+      any internal data. While it is difficult to render OpenGL from
+      multiple threads, it can be done with the proper locking. The
+      downside is the locking adds a performance hit, since all the
+      threads will have to have the access synchronized by using
+      mutexes.
+    </para>
+    
+    <para>
+      The X11 context is maintained one per instantiation of the
+      plugin. It is necessary to lock access to the X11 context when
+      using threads by using <emphasis>XLockDisplay()</emphasis> and
+      <emphasis>XUnlockDisplay()</emphasis>. A connection to the X11
+      server is opened for every instantiation of the plugin using
+      <emphasis>XOpenDisplay()</emphasis>.
+    </para>
+    
+    <para>
+      The <emphasis>GLX Context</emphasis> is maintained one per
+      instantiation of the plugin for a web page. If there are more
+      than one Flash movie, there is more than one GLX Context. A GLX
+      context can be created by using <emphasis>glXCreateContext()</emphasis>,
+      and then later destroyed by using 
<emphasis>glXDestroyContext()</emphasis>.
+      When swapping threads, the context is changed using
+      <emphasis>glXMakeCurrent()</emphasis>.
+    </para>
+    
+    <para>
+      All the emphasis that directly accesses a GLX context or the X11
+      display must be wrapped with a mutex.
+    </para>
+    
+  </sect5>
+  
+  <sect5 id="eventhandle">
+    <title>Plugin Event Handling</title>
+    <para>
+      Firefox on most UNIX systems is a GTK+ application, so it is
+      possible to have the plugin hook into the X11 event handling via
+      GLX or GTK. Since Firefox uses GTK, so does Gnash. This also
+      allows the addition of a right-click mouse menu for controlling
+      the player. The GTK build of Gnash offers the best browsing
+      experience as it's more functional than the SDL version.
+    </para>
+
+    <para>
+      It is also possible to disable the <emphasis>GTK</emphasis> support so
+      only the older <emphasis>SDL</emphasis> support is used. In this case 
+      Gnash can't support event handling within the browser. This
+      means that when using the SDL of the plugin, mouse clicks and
+      keys pressed get ignored. Windows also can't be resized, and
+      sometimes they overrun their boundaries as well. To disable the
+      GTK support and force SDL to be used anyway, configure with
+      <emphasis>--disable-glext</emphasis>
+    </para>
+
+    <para>
+      
+    </para>
+
+  </sect5>  
+</sect4>

Index: revisions.xml
===================================================================
RCS file: revisions.xml
diff -N revisions.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ revisions.xml       1 Mar 2008 15:04:43 -0000       1.1
@@ -0,0 +1,19 @@
+<revhistory>
+  
+  <revision> 
+    <revnumber>Gnash User Manual version 0.4</revnumber> 
+    <date>Feb 2008</date>
+    <revdescription> 
+      <para role="author">Rob Savoye
+      <email>address@hidden</email>
+      The end user parts of the manual have been pulled out of
+      the original version of the manual, and rewritten. This
+      is now a reference manual only.
+      </para>
+      
+      <para role="publisher">Open Media Now! Foundation</para>
+    </revdescription> 
+  </revision> 
+  
+</revhistory> 
+  
\ No newline at end of file

Index: rtmp.xml
===================================================================
RCS file: rtmp.xml
diff -N rtmp.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ rtmp.xml    1 Mar 2008 15:04:43 -0000       1.1
@@ -0,0 +1,561 @@
+<?xml version="1.0" encoding="utf-8"?>
+<chapter id="rtmp">
+  <title>RTMP Protocol</title>
+  
+  <para>
+    This document is based mostly on my own reverse engineering of the
+    RTMP protocol and AMF format. <emphasis>tcpdump</emphasis> and
+    <emphasis>ethereal</emphasis> are your friend. Some additional info that 
got
+    me started was from the <ulink  type="http"
+       url="http://www.osflash.org/red5";>Red5</ulink>
+    project. <emphasis>Red5</emphasis> is the only other open source Flash
+    server. So some details are still vague, but as the implementation
+    appears to work, we'll figure out what they are later.
+  </para>
+
+  <para>
+    The Real Time Messaging Protocol was created by MacroMedia (now
+    Adobe) for delivering Flash objects and video over a network
+    connection. Currently the only servers which support this format
+    are the MacroMedia Media sever, and the Open Source Red5 project.
+  </para>
+
+  <para>
+    This is a simple protocol, optimized for poor bandwidth
+    connections. It can support up to 64 concurrent streams over the
+    same network connection. Part of each AMF packet header contains
+    the index number of the stream. A single RTMP message can contain
+    multiple AMF packets.
+  </para>
+
+  <para>
+    An RTMP connection uses Tcp/ip port 1935. It is also possible to
+    tunnel RTMP over an HTTP connection using port 80. Each AMF packet
+    is 128 bytes long except for streaming audio, which has 64 byte
+    packets.
+  </para>
+
+  <para>
+    The basics of the RTMP protocol are as follows. All communications
+    are initiated by the client.
+    <mediaobject>
+      <imageobject>
+       <imagedata align="center" fileref="images/rtmp.png"/>
+      </imageobject>
+    </mediaobject>
+  </para>
+
+  <para>
+    The client starts the RTMP connection by sending a single byte
+    with a value of 0x3. This byte is followed by a data block of 1536
+    bytes. The format if this data block is unknown, but it appears to
+    not be actually used by the protocol except as a handshake.
+  </para>
+
+  <para>
+    The server receives this packet, stores the 1536 byte data block,
+    and then send a single byte with the value of 0x3, followed by two
+    1536 data blocks. The second data block is the full contents of
+    the original data block as sent by the client.
+  </para>
+
+  <para>
+    The client receives the 1536 byte data block, and if they match,
+    the connection is established. After the handshake process is
+    done, there are three other messages that the client sends to the
+    sever to start the data flowing.
+  </para>
+
+  <para>
+    The first AMF packet sent to the server contains the
+    <emphasis>connect</emphasis> packet. This doesn't appear to do
+    much but notify the server the client is happy with the
+    handshake, and ready to start reading packets.
+  </para>
+
+  <para>
+    The second packet is the <emphasis>NetConnection</emphasis> object from
+    the client. This ActionScript class is used by the Flash movie to
+    create the network connection to the server.
+  </para>
+
+  <para>
+    The third packet is the <emphasis>NetStream</emphasis> object from the
+    client. This is the ActionScript class used to specify the file to
+    be streamed by the server.
+  </para>
+
+  <para>
+    The RTMP packet for our example looks like this:
+   
+    <programlisting>
+      030000190000c91400000000020007connect00?f0000000000000030003app0200#
+      software/gnash/tests/1153948634.flv0008flashVer02000cLNX 6,0,82,0 0006
+      swfUrl02001dfile:///file|%2Ftmp%2Fout.swfc30005tcUrl\002\0004
+      rtmp://localhost/software/gnash/tests/1153948634.flv\000\000\t
+      \002\000\005userx
+    </programlisting>
+    
+    We'll take this apart in a bit, but you can see how all three AMF
+    packets are in the same message. The message is received in
+    several 128 byte blocks, with the last one being less than
+    that. The total size of the RTMP message is in the header, so the
+    reader can tell if the entire message was read or not.
+  </para>
+  
+  <para>
+    The RTMP header is first, followed by the connect message as an
+    ASCII string as the message body. The following AMF packet is the
+    <emphasis>NetConnection</emphasis> one, which specifies that this is coming
+    from a Flash application. This also contains the file path the server
+    can use to find the file to stream. This is then followed by the
+    version number, which I assume is the version of the Flash player,
+    so the server knows what it is talking to.
+  </para>
+
+  <para>
+    The third packet is the one from <emphasis>NetStream</emphasis>, which
+    specifies the URL used for the movie, followed by the user name
+    for a semblance of security.
+  </para>
+
+  <para>
+    For the next level of detail, we'll explain the format of AMF. AMF
+    is used by the RTMP protocol to transfer data. Each Flash object
+    is encapsulated in an AMF packet, including streaming audio or
+    video.
+  </para>
+
+  <para>
+    The first byte of the RTMP header determines two things about the
+    rest of the message. The first 2 bits of this byte signify the
+    total size of the RTMP header. The RTMP header is of a variable
+    size, so this is important.
+
+    <variablelist>
+      <varlistentry>
+       <term>00</term>
+       <listitem>
+         <para>
+           This specifies the header contains 12 bytes, including
+           this one.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>01</term>
+       <listitem>
+         <para>
+           This specifies the header contains 8 bytes, including this
+           one.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>02</term>
+       <listitem>
+         <para>
+           This specifies the header contains 4 bytes, including this
+           one.
+         </para>
+       </listitem>
+      </varlistentry>
+      <varlistentry>
+       <term>03</term>
+       <listitem>
+         <para>
+           This specifies the header contains 1 byte, so this is the
+           complete header.
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+  </para>
+
+  <para>
+    The other 6 bits in this byte represent the AMF index. As a single
+    RTMP connection can support multiple data streams, this signifies
+    which stream this packet is for. Once an AMF object is fully
+    received by the client, the AMF index may be reused.
+  </para>
+
+  <para>
+    For messages with headers of at least 4 bytes, the next 3 bytes are
+    used by audio and video data packets, but at this time the meaning
+    of this field is unknown.
+  </para>
+
+  <para>
+    For messages with a 8 byte or larger header, the next 3 bytes
+    determine the size of the RTMP message being transmitted. Messages
+    with a 1 byte or 4 byte header use a standard size, 128 bytes for
+    video, and 64 bytes for audio.
+  </para>
+
+  <para>
+    For messages with an 8 byte or larger header, the next byte is the
+    type of the AMF object.
+    
+    <variablelist>
+      <varlistentry>
+       <term>0x3</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP packet is the
+           number of bytes read. This is used to start the RTMP
+           connection.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x4</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP message is a
+           <emphasis>ping</emphasis> packet.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x5</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP message is
+           server response of some type.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x6</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP packet is
+           client request of some type.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x8</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP packet is an
+           audio message.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x9</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP message is a
+           video packet.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x12</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP message is
+           notify. 
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x13</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP message is
+           shared object.
+         </para>
+       </listitem>
+      </varlistentry> 
+      <varlistentry>
+       <term>0x14</term>
+       <listitem>
+         <para>
+           This specifies the content type of the RTMP message is
+           remote procedure call. This invokes the method of a Flash
+           class remotely.
+         </para>
+       </listitem>
+      </varlistentry> 
+    </variablelist>     
+  
+  </para>
+
+  <para>
+    There are two sets of data types to consider. One set is used by
+    the to specify the content type of the AMF object, the other is an
+    ActionScript data type tag used to denote which type of object is
+    being transferred.
+  </para>
+  
+  <para>
+    The values of the initial type byte are:
+    <variablelist>
+
+      <varlistentry>
+       <term>0x0</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a numeric
+           value. All numeric values in Flash are 64 bit,
+           <emphasis>big-endian</emphasis>.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x1</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a boolean
+           value.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x2</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is an
+           <emphasis>ASCII</emphasis> string. 
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x3</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a Flash
+           object. The Flash object data type field further along in
+           the message specifies which type of ActionScript object it
+           is.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x4</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a Flash
+           movie, ie. another Flash movie.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x5</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a NULL
+           value. NULL is often used as the return code from calling
+           Flash functions.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x6</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a
+           undefined. This is also used as the return code from
+           calling Flash functions.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x7</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a reference.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x8</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a ECMA
+           array.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x9</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is the end of an
+           object definition. As an object is transmitted with
+           multiple AMF packets, this lets the server know when the
+           end of the object is reached.
+         </para>
+       </listitem>
+      </varlistentry>
+
+
+      <varlistentry>
+       <term>0xa</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a Strict
+           array.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0xb</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a date.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0xc</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a multi-byte
+           string. Multi-byte strings are used for international
+           language support to represent non <emphasis>ASCII</emphasis>
+           fonts.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0xd</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a an
+           unsupported feature.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0xe</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a record
+           set.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0xf</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a AML
+           object. XML objects are then parsed by the
+           <emphasis>XML</emphasis> ActionScript class.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>0x10</term>
+       <listitem>
+         <para>
+           This specifies the data in the AMF packet is a typed object.
+         </para>
+       </listitem>
+      </varlistentry>
+
+    </variablelist>
+    
+  </para>
+
+  <para>
+    For messages with a 12 byte header, the last 4 bytes are the
+    routing of the message. If the destination is the server, this
+    value is the NetStream object source. If the destination is the
+    client, this is the NetStream object for this RTMP message. A
+    value of 0x00000000 appears to be reserved for the NetConnection
+    object. 
+  </para>
+
+  <para>
+    Multiple AMF streams can be contained in a single RTMP messages,
+    so it's important to check the index of each AMF packet.
+  </para>
+
+  <para>
+    An example RTMP header might look like this. (spaces added between
+    fields for clarity) All the numbers are in hex.
+
+    <screen>
+      03 000019 0000c9 14 000000000
+    </screen>
+    
+    <variablelist>
+      <varlistentry>
+       <term>03</term>
+       <listitem>
+         <para>
+           The first two bits of this byte are the size of the
+           header, which in this example is 00, for a 12 byte
+           header. The next 6 bits is the AMF stream index number,
+           which in this example is 0x3.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>000019</term>
+       <listitem>
+         <para>
+           These 3 bytes currently have an unknown purpose.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>000c9</term>
+       <listitem>
+         <para>
+           Since this example has a 12 byte header, this is the size
+           of the RTMP message, in this case 201 bytes.
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>14</term>
+       <listitem>
+         <para>
+           This is the content type of the RTMP message, which in
+           this case is to invoke a remote function call. (which we
+           later see is the connect function).
+         </para>
+       </listitem>
+      </varlistentry>
+
+      <varlistentry>
+       <term>00000000</term>
+       <listitem>
+         <para>
+           The source is the NetConnection object used to start this
+           connection.
+         </para>
+       </listitem>
+      </varlistentry>
+    </variablelist>
+
+  </para>
+
+  &amf;
+
+</chapter>
+  




reply via email to

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