~ubuntu-branches/ubuntu/saucy/gnash/saucy-proposed

« back to all changes in this revision

Viewing changes to doc/C/refmanual/internals.xml

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<chapter id="internals">
 
2
  <title>Software Internals</title>
 
3
  
 
4
  <sect1 id="tour">
 
5
    <title>A Tour of Gnash</title>
 
6
    
 
7
    <para>
 
8
      The top level of Gnash has several libraries, <emphasis>libgnashbase</emphasis>,
 
9
      <emphasis>libgnashserver</emphasis>,
 
10
      <emphasis>libgnashmedia</emphasis>,
 
11
      <emphasis>libgnashamf</emphasis> and
 
12
      <emphasis>libgnashbackend</emphasis>. There are several utility programs 
 
13
      included for debug parsing and processing of SWF movie files,
 
14
      and other useful utilities for examining local Shared Objects and
 
15
      sniffing LocalConnections.
 
16
    </para>
 
17
    
 
18
    <sect2 id="The Libraries">
 
19
      <title>The Libraries</title>
 
20
      
 
21
      <sect3 id="libbase">
 
22
        <title>libgnashbase</title>
 
23
        
 
24
        <para>
 
25
          Libgnashbase contains support classes used by the rest of the
 
26
          code.This library has no dependencies on any of the other
 
27
          &app; libraries.
 
28
        </para>
 
29
 
 
30
        <para>
 
31
          &app; makes heavy use of smart pointers, so memory allocations
 
32
          are freed up automatically by the interpreter. Both STL and
 
33
          Boost smart pointers are used.
 
34
        </para> 
 
35
      </sect3>
 
36
      
 
37
      <sect3 id="libgnashserver">
 
38
        <title>libgnashserver</title>
 
39
        <para>
 
40
          Libgnashserver is the guts of the interpreter itself. This is where
 
41
          the main code for the interpreter lives. Includes in
 
42
          libserver are the two support libraries for the parser and
 
43
          the core of the virtual machine.
 
44
        </para>
 
45
      </sect3>
 
46
 
 
47
      <sect3 id="libgnashmedia">
 
48
        <title>libgnashmedia</title>
 
49
        <para>
 
50
                Libgnashmedia handles Gnash's audio and video capabilities,
 
51
                dealing with streamed video and sound as well as decoding
 
52
                embedded media frames. Besides the standard SWF formats
 
53
                FLV, MPEG4, Nellymoser, ADPCM, MP3 and RAW, &app; can 
 
54
                decode other formats supports by gstreamer or ffmpeg, 
 
55
                including the free OGG container and free codecs.
 
56
        </para>
 
57
      </sect3>
 
58
 
 
59
      <sect3 id="libgnashamf">
 
60
        <title>libgnashamf</title>
 
61
        <para>
 
62
          AMF is the data format used internally by SWF files. This is
 
63
          Gnash's support library to handle AMF data. This is used by
 
64
          the ActionScript classes SharedObject and
 
65
          LocalConnection. This is also used by the NetStream class
 
66
          when using thre RTMP streaming network protocol.
 
67
        </para>
 
68
      </sect3>
 
69
      
 
70
      <sect3 id="libgnashbackend">
 
71
        <title>libgnashbackend</title>
 
72
        
 
73
        <para>
 
74
          Libgnashbackend is a library containing the rendering
 
75
          code that glues this display to the Gnash. Supported
 
76
          rendering backends are OpenGL, Cairo, and AGG.
 
77
        </para>
 
78
      </sect3>
 
79
 
 
80
      <sect3 id="libgnashpluin">
 
81
        <title>libgnashplugin</title>
 
82
        
 
83
        <para>
 
84
          Libgnashplugin is the Mozilla/Firefox plugin.
 
85
        </para> 
 
86
      </sect3>
 
87
 
 
88
      <sect3 id="libklashpart">
 
89
        <title>libklashpart</title>
 
90
        
 
91
        <para>
 
92
          Libklashpart is the Konqueror plugin.
 
93
        </para> 
 
94
      </sect3>
 
95
    </sect2>
 
96
 
 
97
 
 
98
    <sect2 id="apps">
 
99
      <title>The Applications</title>
 
100
      
 
101
      <para>
 
102
            There are currently a few standalone programs in Gnash,
 
103
        which serve either to assist with Gnash development or to play SWF
 
104
        movies.
 
105
      </para>
 
106
 
 
107
      <sect3 id="Gnash">
 
108
        <title>The Standalone Player</title>
 
109
        
 
110
        <para>
 
111
          This is the standalone OpenGL backend used to play
 
112
          movies. There are several command line options and keyboard
 
113
          control keys used by Gnash.
 
114
        </para>
 
115
 
 
116
      </sect3>
 
117
 
 
118
      <sect3 id="processor">
 
119
        <title>Gprocessor</title>
 
120
        
 
121
        <para>
 
122
          Gprocessor is used to print out the actions (using the -va
 
123
          option) or the parsing (using the -vp option) of a SWF
 
124
          movie. It is also used to produce the <emphasis>.gsc</emphasis>
 
125
          files that Gnash uses to cache data, thereby speeding up the
 
126
          loading of files.
 
127
        </para>
 
128
 
 
129
      </sect3>
 
130
      <sect3 id="soldumper">
 
131
        <title>SOLdumper</title>
 
132
        
 
133
        <para>
 
134
          SOLDumper is a utility program used to find and dump the
 
135
          content of <emphasis>Local Shared Objects</emphasis>, also
 
136
          called &quot;Flash Cookies&quot; by some.
 
137
        </para>
 
138
 
 
139
      </sect3>
 
140
      <sect3 id="dumpshm">
 
141
        <title>Dumpshm</title>
 
142
        
 
143
        <para>
 
144
          Dumpshm is a program used to find and dump the contents of
 
145
          the <emphasis>LocalConnection</emphasis> shared memory segment.
 
146
        </para>
 
147
 
 
148
      </sect3>
 
149
    </sect2>
 
150
    
 
151
    <sect2 id="plugin">
 
152
      <title>The Plugin</title>
 
153
 
 
154
      <para>
 
155
        The plugin is designed to work within Mozilla or Firefox,
 
156
        although there is Konqueror support as well. The plugin uses
 
157
        the Mozilla plugin API (NPAPI) to be cross platform, and is
 
158
        portable, as well as being well integrated into Mozilla based
 
159
        browsers.
 
160
      </para>
 
161
 
 
162
      <sect3 id="pluginstatus">
 
163
        <title>Current Implementation</title>
 
164
        <para>
 
165
          The plugin works in a
 
166
          fashion similar to MozPlugger: the standalone player
 
167
          is used instead of using a thread. This gets around the
 
168
          issue of having to maintain a separate player to support the
 
169
          plugin. It also gets around the other issues that Gnash
 
170
          itself is not thread safe at this time.
 
171
        </para>
 
172
        <para>
 
173
          As of Jan, 2007, streaming video, ala &quot;YouTube&quot;
 
174
          works, along with other video sharing sites.
 
175
        </para>
 
176
      </sect3>
 
177
 
 
178
      <sect3 id="gui">
 
179
        <title>GUI Support</title>
 
180
 
 
181
        <para>
 
182
          Any plugin that wants to display in a browser window needs
 
183
          to be tied into the windowing system of the platform being
 
184
          used. On GNU/Linux systems, Firefox is a GTK2+ application.
 
185
          There is also KDE support through the use of the Klash
 
186
          plugin.
 
187
        </para>
 
188
 
 
189
        <para>
 
190
          Gnash can use either several different GUI toolkits to create the window,
 
191
          and to handle events for the standalone player.
 
192
        </para>
 
193
        
 
194
        <para>
 
195
          The SDL version is more limited, but runs on all
 
196
          platforms, including win32. It has no support for event
 
197
          handling, which means mouse clicks, keyboard presses, and
 
198
          window resizing doesn't work. I personally find the default
 
199
          event handler slow and unresponsive. Gnash has support to
 
200
          use fast events, (currently not enabled) which is an SDL
 
201
          hack using a background thread to pump events into the SDL
 
202
          event queue at a much higher rate.
 
203
        </para>
 
204
 
 
205
        <para>
 
206
          There are a variety of development libraries that build a GUI
 
207
          widget system on top of SDL and OpenGL. The use of these to
 
208
          add menus and dialog boxes to the SDL version is being
 
209
          considered. 
 
210
        </para>
 
211
 
 
212
        <para>
 
213
          The GTK support is currently the most functional, and the
 
214
          best integrated into Firefox. The performance of this
 
215
          version is better than the SDL version because of the more
 
216
          efficient event handling within GTK. For the best end user
 
217
          experience, use the GTK enabled version.
 
218
        </para>
 
219
 
 
220
        <para>
 
221
          GTK also allows Gnash to have menus and dialog
 
222
          boxes. Currently this is only being utilized in a limited
 
223
          fashion for now. There is a right mouse button menu that
 
224
          allows the user to control the movie being player the same
 
225
          way the existing keyboard commands do.
 
226
        </para>
 
227
 
 
228
      </sect3>
 
229
      
 
230
      <sect3 id="mozplugger">
 
231
        <title>Mozplugger</title>
 
232
 
 
233
        <para>
 
234
          <ulink type="http"
 
235
         url="http://mozplugger.mozdev.org/">Mozplugger</ulink> is a
 
236
          <emphasis>Mozilla/Firefox</emphasis> plugin that uses external
 
237
          programs to play video, audio, and other multimedia content
 
238
          in the browser. With some support added to the external
 
239
          application, it's possible to force the external program to
 
240
          use the internal window in the browser where this plugin is
 
241
          supposed to display. This enables one to then run the
 
242
          standalone player and display its output in the browser.
 
243
        </para>
 
244
 
 
245
        <para>
 
246
          While this is not an optimal solution, it does enable one to
 
247
          use Gnash as the SWF player when browsing. The main issue
 
248
          appears to be that the SWF movie being played doesn't get
 
249
          any mouse or keyboard input. That may be a mozplugger
 
250
          configuration issue, however.
 
251
        </para>
 
252
 
 
253
        <para>
 
254
          Use of MozPlugger is obsolete now that the Gnash plugin
 
255
          works. Still, this may be useful still on some platforms.
 
256
        </para>
 
257
 
 
258
        <para>
 
259
          Add this to your <emphasis>$(HOME)/.mozilla/mozpluggerrc</emphasis>
 
260
          file to enable this:
 
261
 
 
262
          <programlisting>
 
263
            application/x-shockwave-flash:swf:Shockwave Gnash
 
264
        nokill embed noisy ignore_errors hidden fill swallow(Gnash) loop: gnash -v "$file" -x $window
 
265
        : gnash -v "$file" -x $window
 
266
          </programlisting>
 
267
        </para>
 
268
 
 
269
        <para>
 
270
          Once this is added, you must delete the
 
271
          <emphasis>$(HOME)/.mozilla/firefox/pluginreg.dat</emphasis> file to
 
272
          force Firefox to register the plugins again. This is an
 
273
          ASCII text file, so if the patch has been added correctly,
 
274
          you'll see an entry for <emphasis>swf</emphasis> files after it is
 
275
          recreated. You will need to restart Firefox to recreate this
 
276
          file.
 
277
        </para>
 
278
 
 
279
        <para>
 
280
          This file is not recreated immediately when restarting
 
281
          Firefox, but waits till the first time a plugin is used. You
 
282
          can force creation of this file by typing
 
283
          <emphasis>about:plugins</emphasis> into the URL entry of the browser
 
284
          window. The output will also contain information about the
 
285
          mozplugger. You should see an entry for Gnash now.
 
286
        </para>
 
287
        
 
288
      </sect3>
 
289
 
 
290
      <sect3 id="Klash">
 
291
        <title>Klash</title>
 
292
        <para>
 
293
          Klash is MozPlugger type support for KDE's Konqueror web
 
294
          browser. Klash makes Gnash a <emphasis>kpart</emphasis>, so it's
 
295
          integrated into KDE better than when using MozPlugger. Klash
 
296
          uses the standalone player, utilizing Gnash's "-x" window
 
297
          plugin command line option.
 
298
        </para>
 
299
 
 
300
        <para>
 
301
          By default, Klash is not built. To enable building Klash,
 
302
          use the <emphasis>--enable-klash</emphasis> option when
 
303
          configuring. Other than installing, there is nothing else
 
304
          that needs to be done to install Klash.
 
305
        </para>
 
306
      </sect3>
 
307
 
 
308
    </sect2>
 
309
 
 
310
    &logging;
 
311
 
 
312
  </sect1>
 
313
 
 
314
  <sect1 id="soundhandlers">
 
315
    <title>Sound handling in Gnash</title>
 
316
 
 
317
    <para>
 
318
      When a SWF-file contains audio Gnash uses its sound handlers to play it.
 
319
      At the moment there are two sound handlers, but it is likely that more 
 
320
      will be made.
 
321
    </para>
 
322
 
 
323
    <para>
 
324
      There are two different settings related to sound support:
 
325
      <emphasis>pluginsound</emphasis> and <emphasis>sound</emphasis>. 
 
326
      This was done in order to allow the plugin to be independently 
 
327
      configured, for instance to block sound from advertisements.
 
328
    </para>
 
329
 
 
330
    <sect2 id="soundtypes">
 
331
      <title>Sound types</title>
 
332
      <para>
 
333
        Sounds can be divided into two groups: event-sounds and soundstreams.
 
334
        Event-sounds are contained in a single SWF frame, but the playtime can
 
335
        span multiple frames. Soundstreams can be (and normally are) divided
 
336
        between the SWF frames the soundstreams spans. This means that if a
 
337
        gotoframe-action jumps to a frame which contains data for a soundstream,
 
338
        playback of the stream can be picked up from there. 
 
339
      </para>
 
340
    </sect2>
 
341
 
 
342
     <sect2 id="soundparsing">
 
343
      <title>Sound parsing</title>
 
344
      <para>
 
345
        When Gnash parses a SWF-file, it creates a sound handler if possible
 
346
        and hands over the sounds to it. Since the event-sounds are contained 
 
347
        in one frame, the entire event-sound is retrieved at once, while a 
 
348
        soundstream maybe not be completely retrieved before the entire 
 
349
        SWF-file has been parsed. But since the entire soundstream doesn't need
 
350
        to be present when playback starts, it is not necessary to wait. 
 
351
      </para>
 
352
    </sect2>
 
353
 
 
354
    <sect2 id="soundplayback">
 
355
      <title>Sound playback</title>
 
356
      <para>
 
357
        When a sound is about to be played Gnash calls the sound handler, which
 
358
        then starts to play the sound and return. All the playing is done by
 
359
        threads (in both SDL and Gstreamer), so once 
 
360
        started the audio and graphics are not sync'ed with each other, which
 
361
        means that we have to trust both the graphic backend and the audio
 
362
        backend to play at correct speed. 
 
363
      </para>
 
364
    </sect2>
 
365
 
 
366
    <sect2 id="sdlsound">
 
367
      <title>The SDL sound backend</title>
 
368
      <para>
 
369
        The current SDL sound backend has replaced the original sound 
 
370
        handler, based on SDL_mixer, which by design had some limitations, 
 
371
        making it difficult to implement needed features such as support 
 
372
        for soundstreams. 
 
373
        The SDL sound backend supports both event-sounds and soundstreams,
 
374
        using Gnash's internal ADPCM, and optionally MP3 support, using
 
375
        FFMPEG.
 
376
        When it receives sound data it is stored without being decoded, unless
 
377
        it is ADPCM, which is decoded in the parser. When playing, backend
 
378
        relies on a function callback for retrieving output sound, which is 
 
379
        decoded and re-sampled if needed, and all sound output is mixed together.
 
380
        The current SDL sound backend was made since Gnash needed a working
 
381
        sound backend as soon as possible, and since the gstreamer backend at
 
382
        the time suffered from bugs and/or lack of features in gstreamer. The
 
383
        result was the most complete and best sound handler so far.
 
384
        The advantages of the SDL sound handler is speed, and ease of use,
 
385
        while its only real disadvantage is that it has to be compiled with
 
386
        MP3 support, which some Linux distributions will probably not like...
 
387
      </para>
 
388
    </sect2>
 
389
 
 
390
   <sect2 id="gstreamer">
 
391
      <title>The Gstreamer backend</title>
 
392
      <para>
 
393
        The Gstreamer backend, though not complete, supports both soundstreams
 
394
        and event-sounds. When receiving sound data it stores it compressed,
 
395
        unless if it's ADPCM event-sounds, which it decodes by the parser.
 
396
        When the playback starts, the backend sets up a
 
397
        Gstreamer bin containing a decoder (and other things needed) and places
 
398
        it in a Gstreamer pipeline, which plays the audio. All the sound data is
 
399
        not passed at once, but in small chunks, and via callbacks the
 
400
        pipeline gets fed. The advantages of the Gstreamer backend is that it
 
401
        supports both kinds of sound, it avoids all the legal MP3-stuff, and it
 
402
        should be relatively easy to add VORBIS support. The drawbacks are that
 
403
        it has longer "reply delay" when starting the playback of a sound, and
 
404
        it suffers under some bugs in Gstreamer that are yet to be fixed. 
 
405
      </para>
 
406
    </sect2>
 
407
 
 
408
    <sect2 id="audio-future">
 
409
      <title>Future audio backends</title>
 
410
      <para>
 
411
        It would probably be desirable to make more backends in the future,
 
412
        either because other and better backend systems are brought to our
 
413
        attention, or perhaps because an internal sound handling is better
 
414
        suited for embedded platform with limited software installed. 
 
415
      </para>
 
416
    </sect2>
 
417
 
 
418
    <sect2 id="gstreamer-details">
 
419
      <title>Detailed description of the Gstreamer backend</title>
 
420
      <para>
 
421
        Gstreamer uses pipelines, bins and elements. Pipelines are the
 
422
        main bin, where all other bins or elements are places. Visually the
 
423
        audio pipeline in Gnash looks like this: 
 
424
      </para>
 
425
 
 
426
      <programlisting>
 
427
         ___
 
428
        |Bin|_
 
429
        |___| \
 
430
         ___   \ _____       ____________
 
431
        |Bin|___|Adder|_____|Audio output|
 
432
        |___|   |_____|     |____________|
 
433
         ___   /
 
434
        |Bin|_/
 
435
        |___|
 
436
 
 
437
      </programlisting>
 
438
 
 
439
      <para>
 
440
        There is one bin for each sound which is being played. If a sound is
 
441
        played more the once at the same time, multiple bins will be made. The
 
442
        bins contains: 
 
443
      </para>
 
444
 
 
445
      <programlisting>
 
446
 
 
447
        |source|---|capsfilter|---|decoder|---|aconverter|---|aresampler|---|volume|
 
448
 
 
449
      </programlisting>
 
450
 
 
451
      <para>
 
452
        In the source element we place parts of the undecoded sound data, and
 
453
        when playing the pipeline will pull the data from the element. Via
 
454
        callbacks it is refilled if needed. In the capsfilter the data is
 
455
        labeled with the format of the data. The decoder (surprise!) decodes
 
456
        the data. The audioconverter converts the now raw sound data into a
 
457
        format accepted by the adder, all input to the adder must in the same
 
458
        format. The audio re-sampler re-samples the raw sound data into a sample
 
459
        accepted by the adder, all input to the adder must in the same
 
460
        sample rate. The volume element makes it possible to control the volume
 
461
        of each sound. 
 
462
      </para>
 
463
 
 
464
      <para>
 
465
        When a sound is done being played it emits a End-Of-Stream-signal
 
466
        (EOS), which is caught by an event-handler-callback, which then makes
 
467
        sure that the bin in question is removed from the pipeline. When a
 
468
        sound is told by Gnash to stop playback before it has ended playback,
 
469
        we do something (not yet finally implemented), which makes the bin emit
 
470
        an EOS, and the event-handler-callback will remove the sound from the
 
471
        pipeline. Unfortunately Gstreamer currently has a bug which causes the
 
472
        entire pipeline to stop playing when unlinking an element from the
 
473
        pipeline; so far no fix is known. 
 
474
      </para>
 
475
 
 
476
      <para>
 
477
        Gstreamer also contains a bug concerning linking multiple elements to
 
478
        the adder in rapid succession, which causes to adder to "die" and stop
 
479
        the playback. 
 
480
      </para>
 
481
    </sect2>
 
482
 
 
483
 
 
484
  </sect1>
 
485
 
 
486
  <sect1 id="testing">
 
487
    <title>Testing </title>
 
488
 
 
489
     <para>
 
490
       <link linkend="runtests">Instructions on running tests</link>
 
491
       can be found in the section on building Gnash.
 
492
     </para>
 
493
 
 
494
    <sect2 id="testtools">
 
495
      <title>Testing Tools</title>
 
496
 
 
497
      <para>
 
498
        Currently Gnash uses three other tools to help with
 
499
        testing. Two of these are free compilers for the SWF
 
500
        format. This lets us write simple test cases for Gnash to test
 
501
        specific features, and to see how the features operate.
 
502
      </para>
 
503
 
 
504
      <para>
 
505
        The primary compiler used at this time is <ulink type="http"
 
506
        url="http://ming.sf.net">Ming</ulink>. Since release 0.3,
 
507
        <emphasis>Ming</emphasis> includes a command-line compiler,
 
508
        <emphasis>makeswf</emphasis>. This allows test case development
 
509
        to be done entirely with free tools.
 
510
      </para>
 
511
      
 
512
      <para>
 
513
        The other tools are optional.  
 
514
        <ulink type="http"
 
515
               url="http://www.gnu.org/software/dejagnu">DejaGnu</ulink>
 
516
        is used to run multiple test cases in an automated
 
517
        manner. <emphasis>DejaGnu</emphasis> is used by many other <ulink
 
518
        type="http" url="http://www.gnu.org">GNU</ulink> projects like 
 
519
        <ulink type="http" url="http://gcc.gnu.org">GCC</ulink> and 
 
520
        <ulink type="http" url="http://www.samba.org">Samba</ulink>.
 
521
      </para>
 
522
      
 
523
    </sect2>
 
524
 
 
525
    <sect2 id="testcases">
 
526
      <title>Test Cases</title>
 
527
      
 
528
      <para>
 
529
        ActionScript test cases are located under testsuite/actionscript.all/;
 
530
        these are organized in one file for the ActionScript class.
 
531
        Other Ming-generated tests are under testsuite/ming-misc.all/;
 
532
        these are typically used to test specific tag types.
 
533
        Full movies are located in testsuite/movies.all/ and
 
534
        sample movies are found in testsuite/samples/.
 
535
        Other directories in testsuite/ are (or shall be) used for other
 
536
        kind of tests.
 
537
      </para>
 
538
      
 
539
    </sect2>
 
540
 
 
541
    <sect2 id="writeastests">
 
542
      <title>Writing ActionScript Tests</title>
 
543
 
 
544
      <para>
 
545
        Writing ActionScript tests is very simple. The
 
546
        <emphasis>makeswf</emphasis> compiler makes use of the C preprocessor,
 
547
        thus allowing the inclusion of definitions for macros and external 
 
548
        files. We use these feature to provide common utilities
 
549
        for test units.
 
550
      </para>
 
551
      
 
552
      <para>
 
553
        Each test unit sets an <emphasis>rcsid</emphasis> variable, includes the
 
554
        <emphasis>check.as</emphasis> file and performs some checks using
 
555
        the provided macros. Here is an example:
 
556
        
 
557
        <programlisting>
 
558
 
 
559
          // This variable will be used by check.as
 
560
          // to show testcase info as part of the test runs.
 
561
          rcsid="Name and version of this testcase, usually the RCS id";
 
562
          
 
563
          #include "check.as"
 
564
          
 
565
          // Test object creation
 
566
          check(new Object() instanceOf Object);
 
567
          
 
568
          // Test parseInt
 
569
          check(isNaN(parseInt('none')));
 
570
 
 
571
          // Test assignment
 
572
          var a = 1;
 
573
          check_equals(a, 1);
 
574
          
 
575
          // .. your tests here ...
 
576
        </programlisting>
 
577
      </para>
 
578
      
 
579
      <para>
 
580
        The check(expr) macro will <emphasis>trace</emphasis> PASSED or FAILED
 
581
        together with the expression being evaluated and the line number
 
582
        of the check. This is the format expected by DejaGnu.
 
583
      </para>
 
584
 
 
585
      <para>
 
586
        The <emphasis>check_equals(obtained, expected)</emphasis> macro uses equality operator
 
587
        <emphasis>==</emphasis> to check for equality. When possible, use of the
 
588
        <emphasis>check_equals()</emphasis> macro is preferred over <emphasis>check()</emphasis>
 
589
        because it shows what the actual result was in case of a failure. 
 
590
      </para>
 
591
      
 
592
      <para>
 
593
        Additionally, the check.as file provides a transparent way to send
 
594
        results to a TextField rather then using trace. This is very useful
 
595
        when you use a SWF player without tracing support.
 
596
      </para>
 
597
      
 
598
      <para>
 
599
        Test units are built by running <emphasis>make TestName-v#.swf</emphasis>.
 
600
        This will use TestName.as as source and the value of # as target version.
 
601
        Allowed target version are from 5 to 8 (inclusive).
 
602
      </para>
 
603
      
 
604
      <para>
 
605
        Note that if you get a syntax error from the compiler, the line
 
606
        number will refer to the pre-processed file. This file is called
 
607
        <emphasis>TestName.as.pp</emphasis> or <emphasis>TestName-v#.swf.frame#.pp</emphasis>
 
608
        (depending on Ming version) and it's not thrown away by
 
609
        <emphasis>makeswf</emphasis> to make debugging easier.
 
610
      </para>
 
611
 
 
612
      <para>
 
613
        Sometimes an expression is only supported by a specific SWF
 
614
        version, or it's evaluated differently by different SWF versions.
 
615
        For this purpose the framework provides an OUTPUT_VERSION macro
 
616
        that you can use to switch code based on output version. For example:
 
617
 
 
618
        <programlisting>
 
619
 
 
620
          #if OUTPUT_VERSION &gt;= 7
 
621
          check(_root.getSWFVersion == OUTPUT_VERSION);
 
622
          #endif
 
623
          
 
624
        </programlisting>
 
625
      </para>
 
626
    </sect2>
 
627
 
 
628
    <sect2 id="writemingtests">
 
629
      <title>Writing Ming-based self-contained SWF tests</title>
 
630
 
 
631
      <para>
 
632
        Ming-based test cases are located in testsuite/misc-ming.all
 
633
        and contain a test generator and a test runner.
 
634
        The test generator (usually a C program) is used to produce the SWF 
 
635
        file, while the test runner (a C++ program) will run it using a 
 
636
        MovieTester class.
 
637
        Note that only the test generator needs Ming, not the test
 
638
        runner, so if Ming isn't installed on the user's host,
 
639
        the test cases can still be run as long as SWF has been distributed.
 
640
      </para>
 
641
      
 
642
      <para>
 
643
        Producing tests using Ming has the advantage that you can easily see
 
644
        and modify the full source code for the SWF movie, and you can use
 
645
        some <link linkend="ming_testgenerator_facilities">facilities</link>
 
646
        provided by the Gnash testing framework to easily run tests.
 
647
      </para>
 
648
 
 
649
      <para>
 
650
        For generic Ming API documentation, see <ulink type="http"
 
651
        url="http://www.libming.org/">http://www.libming.org</ulink>. 
 
652
      </para>
 
653
 
 
654
      <sect3 id="ming_testgenerator_facilities">
 
655
      <title>Using Ming-based test generators facilities</title>
 
656
 
 
657
      <para>
 
658
        Ming-based test generator facilities, which might be moved into
 
659
        a loadable SWF in the future, can be currently used by your test
 
660
        generator by including the ming_utils.h file and calling the
 
661
        appropriate functions.
 
662
      </para>
 
663
 
 
664
      <para>
 
665
        The most useful facility provided for Ming-based SWF test generators
 
666
        is a Dejagnu-like TestState ActionScript class.
 
667
        In order to use this facility you must call 'add_dejagnu_functions()'
 
668
        right after Movie creation.
 
669
        The function takes an SWFMovie object and some parameters specifying
 
670
        depth and location of the "visual" trace textfield; it instantiates
 
671
        a global 'TestState' ActionScript object to keep track of test's state.
 
672
      </para>
 
673
 
 
674
      <para>
 
675
        You will <emphasis>not</emphasis> need to directly invoke the
 
676
        TestState object created by the 'add_dejagnu_functions()' routine,
 
677
        rather you will be using C macros hiding its complexity:
 
678
        
 
679
        <programlisting>
 
680
 
 
681
        check(SWFMovie mo, const char* expr)
 
682
 
 
683
                Evaluate an ActionScript expression.
 
684
 
 
685
        xcheck(SWFMovie mo, const char* expr)
 
686
 
 
687
                Evaluate an ActionScript expression.
 
688
                A failure is expected
 
689
                (for cases where the call exposes a known bug).
 
690
 
 
691
        check_equals(SWFMovie mo, const char* obtained, const char* expected)
 
692
 
 
693
                Evaluate an ActionScript expression against an expected output.
 
694
 
 
695
        xcheck_equals(SWFMovie mo, const char* obtained, const char* expected)
 
696
 
 
697
                Evaluate an ActionScript expression against an expected output.
 
698
                A failure is expected (for cases where the call exposes a known bug).
 
699
 
 
700
        print_tests_summary(SWFMovie mo)
 
701
 
 
702
                This will print a summary of tests run, and should be
 
703
                called as the last step in your SWF generator.
 
704
        </programlisting>
 
705
        
 
706
      </para>
 
707
      
 
708
      <para>
 
709
        Test cases generated using Ming and the provided
 
710
        <link linkend="ming_testgenerator_facilities">facilities</link>
 
711
        will be self-contained, which means they can be used as tests
 
712
        by simply running them with whatever Player you might have.
 
713
        Any 'check' or 'check_equals' result will be both traced and
 
714
        printed in a textfield. You can use 'gprocessor -v' to have
 
715
        Gnash use them as tests.
 
716
      </para>
 
717
      
 
718
      <para>
 
719
        See section <link linkend="writing_test_runners">Writing Test Runners</link>
 
720
        for information about writing SWF test runners.
 
721
      </para>
 
722
      </sect3>
 
723
    </sect2>
 
724
    
 
725
    <sect2 id="writing_dejagnu_so_tests">
 
726
      <title>Writing self-contained SWF tests with other compilers</title>
 
727
      
 
728
      <para>
 
729
        If you want/need to use a different compiler for your test cases (there's
 
730
        plenty of open source tools for generating SWF out there), you can still
 
731
        make use of a loadable SWF utility provided as part of the Gnash testsuite
 
732
        to let your test consistent with the rest of the suite.
 
733
      </para>
 
734
      
 
735
      <para>
 
736
        The loadable module is called <emphasis>Dejagnu.swf</emphasis> and is built during
 
737
        <emphasis>make check</emphasis> under testsuite/misc-ming.all. In order to use it
 
738
        you will need to load it into your SWF. We currently load it with an IMPORT
 
739
        tag for our ActionScript based test cases, but you can probably also use
 
740
        loadMovie or whatever works in the target SWF you're generating. Just make
 
741
        sure that the module is initialized before using it. You can check this by
 
742
        inspecting the <emphasis>dejagnu_module_initialized</emphasis> variable, which will
 
743
        be set to 'true' when all initialization actions contained in the
 
744
        <emphasis>Dejagnu.swf</emphasis> file are executed. 
 
745
      </para>
 
746
      
 
747
      <para>
 
748
        Once the module is loaded you will be able to invoke the following functions,
 
749
        all registered against the <emphasis>_root</emphasis> sprite (effects of <emphasis>_lockroot</emphasis>
 
750
        untested):
 
751
        <programlisting>
 
752
          
 
753
          check(expression, [message]);
 
754
          
 
755
          Evaluate the expression.
 
756
          Trace result (PASSED: expression / FAILED: expression).
 
757
          If fails, *visually* trace the failure.
 
758
          If second argument is given, it will be used instead of
 
759
          'expression' for printing results.
 
760
          
 
761
          check_equals(obtained, expected)
 
762
          
 
763
          Evaluate an expression against an expected output.
 
764
          Trace result (PASSED: obtained == expected / FAILED: expected X, obtained Y)
 
765
          If fails, *visually* trace the failure.
 
766
          
 
767
          xcheck(expression, [message]);
 
768
          
 
769
          Evaluate the expression.
 
770
          Trace result (XPASSED: expression / XFAILED: expression).
 
771
          If fails, *visually* trace the failure.
 
772
          If second argument is given, it will be used instead of
 
773
          'expression' for printing results.
 
774
          
 
775
          xcheck_equals(obtained, expected)
 
776
          
 
777
          Evaluate an expression against an expected output.
 
778
          Trace result (XPASSED: obtained == expected / XFAILED: expected X, obtained Y)
 
779
          If fails, *visually* trace the failure.
 
780
          
 
781
          note(string)
 
782
          
 
783
          Print string, both as debugging and *visual* trace.
 
784
          
 
785
          totals()
 
786
          
 
787
          Print a summary of tests run, both as debugging and *visual* traces.
 
788
          
 
789
        </programlisting>
 
790
      </para>
 
791
      
 
792
      <para>
 
793
        Visual traces are lines of text pushed to a textarea defined
 
794
        by the <emphasis>Dejagnu.swf</emphasis> module. The textarea is
 
795
        initially placed at <emphasis>0, 50</emphasis> and is
 
796
        <emphasis>600x800</emphasis> in size. You can resize/move the clip
 
797
        after loading it. Also, you can completely make the clip
 
798
        invisible if that bothers you. The important thing is the
 
799
        <emphasis>debugging</emphasis> trace (call to the trace
 
800
        function). The latter will be used by the testing framework. 
 
801
      </para>
 
802
      
 
803
      <para>
 
804
        See section <link linkend="writing_test_runners">Writing Test Runners</link>
 
805
        for information about writing a test runners for your self-contained tests.
 
806
      </para>
 
807
      
 
808
    </sect2>
 
809
    
 
810
    <sect2 id="writing_test_runners">
 
811
      <title>Writing Test Runners</title>
 
812
      
 
813
      <para>
 
814
        Test runners are executables that run one or more tests,
 
815
        writing results in Dejagnu form to standard output.
 
816
      </para>
 
817
      
 
818
      <para>
 
819
        The Dejagnu form uses a standard set of labels when printing test 
 
820
        results.  These are:
 
821
        <informaltable frame="all">
 
822
          <?dbhtml table-width="75%" ?>
 
823
          <tgroup cols="2">
 
824
            <thead>
 
825
              <row>
 
826
                <entry valign="top">
 
827
                  <para>Label</para>
 
828
                </entry>
 
829
                <entry valign="top">
 
830
                  <para>Meaning</para>
 
831
                </entry>
 
832
              </row>
 
833
            </thead>
 
834
            <tbody>
 
835
              <row>
 
836
                <entry valign="top" align="left">
 
837
                  <para>PASSED</para>
 
838
                </entry>
 
839
                <entry valign="top" align="left">
 
840
                  <para>The test succeeded.</para>
 
841
                </entry>
 
842
              </row>
 
843
              <row>
 
844
                <entry valign="top" align="left">
 
845
                  <para>FAILED</para>
 
846
                </entry>
 
847
                <entry valign="top" align="left">
 
848
                  <para>The test failed.</para>
 
849
                </entry>
 
850
              </row>
 
851
              <row>
 
852
                <entry valign="top" align="left">
 
853
                  <para>XPASSED</para>
 
854
                </entry>
 
855
                <entry valign="top" align="left">
 
856
                  <para>The test succeeded, but was expected to fail.</para>
 
857
                </entry>
 
858
              </row>
 
859
              <row>
 
860
                <entry valign="top" align="left">
 
861
                  <para>XFAILED</para>
 
862
                </entry>
 
863
                <entry valign="top" align="left">
 
864
                  <para>The test failed, and was expected to fail.</para>
 
865
                </entry>
 
866
              </row>
 
867
              <row>
 
868
                <entry valign="top" align="left">
 
869
                  <para>UNRESOLVED</para>
 
870
                </entry>
 
871
                <entry valign="top" align="left">
 
872
                  <para>The results of the test could not be automatically 
 
873
                  parsed.</para>
 
874
                </entry>
 
875
              </row>
 
876
              <row>
 
877
                <entry valign="top" align="left">
 
878
                  <para>UNTESTED</para>
 
879
                </entry>
 
880
                <entry valign="top" align="left">
 
881
                  <para>This test case is not complete.</para>
 
882
                </entry>
 
883
              </row>
 
884
              <row>
 
885
                <entry valign="top" align="left">
 
886
                  <para>UNSUPPORTED</para>
 
887
                </entry>
 
888
                <entry valign="top" align="left">
 
889
                  <para>The test case relies on a conditional feature which 
 
890
                  is not present in your environment.</para>
 
891
                </entry>
 
892
              </row>
 
893
            </tbody>
 
894
          </tgroup>
 
895
        </informaltable>
 
896
      </para>
 
897
      
 
898
      <para>
 
899
        The following labels may also appear:
 
900
        <informaltable frame="all">
 
901
          <?dbhtml table-width="75%" ?>
 
902
          <tgroup cols="2">
 
903
            <thead>
 
904
              <row>
 
905
                <entry valign="top">
 
906
                  <para>Label</para>
 
907
                </entry>
 
908
                <entry valign="top">
 
909
                  <para>Meaning</para>
 
910
                </entry>
 
911
              </row>
 
912
            </thead>
 
913
            <tbody>
 
914
              <row>
 
915
                <entry valign="top" align="left">
 
916
                  <para>ERROR</para>
 
917
                </entry>
 
918
                <entry valign="top" align="left">
 
919
                  <para>There was a serious error in running the test. </para>
 
920
                </entry>
 
921
              </row>
 
922
              <row>
 
923
                <entry valign="top" align="left">
 
924
                  <para>WARNING</para>
 
925
                </entry>
 
926
                <entry valign="top" align="left">
 
927
                  <para>There may have been a problem with running the
 
928
                  test.</para>
 
929
                </entry>
 
930
              </row>
 
931
              <row>
 
932
                <entry valign="top" align="left">
 
933
                  <para>NOTE</para>
 
934
                </entry>
 
935
                <entry valign="top" align="left">
 
936
                  <para>There was some additional information given about
 
937
                  the test.</para>
 
938
                </entry>
 
939
              </row>
 
940
            </tbody>
 
941
          </tgroup>
 
942
        </informaltable>
 
943
      </para>
 
944
      
 
945
      <sect3 id="generic_test_runner">
 
946
        <title>Using the generic test runner for self-contained SWF tests</title>
 
947
        
 
948
        <para>
 
949
          The simplest test runner is one that simply invokes Gnash
 
950
          in verbose mode against a self-contained SWF test movie.
 
951
          Self-contained SWF test movies are the ones that print
 
952
          the PASSED/FAILED etc. lines using ActionScript (traces).
 
953
          By invoking Gnash in verbose mode this movie will behave
 
954
          as a compliant "Test Runner".
 
955
        </para>
 
956
        
 
957
        <para>
 
958
          A generator for simple test runners can be found in
 
959
          <emphasis>testsuite/generic-testrunner.sh</emphasis>.
 
960
          The script can be invoked by passing it <emphasis>$(top_builddir)</emphasis>
 
961
          as the first argument and the name of the SWF file (without the path)
 
962
          as the second argument. This will create a specific runner for your
 
963
          test in the current build directory.
 
964
          A simple Makefile.am rule for doing this follows:
 
965
          <programlisting>
 
966
            MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
 
967
            sh $(srcdir)/../generic-testrunner.sh $(top_builddir) MyTest.swf > $@
 
968
            chmod +x $@
 
969
          </programlisting>
 
970
        </para>
 
971
        
 
972
        <para>
 
973
          By default, the generated test runner will play the movie up to the
 
974
          last frame. If you want the movie to be played more then once (maybe
 
975
          because you're exactly testing loop features) you can use the -r switch
 
976
          to the generic-testrunner.sh call. The following will create a runner
 
977
          playing the movie twice:
 
978
          <programlisting>
 
979
            MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
 
980
            sh $(srcdir)/../generic-testrunner.sh -r2 $(top_builddir) MyTest.swf > $@
 
981
            chmod +x $@
 
982
          </programlisting>
 
983
        </para>
 
984
        
 
985
        <para>
 
986
          In case your test movie stops before the last frame, or you want to control the
 
987
          exact number of times to call the frame advancement routine, you can use the 
 
988
          -f switch to control that.
 
989
          <programlisting>
 
990
            MyTest-Runner: $(srcdir)/../generic-testrunner.sh MyTest.swf
 
991
            sh $(srcdir)/../generic-testrunner.sh -f10 $(top_builddir) MyTest.swf > $@
 
992
            chmod +x $@
 
993
          </programlisting>
 
994
          When both -f and -r are given, the first exit condition reached will take effect.
 
995
        </para>
 
996
        
 
997
      </sect3>
 
998
      
 
999
      <sect3 id="writing_movie_testers">
 
1000
        <title>Writing Movie testers</title>
 
1001
        
 
1002
        <para>
 
1003
          There are some parts of Gnash that can NOT be tested
 
1004
          by only using ActionScript tests. Examples include: frame
 
1005
          advancements, actual actions execution, gui events and so on.
 
1006
        </para>
 
1007
        
 
1008
        <para>
 
1009
          In this case you might want to use the MovieTester class to
 
1010
          implement a C++ test runner. Be aware that you can <emphasis>mix</emphasis> tests in
 
1011
          the MovieTester-based class with <emphasis>self-contained</emphasis>
 
1012
          tests in the SWF file as long as you activate verbosity for
 
1013
          the debug logfile. This is done, for example, for the
 
1014
          DefineEditTextVariableNameTest.swf file. The corresponding
 
1015
          test runner (DefineEditTextVariableNameTest-Runner) is a C++
 
1016
          runner based on MovieTester class. If you run the runner you
 
1017
          see two kinds of test results: the ones coming from the ActionScript
 
1018
          engine, and the ones coming from the test runner. You can
 
1019
          distinguish between the two because the former contains an additional
 
1020
          timestamp and the latter does not. Also, you'll see two final
 
1021
          summaries for the two test sets. The 'make check' rule, which uses
 
1022
          the testsuite/simple.exp output parser as its work-horse, will
 
1023
          count test results from both test sets.
 
1024
        </para>
 
1025
        
 
1026
        
 
1027
        <para>
 
1028
          Movie testers are executables which load an SWF, generate events
 
1029
          (both user or system) on it, and check its state using
 
1030
          a standard interface.
 
1031
        </para>
 
1032
        
 
1033
        <para>
 
1034
          To help this process a MovieTester class is defined in the
 
1035
          testsuite/MovieTester.{h,cpp} files; see Doxygen documentation
 
1036
          for more information.
 
1037
        </para>
 
1038
        
 
1039
        <para>
 
1040
          Note that you do NOT need access to the SWF source code in order
 
1041
          to implement a Movie tester for it.  Some knowledge about the 
 
1042
          expected behavior suffices.
 
1043
        </para>
 
1044
      </sect3>
 
1045
    </sect2>
 
1046
  </sect1>
 
1047
  
 
1048
  &newasclass;
 
1049
    
 
1050
</chapter>
 
1051