Gnash Reference Manual

This manual describes version 0.8.2 of Gnash.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. You can find a copy of the GFDL at this link or in the file COPYING-DOCS distributed with this manual.

Revision History
Revision Gnash User Manual version 0.4Feb 2008

Rob Savoye 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.

Open Media Now! Foundation


Table of Contents

1. Introduction
Audience
What Is Supported?
2. Building from Source
Overview
Getting The Source
Releases
CVS Access
Code Dependencies
Testing Dependencies
Documentation Dependencies
Configuring Gnash
Compiling the Code
Creating the Documentation
Running the Tests
Using DejaGnu
Running The Tests Manually
3. Software Internals
A Tour of Gnash
The Libraries
The Applications
The Plugin
The Debug Logging System
Sound handling in Gnash
Sound types
Sound parsing
Sound playback
The SDL sound backend
The Gstreamer backend
Future audio backends
Detailed description of the Gstreamer backend
Testing
Testing Tools
Test Cases
Writing ActionScript Tests
Writing Ming-based self-contained SWF tests
Writing self-contained SWF tests with other compilers
Writing Test Runners
5. Reporting Bugs
Get a Fresh Binary Package
Determine if the bug was previously reported
Review the bug writing guidelines
Filing a bug report
6. Gnash Extensions
Creating A New Extension
Crafting an Extension
Debugging An Extension
Included Extensions
7. RTMP Protocol
AMF Format
8. Mozilla/Firefox NPAPI Plugin
Plugin C API
Plugin C++ API
OpenGL and Threads
Plugin Event Handling
9. Authors
A. GNU Free Documentation License
0. PREAMBLE
1. APPLICABILITY AND DEFINITIONS
2. VERBATIM COPYING
3. COPYING IN QUANTITY
4. MODIFICATIONS
5. COMBINING DOCUMENTS
6. COLLECTIONS OF DOCUMENTS
7. AGGREGATION WITH INDEPENDENT WORKS
8. TRANSLATION
9. TERMINATION
10. FUTURE REVISIONS OF THIS LICENSE
Addendum

List of Tables

2.1. Code Dependency Table
2.2. Testing Dependency Table
2.3. Documentation Dependency Table
2.4. Configuration Options - Features
2.5. Custom Path Options

Chapter 1. Introduction

Gnash is a free SWF movie player. It is available as a stand-alone application or as a plugin for several popular web browsers. It supports playing media from a disk or streaming over a network connection. Some popular video sharing sites like YouTube are supported on a wide variety of devices from embedded ones to modern desktops.

Gnash has a better focus on security, allowing the user tight control of all network or disk based I/O. Gnash also supports extending ActionScript by creating your own classes. You can write wrappers for any development library, and import them into the player much like Perl or Python does.

Audience

This manual is primarily focused on users interested in how to get Gnash installed from a package, and basic usage as a web browser plugin. For more technical details, please refer to the Gnash Reference manual.

What Is Supported?

Gnash is known to compile for most any POSIX and ANSI C++ conforming system if you have all the dependent libraries installed. Systems we test on, and which Gnash is known to run on are Ubuntu, Fedora, Debian, Mandriva, OpenBSD, NetBSD, FreeBSD, Win32, and Darwin (OSX) primarily. Occasionally other platforms are built, primarily by those distribution maintainers. This includes BeOS, Haiku, Syllable, OS/2, Solaris, Slackware, and Gentoo.

Gnash is capable of reading up to SWF v9 files and opcodes, but primarily supports SWF v7, with better SWF v8 and v9 support under heavy development. With the 0.8.2 release, Gnash includes initial parser support for SWF v8 and v9. Not all ActionScript 2 classes are implemented yet, but all of the most heavily used ones are. Many ActionScript 2 classes are partially implemented; there is support for all of the commonly used methods of each class.

Gnash has implemented about 80% of ActionScript v2.0, and has begun implementing ActionScript v3.0. Gnash supports the majority of Flash opcodes up to SWF v9, and a wide sampling of ActionScript classes for SWF v8.

As ActionScript 3 is a more developed version of ActionScript 2, many of the same classes work for both. Support has been added to Gnash's ActionScript library to support the new ActionScript 3 filters, which get applied to every class. Implementing ActionScript clases is often the easiest way for new Gnash developers to make a contribution without a deep internal knpowledge of Gnash.

Gnash has included video support since early 2007, but this is an ever changing field of reverse engineering. Many of the popular video sharing sites use SWF v8 or v9, which Gnash still has imperfect support for. This is improving all the time, so often builds from a development snapshot will work when using the older release packaged in your distribution doesn't. You can find daily snapshots of the latest CVS tree at: http://www.gnashdev.org/dev_snapshots.

Gnash uses ffmpeg for codecs, so any file supported by Mplayer should work with Gnash. Gnash supports the loading of patent free codecs like Ogg Vorbis or Theora from disk based files, while work is being done to support these codecs when embedded in a SWF file. Ffmpeg contains the codecs used by the current SWF defintion, FLV, VP6 (ON2), H.263, H.264, and MP3.

Chapter 2. Building from Source

Overview

The typical process of building from source will involve getting the source, build dependencies, configuration, compilation, testing, and installation. A simplified overview of the process would be:

        ./autogen.sh
        ./configure 
        make
        make check
        make install
      

If you are compiling with GCC you will probably need to use a machine with at least 128 megabytes of physical RAM; 64MB is not enough for a couple of the files, even with swap enabled and optimisation turned off.

At present the Gnash source is about 30 MB extracted and configured and requires a total of about 125 megabytes to compile it.

Continue reading for detailed step-by-step instructions of the entire procedure.

Getting The Source

Releases

Tarballs of official releases can be found in the download area of the project's GNU Savannah page at http://savannah.gnu.org/projects/gnash or under http://ftp.gnu.org/gnu/gnash

CVS Access

The latest Gnash development sources are available via anonymous CVS. Use the following commands to check them out (just hit return when you are prompted for the password):

	  export CVS_RSH=ssh
	  cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/gnash co gnash
	

You will then be able to update your copy from the repository using

	  cd gnash
	  cvs update -d
	

If you only have access to the internet via a web proxy, you will find daily source snapshots of the latest CVS tree in http://www.gnashdev.org/dev_snapshots

Code Dependencies

Gnash has a number of dependencies on other packages. If you install the dependencies using a package manager, be certain to install the development versions of the packages. The normal versions are often missing the headers Gnash needs to compile.

Some dependencies have other dependencies, like GTk also needs glib2, atk, and pango to produce a fully linked executable. Different distributions also use differing dependencies, sometimes a package will depend on libxml2 on one system, but libexpat on another.

Table 2.1. Code Dependency Table

NameLevelVersionDescriptionExplanationapt-get packageRPM/Yum packageBSD package
BoostRequired1.32 or higher Boost is a library of portable C++ classes and templates. In Gnash, Boost libraries are used extensively, primarily boost-gthread and boost-date-time. Boost is used for thread and mutext handling. libboost-thread-dev, libboost-date-time-dev libboost-dev libboost-thread-devel, libboost-date-time-devel boost-headers, boost-libs, or just boost
libxml2Required  Libxml2 is the GNOME XML parser library and is available at http://xmlsoft.org. This library is used to parse messages for the XML XMLNode, or XMLSocket ActionScript classes. libxml2-devlibxml2-devellibxml2
AGGPossibly Required2.4 or higher AGG is the AntiGrain low-level 2D graphics library. Gnash requires the installation of at least one renderer. AGG is considered the best supported renderer for Gnash. libagg-devagg-develagg
OpenGLPossibly Required  OpenGL is a standard specification defining a cross-language cross-platform API for writing applications which produce 3D and 2D graphics. It supports hardware acceleration. You can download a free implementation from http://www.mesa3d.org, although it doesn't support hardware acceleration. Gnash requires the installation of at least one renderer. If you don't have a hardware accelerated driver, you're better off using AGG for the renderer. libgl1-mesa-devlibmesa-develmesa
CairoPossibly Required  Cairo is a 2D graphics library with support for multiple output devices. It will automatically use graphic card acceleration when available, and has an experimental OpenGL backend. Gnash requires the installation of at least one renderer. Cairo is considered the least supported renderer for Gnash. libcairo2-devcairo-develcairo
GTKPossibly Required2.2 or higher GTK is the GIMP Toolkit GUI library used by the GNOME desktop. It uses Cairo internally. Gtk enables better integration with Firefox, as well as better event handling and higher level GUI constructs like menus and dialog boxes. Gnash requires the installation of at least one GUI library. GTK is considered to be the best supported GUI library option for Gnash. libgtk2.0-devgtk-develgtk+2
GtkGlExtPossibly Required  GtkGlExt integrates OpenGL into GTK. This library is required in order to use the GTK GUI library in conjunction with the OpenGL renderer. libgtkglext1-devgtkglext-develgtkglext
SDLPossibly Required  The Simple DirectMedia Layer is a cross-platform multimedia library which provides abstraction for audio, graphics, sound and input APIs. SDL is available from http://www.libsdl.org. Gnash requires the installation of at least one GUI library. SDL may also be used as a sound handler regardless of whether it is employed as a GUI library. The GUI library is poorly supported in Gnash, but the sound handler is the best supported in Gnash. libsdl1.2-devSDL-develSDL-1.2
FLTKPossibly Required2.0 or higher The Fast Light ToolKit is a portable GUI library which is intended as a replacement for the SDL GUI. Gnash requires the installation of at least one GUI library. FLTK may be used in conjunction with the Cairo and AGG renderers. No distribution packages are available.No distribution packages are available.No distribution packages are available.
KDEPossibly Required  Kdelibs is a collection of libraries needed to compile KDE applications. Gnash requires the installation of at least one GUI library. Kdelibs is also required for the Kpart plugin for Konqueror. kdelibs3-dev, kdebase-devkdelibs-devel, kdebase-develkdelibs, kdebase
GstreamerOptional  Gstreamer is a video handler. If you would like video playback, you must install one of the video handlers. libgstreamer0.8-devgstreamer-develgstreamer-0.10
gst-ffmpegPossibly Required  gst-ffmpeg allows you to use the FFMPEG decoder with Gstreamer. This package is required if you would like to use Gstreamer as a video handler. gstreamer0.8-ffmpeg-devgstreamer-ffmpeg-develgstreamer-ffmpeg
FFMPEGPossibly Required  FFMPEG is a video handler. If you would like video playback, you must install one of the video handlers. When using the gstreamer-ffmpeg plugin, ffmpeg doesn't need to be installed, as it's part of the plugin. For systems without Gstreamer support, ffmpeg can be used directly. ffmpeg-devffmpeg-develffmpeg
JPEGOptional  JPEG is a lossy image format which is heavily used for images. This library is used for rendering JPEGs. libjpeg62-devlibjpegjpeg
PNGOptional  PNG is a patent-free image format which is comparable to GIF. This library is used for rendering PNGs. libpng12-devlibpngpng
libcurlOptional  libcurl is the multiprotocal file transfer library. This library is used for URL downloading. libcurl4-gnutlslibcurlcurl
Glib2Optional  Glib2 is a dependency of Gtk, and is a collection of commonly used functions. This library is used for convenience. glib2-devglib2-develglib2
AtkOptional  Atk is a dependency of Gtk, and is used for accessibility support. This library is used for accessiblity.. atk-devatk-develatk
PangoOptional  Pango is a dependency of Gtk, and is used for font handling. This library is used for font handling. pango-devpango-develpango
automakePossibly Required1.6.0 Automake is a tool for generating Makefile.in files. This package is required to run autogen.sh, which is a requirement if you are using the development source from CVS. automakeautomakeautomake
autoconfPossibly Required2.59 Autoconf is a package for generating configure scripts. This package is required to run autogen.sh, which is a requirement if you are using the development source from CVS. autoconfautoconfautoconf
gettextPossibly Required0.14.6 Gettext is part of the GNU Translation Project. This package is required to run autogen.sh, which is a requirement if you are using the development source from CVS. gettextgettextgettext
libtoolPossibly Required1.5.22 This is a generic library support script. This package is required to run autogen.sh, which is a requirement if you are using the development source from CVS. libltdl3-devlibtoollibtool

Testing Dependencies

Gnash tries to run as many tests as possible, but will simply skip tests if the tools to run them are unavailable.

Table 2.2. Testing Dependency Table

NameLevelVersionDescriptionExplanationapt-get packageRPM/Yum packageBSD package
MingOptional0.4.0_beta4 or higher Ming is an ActionScript compiler. Ming is the primary compiler for ActionScript testcases. No distribution packages are available.No distribution packages are available.No distribution packages are available.
MtascOptional1.12 or higher Mtasc is an ActionScript compiler. Mtasc is used in some tests. mtascNo distribution packages are available.No distribution packages are available.
swfcOptionalpart of swftools 0.8.1 Swfc a swf decompiler. Swfc is used in some testcases. No distribution packages are available.No distribution packages are available.No distribution packages are available.
swfmillOptional 0.2.12 Swfmill is an XML-based SWF (Shockwave Flash) processing tool. Swfmill is used in some testcases. No distribution packages are available.No distribution packages are available.No distribution packages are available.
PythonOptional2.4 or higher Python is a scripting language. Python is used by part of the testing framework. pythonpythonpython
DejaGnuOptional1.4 or higher DejaGnu is a testing framework. DejaGnu is used to run multiple tests in an automated fashion. dejagnudejagnudejagnu

Documentation Dependencies

The following packages are used to build Gnash's documentation.

Table 2.3. Documentation Dependency Table

NameLevelVersionDescriptionExplanationapt-get packageRPM/Yum packageBSD package
DocbookRequired  Docbook is is an industry-standard XML format for technical documentation. You can download it from http://sourceforge.net/project/showfiles.php?group_id=21935#files. Gnash documentation is written in Docbook. docbook-utils and docbook-dsssl docbook-dtd41-sgml and docbook-style-dsssl docbook
DocBook2XOptional  This software package converts Docbook documents to the traditional man page format, GNU Texinfo format, and HTML (via Texinfo) format. It is available at http://docbook2x.sourceforge.net/. DocBook2X is required to produce HTML and Texinfo formats. docbook2xdocbook2xdocbook2x
DocBook-utilsOptional  This software package converts Docbook documents to the traditional man page format, GNU Texinfo format, and HTML (via Texinfo) format. DocBook-utils is required to produce HTML and Texinfo formats. docbook-utilsdocbook-utilsdocbook-utils
TexinfoPossibly Required  Texinfo can be used to convert DocBook2X output into GNU info pages. You can download it from http://ftp.gnu.org/gnu/texinfo/. Texinfo is required if you wish to product GNU info pages. texinfotexinfotexinfo
FOPOptional0.20.5 Formatting Objects Processor is a print formatter driven by XSL formatting objects. It is a Java application which can output PDF, PCL, PS, SVG, XML, Print, AWT, MIF, and Text. It is available at http://xmlgraphics.apache.org/fop/. FOP is required for PDF output. fopfopfop
Java (j2re)Possibly Required  FOP requires Sun's Java runtime (GCJ does not work with FOP). You can download it from http://java.sun.com. Sun's Java runtime (j2re) is required to use FOP. Download the package from Sun. Download the package from Sun.  
JAIPossibly Required  Sun's Java Advanced Imaging API can be downloaded from http://java.sun.com/products/java-media/jai/iio.html. JAI is required if you wish to include graphics in a PDF file being generated with FOP. Download the package from Sun. Download the package from Sun.  

If you install j2re, set the JAVA_HOME environment variable to the top directory of the j2re installation. If you encounter problems with the Java installation, you may also need to add this path to the CLASSPATH environment variable.

Configuring Gnash

Gnash, like most GNU projects, allows a user to select various options before compiling its source code. These options include selecting from the available features, specifying custom paths for installation, and cross compiling support uses GNU Autoconf for configuration.

If you opted to download the development snapshot of Gnash, the configure script will not be included. It can be created by running autogen.sh from the source root directory:

      ./autogen.sh
    

Note that there are some dependencies for autogen.

All the standard configure options are available. In addition, Gnash has two types of options: those that enable or disable features, and those that specify custom paths for development packages which are not found during the default search. A complete list of all configuration options, including standard ones, can be seen by typing:

      ./configure --help | less
    

Read further for a more detailed explanation of Gnash-specific options.

The syntax for running configure is as follows:

      configure <options>
    

The example below shows the configure options which create the smallest working standalone version of Gnash. In this example, configure is being run from the source root directory:

    ./configure --disable-debugger --disable-cygnal \
    --disable-plugin --enable-media=ffmpeg --enable-gui=sdl
  

By default, you shouldn't need to supply any options to configure. The configure script will attempt to determine what to build based on the development libraries you have installed. The default configuration for Gnash is both GTK and KDE GUIs, the AGG renderer, and Gstreamer for multimedia support, with no extensions built.

Being highly portable, Gnash has many configuration options available, and not all are supposed to work together. A common mistake when configuring Gnash is to supply too many options, overdriving Gnash's ability to do the right thing.

Features

Some switches can be used during configuration to enable or disable features of Gnash. Some of the most important configuration options are:

  • --enable-gui lets you specify your GUI of choice. The default option is GTK.

  • --enable-renderer allows a renderer to be chosen. The default renderer is AGG.

  • --enable-media permits a media handler to be selected. The default is Gstreamer.

A complete list of available features follows.

Table 2.4. Configuration Options - Features

OptionFunction
--enable-debuggerEnable support for the Flash debugger. The debugger is mainly of interest to Flash developers, and is still under development.
--enable-lirc Enable support for the LIRC remote control protocol.
--enable-cygnal Build the Cygnal streaming media server.
--disable-menus Disable building all the menus for the GUI. THis is used by mobile devices without as much screen space.
--enable-docbook Enable the generation of HTML, INFO, and MAN versions of the documentation from the Docbook XML. You will then be able to use make html, make info, and make man commands. By default, man,info and html pages are generated.
--enable-gui=gtk|sdl|kde|fltk|fb|hildon|alp

Select the Graphic User Interface to use (choose one).

GTK

The GTK+ toolkit, which is the default GUI. Said to interwork particularly well with firefox.

Hildon

The Hildon toolkist is based on GTK+, and is use by some mobile devices.

ALP

The ALP "Hiker" GUI is used for the Access Linux platform.

SDL

Simple DirectMedia Layer, a simple and portable GUI. Its sound facilities are used when --enable-media=ffmpeg regardless of whether it is also in charge of the GUI.

KDE

An interface adapted to the KDE Desktop Environment. This must be selected when building the Konqueror plugin "klash". Furthermore, the only renderer that currently works with KDE is opengl.

FLTK

Fast Light ToolKit, low on resource usage. Since all build using fltk are now broken, we declare it "for developers".

FB

The Linux Frame Buffer, also known as /dev/fb0. AGG is the only renderer that can currently be used with the framebuffer GUI.

--enable-i810-lod-bias Enable fix for Intel 810 LOD bias problem. Older versions of libMesa on the Intel i810 or i815 graphics processor need this flag or Gnash will core dump. This has been fixed in newer versions (summer 2005) of libMesa.
--enable-media=ffmpeg|gst|none

Select the specified media decoder and sound engine. FFMPEG uses the SDL sound engine; GST uses its own. GST is the default decoder.

You should only select one media decoder.

--disable-nsapi --enable-nsapi Force disable/enable building the NPAPI plugin. By default the Mozilla plugin is built if the GTK gui is selected. Specify the --with-npapi-plugindir= option to specify where the plugin should be installed.
--disable-kparts --enable-kparts Force disable/enable building the KPARTS plugin. By default the KDE plugin is built if the kde gui is selected. Specify the --with-kde-plugindir= and --with-kde-servicesdir= options (or more generally the --with-kde-pluginprefix= one) to specify where the plugin should be installed. The default installation dir is extracted from kde-config.
--disable-plugins Disable build of both kparts and npapi plugins
--enable-renderer=opengl|cairo|agg Enable support for the a graphics backend. Currently only opengl and agg work sufficiently. OpenGL is used when you have hardware accelerated graphics. AGG i used when you do not have hardware accelerated graphics. Typically most desktop machines have OpenGL support, and most embedded systems do not. OpenGl is the default when building Gnash, although the quality of AGG's rendering is currently superior to OpenGL.
--enable-sdk-install Enable installing the libraries and headers as an SDK.
--disable-shared Enable installing the shared libraries and headers. Note that the extensions mechanism may not work if shared libraries are disabled.
--enable-strict Turn verbose GCC compiler warnings. By default only -Wall is used with GCC.
--enable-fps-debug Enable FPS debugging code. When this feature is compiled in you can use the -f switch of Gnash to have FPS printed at regular intervals.
--enable-writeMakes the Mozilla plugin write the currently playing SWF movie to /tmp.
--disable-mit-shm Disable support for the MIT-SHM X extensions. Currently support is only available using GTK gui and AGG renderer. Keeping it enabled is not a problem as it will not be used if not available in the current X session.

Specifying Custom Paths

By default, none of these options should be required unless you want Gnash to use a specific version of a development package, or if the configure test fails to find a component. Please report the problem if a configure test fails.

The following custom path options are available:

Table 2.5. Custom Path Options

OptionFunction
--x-includes=DIR X include files are in DIR.
--x-libraries=DIR X library files are in DIR.
--with-libxml=PFX Prefix to where libxml is installed.
--with-libxml-libraries=DIR Directory where libxml library is installed.
--with-libxml-includes=DIR Directory where libxml header files are installed.
--with-docbook=DIR Directory where the DocBook style-sheets are installed.
--with-sdl-prefix=PFX Prefix where SDL is installed.
--with-zlib-incl Directory where zlib header is installed.
--with-zlib-lib Directory where zlib library is installed.
--with-jpeg-incl Directory where jpeg header is installed.
--with-jpeg-lib Directory where jpeg library is installed.
--with-png-incl Directory where png header is installed.
--with-png-lib Directory where png library is installed.
--with-qt-dir Directory where QT is installed. This is only used by the Klash plugin.
--with-qt-includes Directory where the QT header files are installed. This is only used by the Klash plugin.
--with-qt-libraries Directory where the QT libraries are installed. This is only used by the Klash plugin.
--with-npapi-plugindir This is the directory to install the NPAPI (Mozilla) plugin in. By default it goes to ~/.mozilla/plugins.
--with-kde-pluginprefix This option sets the default install dir for all KPARTS (kde) files. The plugin will be installed in PREFIX/lib/kde3, use -with-kde-plugindir to override. The service file in PREFIX/share/services, use --with-kde-servicesdir to override. The config file in PREFIX/share/config, use --with-kde-configdir to override. The appdata file in PREFIX/share/apps/klash, use --with-kde-appsdatadir to override.
--with-kde-plugindir This is the directory to install the KPARTS (kde) plugin in. By default it is what's set by --with-kde-pluginprefix or what's returned by kde-config --install module --expandvars, or $(prefix)/share/services if kde-config is not found.
--with-kde-servicesdir This is the directory to install the KPARTS (kde) service in. By default it is what's set by --with-kde-pluginprefix or what's returned by kde-config --install services --expandvars, or $(libdir)/kde3 if kde-config is not found.
--with-kde-configdir This is the directory to install the KPARTS (kde) config files in. By default it is what's set by --with-kde-pluginprefix or what's returned by kde-config --install config --expandvars, or $(prefix)/share/config if kde-config is not found.
--with-kde-appsdatadir This is the directory to install the KPARTS (kde) application data files in. By default it is what's set by --with-kde-pluginprefix or what's returned by kde-config --install data --expandvars, or $(prefix)/share/apps if kde-config is not found.
--with-ming Ming is used to build test cases, but not by the Gnash player itself.
--with-ogg_incl Directory where the libogg headers are installed.
--with-ogg_lib Directory where the libogg library is installed.
--with-gstreamer-incl Directory where the Gstreamer headers are installed. Gstreamer version 0.10 or greater must be used.
--with-gstreamer-lib Directory where the Gstreamer library is installed. Gstreamer version 0.10 or greater must be used.
--with-opengl-includes Directory where OpenGL (libMesa) headers are installed.
--with-opengl-lib Directory where the OpenGL (libMesa) library is installed.
--with-glext-incl Directory where GtkGlExt headers are installed.
--with-glext-lib Directory where the GtkGlExt library is installed.
--with-gtk2-incl Directory where the Gtk2 headers are installed.
--with-gtk2-lib Directory where the Gtk2 library is installed.
--with-cairo_incl Directory where the Cairo headers are installed.
--with-cairo-lib Directory where the Cairo library is installed.
--with-glib-incl Directory where the Glib headers are installed.
--with-glib-lib Directory where the Glib library is installed.
--with-pango-incl Directory where the Pango headers are installed.
--with-pango-lib Directory where the Pango library is installed.
--with-atk-incl Directory where the ATK headers are installed.
--with-atk-lib Directory where the ATK library is installed.
--with-pthread-incl Directory where the Pthread headers are installed.
--with-pthread-lib Directory where the Pthread library is installed.
--with-agg-incl Directory where the AGG (Antigrain) headers are installed.
--with-agg-lib Directory where the AGG (Antigrain) library is installed.
--with-ffmpeg-incl Directory where the FFMPEG headers are installed.
--with-ffmpeg-lib Directory where the FFMPEG library is installed.
--with-boost-incl Directory where the Boost headers are installed.
--with-boost-lib Directory where the Boost library is installed.
--with-curl-incl Directory where the libCurl headers are installed.
--with-curl-lib Directory where the libCurl library is installed.

Once you have Gnash configured, you are ready to build the code. Gnash is built using GNU make.

Compiling the Code

The most basic way to compile code is simply:

	make
      

If the compilation ends with an error, check the output of configure and ensure that you are not missing any required prerequisites. The output of make can be verbose; you may wish to pipe the output to a file.

The variables used by make can be redefined when the program is invoked, if you desire it. The most interesting flags are CFLAGS and CXXFLAGS, which are often used to enable debugging or turn of optimization. The default value for both of these variables is -O2 -g. A list of influential environment variables can be seen in the configuration help:

./configure --help

In the following example, debugging is enabled and optimization is disabled:

make CFLAGS=-g CXXFLAGS=-g

Creating the Documentation

By default, documentation is not built when you install Gnash. This is because there are a number of dependencies for the documentation. Documentation is built when it is specified with a specific target in the generated Makefile in the doc/C sub-directory. If you type make install in this directory, all documents will be built.

You must specify a target output format when you wish to create documentation. The available output formats are: html, pdf, info, man, and alldocs. It is also possible to output GNOME help if the configure option --enable-ghelp was used. The alldocs target will build all output formats except GNOME help. For example, to create HTML output, type:

	make html
      

Gnash also uses Doxygen to produce HTML documentation of Gnash internals. You must have Doxygen installed to produce this documentation, which is built from the doc directory with the command (documents will be placed in the subdirectory apidoc/html):

	make apidoc
      

Running the Tests

Before beginning the potentially lengthy install, it is wise to test the installation. If a test fails, please report it by following the instructions for reporting a bug.

Using DejaGnu

The easiest way to run Gnash's test suite is to install DejaGnu. After installing DejaGnu, run:

	  make check
	

Increasing Verbosity

If you encounter a problem with a test, increasing the verbosity may make the issue easier to spot. Additional details are visible when RUNTESTFLAGS are used to add the verbose and all options. The verbose option prints more information about the testing process, while the all option includes details on passing tests.

	    make check RUNTESTFLAGS="-v -a"
	  

Running Some Tests

It is possible to run just a single test, or a subdirectory of tests, by specifying the directory or compiled test file.

Some tests rely on testsuite/Dejagnu.swf, which in turn relies on Ming. This file is created when you run make check for the entire testsuite, and can also be created on demand:

	    make -C testsuite Dejagnu.swf 
	  

In this example, the clip_as_button2 test is compiled and run:

	    make -C testsuite/samples clip_as_button2-TestRunner 
	    cd testsuite/samples && ./clip_as_button2-TestRunner
	  

This creates and runs all the tests in the directory movies.all:

	    make -C testsuite/movies.all check
	  

Running The Tests Manually

You may also run test cases by hand, which can be useful if you want to see all the debugging output from the test case. Often the messages which come from deep within Gnash are most useful for development.

The first step is to compile the test case, which can be done with make XML-v#.swf where the '#' is replaced with the target SWF version or versions. For example:

	  make XML-v{5,6,7,8}.swf
	

Movie tests

This creates a Flash movie version of the test case, which can be run with a standalone Flash player. For instance, the target for SWF version 6 could be run with Gnash:

	    gnash -v XML-v6.swf
	  

ActionScript Unit Tests

Unit tests for ActionScript classes in testsuite/actionscript.all are run without a graphical display:

	    gprocessor -v XML-v6.swf
	  

Installation

Now that Gnash has been compiled and tested, use the following command to install it:

      make install
    

The above command installs the standalone player. If the correct files were found by configure and if the --disable-plugin option was not specified, the Gnash browser plugin is also installed.

Gnash installs a number of libraries, namely: libgnashbase, libgnashamf, libgnashmedia, libserver, and libgnashplugin. Executables consist of the (optional) plugin, gprocessor, cygnal, dumpshm, soldumper, and gnash. Documentation may also be installed. The installation location is controlled with the --prefix configure option, except for plugins, which are explicitly set with --plugin-dir.

Note that if you are using a single file-system NFS mounted to multiple platforms, the configuration option --exec-prefix may be used to specify where platform-dependent executables and libraries are installed.

Libraries

Installed libraries are located in /usr/local/lib by default. If the --prefix option was used during the configuration step, the libraries will be installed in the directory lib inside the path you specified. If the libraries are stored in a non-standard location, you must identify the path in one of two ways.

The traditional way to do this on UNIX platforms is to set the LD_LIBRARY_PATH variable to the path plus /lib. For example, if you installed in /home/gnash, the LD_LIBRARY_PATH path would be /home/gnash/lib. Multiple paths are delimited with a colon (':').

GNU/Linux allows the custom path to be added to /etc/ld.so.conf. After adding the path, run ldconfig as root to update the runtime cache.

Executables

The Mozilla plugin is built from headers (the Mozilla SDK) provided with Gnash and does not need extra development packages to be installed. By default, the plugin is installed to ~/.mozilla/plugins/. To enable the plugin for other users, copy the file libgnashplugin.so to .mozilla/plugins/ in their home directory. You may also specify the plugin installation directory by using the --with-plugindir option at configuration time.

These defaults are likely to change in future versions of Gnash.

The remaining executables are installed in the bin subdirectory of the directory specified by during configuration. If no path was specified, the default is /usr/local/bin.

Documentation

Documentation is not built by default; please refer to the section on documentation for more information on building documentation.

man and info are installed in /usr/local/share/man and /usr/local/share/info respectively, unless the --mandir or --infodir configuration options are used.

GNOME help documentation uses the directory /usr/local/share/gnash/doc/gnash/C/ by default. A configuration file in the Gnash source tree, doc/C/gnash.omf is used to specify under which menu item Gnash appears in the GNOME help system.

Cross Configuring

To cross configure and compile Gnash, begin by building a target system on your workstation. This includes cross compilers for the target architecture, and some system headers. You will also need to cross compile all the dependencies normally needed to build Gnash. This can on occasion be a daunting process, as not all libraries will cross configure and cross compile. There is more information about cross compiling all the dependant packages on the http://www.gnashdev.org web site.

If you need to build your own tool chain, that is beyond the scope of this manual. There are various resources on the web for howto's on building GCC based cross toolchains. Two popular sites are http://frank.harvard.edu/~coldwell/toolchain/ and http://www.kegel.com/crosstool/. This can also be a very time consuming and frustrating process, even for experienced developers.

Because the process of building your own cross tool chain can be harder than one may wish, there are several other cross development environments that simulate a native environment to make it easier to develop. These also let you develop for both native and cross builds. Several popular ones are Access Linux Platform, Scratchbox, Open Embedded, Maemo.

To build for an ARM based system on an x86 based systems, configure like this using the traditional style cross toolchain, configure like this:

    ../../gnash/configure --build=i686-pc-linux-gnu
    --host=arm-linux --prefix=/usr/local/arm/oe --disable-nsapi
    --disable-kparts --enable-gui=fb --enable-renderer=agg
    --disable-shared --disable-menus
    
  

The important configuration options are the ones which specify the architecture for the build:

--target

The target architecture, where the final executables are expected to run.

--host

The host architecture, where the executables are expected to run. Usually this is the same as the --target, except when building a compiler as a Canadian Cross. In this case, you might build a cross compiler on a UNIX system which runs on a win32 machine, producing code for a third architecture, such as ARM. In this example, --target would be 'arm-unknown-linux-gnu', while --host would be 'win32'.

--build

This is the system the build is running on.

The following example of configure builds for an ARM system on an x86 system. It was run after an ARM system was built in /usr/arm and other required libraries were cross compiled.

      ./configure -target=arm-unknown-linux-gnu --prefix=/usr/arm \
      --host=arm-unknown-linux-gnu --build=i686-pc-linux-gnu --disable-plugin
    

Chapter 3. Software Internals

A Tour of Gnash

The top level of Gnash has several libraries, libgnashbase, libgnashserver, libgnashasobjs and libgnashbackend. There are several utility programs included for debug parsing and processing of Flash movie files, and other useful utilities for examining local Shared Objects and sniffing LocalConnections.

The Libraries

libgnashbase

Libgnashbase contains support classes used by the rest of the code.This library has no dependencies on any of the other Gnash libraries.

Gnash makes heavy use of smart pointers, so memory allocations are freed up automatically by the interpreter. Both STL and Boost smart pointers are used.

libgnashgui

Libgnashgui contains code for a portable GUI class that supports using GTK2, a framebuffer, SDL, or KDE, FLTK, or Aqua.

libgnashserver

Libgnashserver is the guts of the interpreter itself. This is where the main code for the interpreter lives. Includes in libserver are the two support libraries for the parser and the core of the virtual machine.

libgnashasobjs

Libgnashasobjs contains all the ActionScript classes used by the interpreter.

libgnashamf

AMF is the data format used internally by SWF files. This is Gnash's support library to handle AMF data. This is used by the ActionScript classes SharedObject and LocalConnection. This is also used by the NetStream class when using thre RTMP streaming network protocol.

libgnashbackend

Libgnashbackend is a library containing the rendering code that glues this display to the Gnash. Supported rendering backends are OpenGL, Cairo, and AGG.

libgnashplugin

Libgnashplugin is the Mozilla/Firefox plugin.

libklashpart

Libklashpart is the Konqueror plugin.

The Applications

There are currently a few standalone programs in Gnash, which serve either to assist with Gnash development or to play flash movies.

The Standalone Player

This is the standalone OpenGL backend used to play movies. There are several command line options and keyboard control keys used by Gnash.

Gprocessor

Gprocessor 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 .gsc files that Gnash uses to cache data, thereby speeding up the loading of files.

SOLdumper

SOLDumper is a utility program used to find and dump the content of Local Shared Objects, also called "Flash Cookies" by some.

Dumpshm

Dumpshm is a program used to find and dump the contents of the LocalConnection shared memory segment.

The Plugin

The plugin is designed to work within Mozilla or Firefox, although there is Konqueror support as well. The plugin uses the Mozilla NPAPI plugin API to be cross platform, and is portable, as well as being well integrated into Mozilla based browsers.

Current Status

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.

As of Jan, 2007, streaming video, ala "YouTube" works, along with other video sharing sites.

GUI Support

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.

Gnash can use either several different GUI toolkits to create the window, and to handle events for the standalone player.

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.

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.

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.

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.

Mozplugger

Mozplugger is a Mozilla/Firefox 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.

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.

Use of MozPlugger is obsolete now that the Gnash plugin works. Still, this may be useful still on some platforms.

Add this to your $(HOME)/.mozilla/mozpluggerrc file to enable this:

	    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
	  

Once this is added, you must delete the $(HOME)/.mozilla/firefox/pluginreg.dat 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 swf files after it is recreated. You will need to restart Firefox to recreate this file.

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 about:plugins 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.

Klash

Klash is MozPlugger type support for KDE's Konqueror web browser. Klash makes Gnash a kpart, 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.

By default, Klash is not built. To enable building Klash, use the --enable-klash option when configuring. Other than installing, there is nothing else that needs to be done to install Klash.

The Debug Logging System

Gnash supports a debug logging system which supports both C and C++ natively. This means you can use both printf() style debug messages and C++ iostreams style, where you can print C++ objects directly as you would when using cout.

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 log_msg() and log_error() functions, and used a callback to set them up.

If a filename is not specified at object construction time, a default name of gnash-dbg.log 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 GNOME or KDE the debug file goes in your home directory, since that's considered the current directory.

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 -v options on the command line. You can also disable the creation of the debug log.

Currently the use of the C++ API for logging is discouraged, do to performance issues.and the generic log_msg() has been replaced by more spcific function calls to allow more control of what gets displayed and logged.

Logging System C API

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.

log_error(const char* fmt, ...)

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.

void log_unimpl

Displays a warning to the user about missing Gnash features. We expect all calls to this function to disappear over time, as we implement those features of Flash.

void log_trace

Used only for explicit user traces

void log_debug

Logs debug information.

void log_action

Log action execution information. Wrap all calls to this function (and other related statements) into an IF_VERBOSE_ACTION macro, so to allow completely removing all the overhead at compile time and reduce it at runtime.

void log_parse

Log SWF parsing Wrap all calls to this function (and other related statements) into an IF_VERBOSE_PARSE macro, so to allow completely removing all the overhead at compile time and reduce it at runtime.

void log_security

Display a message with security related information.

void log_swferror

This indicates an error in how the binary SWF file was constructed, i.e.probably a bug in the tools used to build the SWF file. Wrap all calls to this function (and other related statements) into an IF_VERBOSE_MALFORMED_SWF macro, so to allow completely removing all the overhead at compile time and reduce it at runtime.

log_warning(const char* fmt, ...)

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.

Logging System C++ API

This is the new C++ streams based API that can be used to print C++ objects natively. All output lines are timestamped.

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 GNASH_REPORT_RETURN at the end of a function to display the function returning message.

GNASH_REPORT_FUNCTION;

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.

GNASH_REPORT_RETURN;

This is used by C functions to print the returning from function debug message. For C++, this macro is executed automatically by the destructor.

This is the main API for the logging system. By default everything is setup to write to the default gnash-dbg.log file whenever a verbose option is supplied. Optionally it is possible to open a log file with a specified name, allowing multiple output files.

closeLog(void)

Close a debug log. The disk file remains.

removeLog(void)

Delete the debug log file from disk.

setVerbosity(void)

Increment the verbosity level.

setVerbosity(int)

Set the verbosity level.

setStamp(bool flag)

If flag is true, then print a timestamp prefixed to every output line. If flag is false, then don't print a timestamp.

setWriteDisk(bool flag)

If flag is true, then create the disk file. If flag is false, then don't create the disk file.

Sound handling in Gnash

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.

There are two different settings related to sound support: pluginsound and sound. This was done in order to allow the plugin to be independently configured, for instance to block sound from advertisements.

Sound types

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.

Sound parsing

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.

Sound playback

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.

The SDL sound backend

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

The Gstreamer backend

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.

Future audio backends

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.

Detailed description of the Gstreamer backend

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:

	 ___
	|Bin|_
	|___| \
	 ___   \ _____       ____________
	|Bin|___|Adder|_____|Audio output|
	|___|   |_____|     |____________|
	 ___   /
	|Bin|_/
	|___|

      

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:


	|source|---|capsfilter|---|decoder|---|aconverter|---|aresampler|---|volume|

      

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.

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.

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.

Testing

Instructions on running tests can be found in the section on building Gnash.

Testing Tools

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.

The primary compiler used at this time is Ming. Since release 0.3, Ming includes a command-line compiler, makeswf. This allows test case development to be done entirely with free tools.

The other tools are optional. DejaGnu is used to run multiple test cases in an automated manner. DejaGnu is used by many other GNU projects like GCC and Samba.

Test Cases

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.

Writing ActionScript Tests

Writing ActionScript tests is very simple. The makeswf 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.

Each test unit sets an rcsid variable, includes the check.as file and performs some checks using the provided macros. Here is an example:


	  // 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 ...
	

The check(expr) macro will trace PASSED or FAILED together with the expression being evaluated and the line number of the check. This is the format expected by DejaGnu.

The check_equals(obtained, expected) macro uses equality operator == to check for equality. When possible, use of the check_equals() macro is preferred over check() because it shows what the actual result was in case of a failure.

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.

Test units are built by running make TestName-v#.swf. This will use TestName.as as source and the value of # as target version. Allowed target version are from 5 to 8 (inclusive).

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 TestName.as.pp or TestName-v#.swf.frame#.pp (depending on Ming version) and it's not thrown away by makeswf to make debugging easier.

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:


	  #if OUTPUT_VERSION >= 7
	  check(_root.getSWFVersion == OUTPUT_VERSION);
	  #endif
	  
	

Writing Ming-based self-contained SWF tests

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.

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 facilities provided by the Gnash testing framework to easily run tests.

For generic Ming API documentation, see http://www.libming.org.

Using Ming-based test generators facilities

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.

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.

You will not need to directly invoke the TestState object created by the 'add_dejagnu_functions()' routine, rather you will be using C macros hiding its complexity:


	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.
	

Test cases generated using Ming and the provided facilities 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.

See section Writing Test Runners for information about writing SWF test runners.

Writing self-contained SWF tests with other compilers

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.

The loadable module is called Dejagnu.swf and is built during make check 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 dejagnu_module_initialized variable, which will be set to 'true' when all initialization actions contained in the Dejagnu.swf file are executed.

Once the module is loaded you will be able to invoke the following functions, all registered against the _root sprite (effects of _lockroot untested):

	  
	  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.
	  
	

Visual traces are lines of text pushed to a textarea defined by the Dejagnu.swf module. The textarea is initially placed at 0, 50 and is 600x800 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 debugging trace (call to the trace function). The latter will be used by the testing framework.

See section Writing Test Runners for information about writing a test runners for your self-contained tests.

Writing Test Runners

Test runners are executables that run one or more tests, writing results in Dejagnu form to standard output.

The Dejagnu form uses a standard set of labels when printing test results. These are:

Label

Meaning

PASSED

The test succeeded.

FAILED

The test failed.

XPASSED

The test succeeded, but was expected to fail.

XFAILED

The test failed, and was expected to fail.

UNRESOLVED

The results of the test could not be automatically parsed.

UNTESTED

This test case is not complete.

UNSUPPORTED

The test case relies on a conditional feature which is not present in your environment.

The following labels may also appear:

Label

Meaning

ERROR

There was a serious error in running the test.

WARNING

There may have been a problem with running the test.

NOTE

There was some additional information given about the test.

Using the generic test runner for self-contained SWF tests

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".

A generator for simple test runners can be found in testsuite/generic-testrunner.sh. The script can be invoked by passing it $(top_builddir) 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:

	    MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
	    sh $(srcdir)/../generic-testrunner.sh $(top_builddir) MyTest.swf > $@
	    chmod +x $@
	  

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:

	    MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
	    sh $(srcdir)/../generic-testrunner.sh -r2 $(top_builddir) MyTest.swf > $@
	    chmod +x $@
	  

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.

	    MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
	    sh $(srcdir)/../generic-testrunner.sh -f10 $(top_builddir) MyTest.swf > $@
	    chmod +x $@
	  

When both -f and -r are given, the first exit condition reached will take effect.

Writing Movie testers

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.

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.

Movie testers are executables which load an SWF, generate events (both user or system) on it, and check its state using a standard interface.

To help this process a MovieTester class is defined in the testsuite/MovieTester.{h,cpp} files; see Doxygen documentation for more information.

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.

Chapter 4. Adding New ActionScript Class