[Swfdec] 9 commits - libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_audio_stream.c libswfdec/swfdec_audio_stream.h libswfdec/swfdec_cache.c libswfdec/swfdec_cached.c libswfdec/swfdec_cached.h libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_image.c libswfdec/swfdec_image.h libswfdec/swfdec_js.c libswfdec/swfdec_js_color.c libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_net_stream.h libswfdec/swfdec_scriptable.c libswfdec/swfdec_scriptable.h libswfdec/swfdec_sound.c libswfdec/swfdec_sound.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_types.h

Benjamin Otte company at kemper.freedesktop.org
Tue Jan 16 13:53:13 PST 2007


 libswfdec/Makefile.am             |    4 
 libswfdec/js/jsapi.c              |    6 -
 libswfdec/js/jsapi.h              |    6 -
 libswfdec/js/jsfun.h              |    2 
 libswfdec/js/jsinterp.c           |    2 
 libswfdec/js/jsobj.c              |    8 -
 libswfdec/js/jsobj.h              |    6 -
 libswfdec/js/jspubtd.h            |    4 
 libswfdec/js/jsscope.c            |    2 
 libswfdec/js/jsscope.h            |    2 
 libswfdec/swfdec_audio_stream.c   |   13 +-
 libswfdec/swfdec_audio_stream.h   |    2 
 libswfdec/swfdec_cache.c          |   11 +
 libswfdec/swfdec_cached.c         |  123 ++++++++++++++++++++++
 libswfdec/swfdec_cached.h         |   65 +++++++++++
 libswfdec/swfdec_edittext_movie.c |   44 +++----
 libswfdec/swfdec_image.c          |   65 ++++-------
 libswfdec/swfdec_image.h          |   32 ++---
 libswfdec/swfdec_js.c             |   41 +------
 libswfdec/swfdec_js.h             |    7 -
 libswfdec/swfdec_js_color.c       |    2 
 libswfdec/swfdec_js_movie.c       |  159 ++++++----------------------
 libswfdec/swfdec_movie.c          |   33 +++++
 libswfdec/swfdec_movie.h          |    9 -
 libswfdec/swfdec_net_stream.c     |    2 
 libswfdec/swfdec_net_stream.h     |    5 
 libswfdec/swfdec_scriptable.c     |  154 +++++++++++++++++++++++++++
 libswfdec/swfdec_scriptable.h     |   66 +++++++++++
 libswfdec/swfdec_sound.c          |  210 ++++++++++++++++++--------------------
 libswfdec/swfdec_sound.h          |   20 +--
 libswfdec/swfdec_swf_decoder.c    |    7 -
 libswfdec/swfdec_types.h          |    1 
 32 files changed, 698 insertions(+), 415 deletions(-)

New commits:
diff-tree 7005f0c65edf0177ea22cbb4514c7df1cbb099c1 (from 327ff632511845290eac307252b9e0441cb7fb43)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 22:38:58 2007 +0100

    get the codec out of SwfdecSound and into the audio objects
    
    rationale: I want to be able to use different codecs if that becomes
    interesting and as such keep the codec selection as close as possible to the
    decoding process

diff --git a/libswfdec/swfdec_audio_stream.c b/libswfdec/swfdec_audio_stream.c
index b1dd5e1..58e2175 100644
--- a/libswfdec/swfdec_audio_stream.c
+++ b/libswfdec/swfdec_audio_stream.c
@@ -38,7 +38,7 @@ swfdec_audio_stream_dispose (GObject *ob
   SwfdecAudioStream *stream = SWFDEC_AUDIO_STREAM (object);
 
   if (stream->decoder != NULL) {
-    SwfdecBuffer *buffer = swfdec_sound_finish_decoder (stream->sound, stream->decoder);
+    SwfdecBuffer *buffer = swfdec_audio_codec_finish (stream->codec, stream->decoder);
     stream->decoder = NULL;
     if (buffer)
       swfdec_buffer_unref (buffer);
@@ -68,7 +68,7 @@ swfdec_audio_stream_decode_one (SwfdecAu
     /* FIXME: with this method and mad not giving out full samples, we end up 
      * putting silence too early */
     if (frame->sound_block) {
-      buffer = swfdec_sound_decode_buffer (stream->sound, stream->decoder, frame->sound_block);
+      buffer = swfdec_audio_codec_decode (stream->codec, stream->decoder, frame->sound_block);
       if (buffer == NULL)
 	continue;
     } else {
@@ -79,7 +79,7 @@ swfdec_audio_stream_decode_one (SwfdecAu
     g_queue_push_tail (stream->playback_queue, buffer);
     return buffer;
   }
-  buffer = swfdec_sound_finish_decoder (stream->sound, stream->decoder);
+  buffer = swfdec_audio_codec_finish (stream->codec, stream->decoder);
   stream->decoder = NULL;
   stream->done = TRUE;
   if (buffer)
@@ -199,9 +199,12 @@ swfdec_audio_stream_new (SwfdecPlayer *p
   stream->sound = frame->sound_head;
   stream->playback_skip = frame->sound_skip;
   stream->current_frame = start_frame;
-  stream->decoder = swfdec_sound_init_decoder (stream->sound);
+  stream->codec = swfdec_codec_get_audio (stream->sound->format);
+  if (stream->codec)
+    stream->decoder = swfdec_audio_codec_init (stream->codec, 
+	stream->sound->width, stream->sound->original_format);
   if (stream->decoder)
-    stream->format = swfdec_sound_get_decoder_format (stream->sound, stream->decoder);
+    stream->format = swfdec_audio_codec_get_format (stream->codec, stream->decoder);
   swfdec_audio_add (SWFDEC_AUDIO (stream), player);
 
   return SWFDEC_AUDIO (stream);
diff --git a/libswfdec/swfdec_audio_stream.h b/libswfdec/swfdec_audio_stream.h
index af2a0ba..8758462 100644
--- a/libswfdec/swfdec_audio_stream.h
+++ b/libswfdec/swfdec_audio_stream.h
@@ -23,6 +23,7 @@
 #define _SWFDEC_AUDIO_STREAM_H_
 
 #include <libswfdec/swfdec_audio_internal.h>
+#include <libswfdec/swfdec_codec.h>
 
 G_BEGIN_DECLS
 
@@ -42,6 +43,7 @@ struct _SwfdecAudioStream
 
   SwfdecSprite *	sprite;		/* sprite we're playing back */
   SwfdecSound *		sound;	      	/* sound we're playing */
+  const SwfdecAudioCodec *codec;	/* codec used by this stream */
   gpointer		decoder;	/* decoder used for this frame */
   SwfdecAudioOut	format;		/* format used by decoder */
   unsigned int		playback_skip;	/* number of samples to skip at the beginning of queue */
diff --git a/libswfdec/swfdec_sound.c b/libswfdec/swfdec_sound.c
index 6e68f38..1620f5d 100644
--- a/libswfdec/swfdec_sound.c
+++ b/libswfdec/swfdec_sound.c
@@ -179,6 +179,7 @@ tag_func_define_sound (SwfdecSwfDecoder 
 SwfdecBuffer *
 swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioOut *format)
 {
+  const SwfdecAudioCodec *codec;
   gpointer decoder;
   SwfdecBuffer *tmp, *tmp2;
   guint sample_bytes;
@@ -193,19 +194,19 @@ swfdec_sound_get_decoded (SwfdecSound *s
   }
   if (sound->encoded == NULL)
     return NULL;
-  sound->codec = swfdec_codec_get_audio (sound->format);
-  if (sound->codec == NULL)
+  codec = swfdec_codec_get_audio (sound->format);
+  if (codec == NULL)
     return NULL;
 
-  decoder = swfdec_sound_init_decoder (sound);
+  decoder = swfdec_audio_codec_init (codec, sound->width, sound->original_format);
   if (decoder == NULL)
     return NULL;
-  sound->decoded_format = swfdec_sound_get_decoder_format (sound, decoder);
+  sound->decoded_format = swfdec_audio_codec_get_format (codec, decoder);
   sample_bytes = 2 * SWFDEC_AUDIO_OUT_N_CHANNELS (sound->decoded_format);
   /* FIXME: The size is only a guess */
   swfdec_cached_load (SWFDEC_CACHED (sound), sound->n_samples * sample_bytes);
-  tmp = swfdec_sound_decode_buffer (sound, decoder, sound->encoded);
-  tmp2 = swfdec_sound_finish_decoder (sound, decoder);
+  tmp = swfdec_audio_codec_decode (codec, decoder, sound->encoded);
+  tmp2 = swfdec_audio_codec_finish (codec, decoder);
   if (tmp == NULL) {
     if (tmp2) {
       tmp = tmp2;
@@ -307,10 +308,6 @@ tag_func_sound_stream_head (SwfdecSwfDec
       SWFDEC_WARNING ("unknown format %d", format);
       sound->format = format;
   }
-  sound->codec = swfdec_codec_get_audio (sound->format);
-  if (sound->codec == NULL) {
-    SWFDEC_WARNING ("No codec found for format %u", sound->format);
-  }
 
   return SWFDEC_STATUS_OK;
 }
@@ -460,49 +457,6 @@ tag_func_define_button_sound (SwfdecSwfD
   return SWFDEC_STATUS_OK;
 }
 
-gpointer 
-swfdec_sound_init_decoder (SwfdecSound * sound)
-{
-  g_assert (sound->decoded == NULL);
-
-  if (sound->codec)
-    return swfdec_audio_codec_init (sound->codec, sound->width, sound->original_format);
-  else
-    return NULL;
-}
-
-SwfdecBuffer *
-swfdec_sound_finish_decoder (SwfdecSound * sound, gpointer data)
-{
-  g_assert (sound->decoded == NULL);
-
-  if (sound->codec)
-    return swfdec_audio_codec_finish (sound->codec, data);
-  return NULL;
-}
-
-SwfdecBuffer *
-swfdec_sound_decode_buffer (SwfdecSound *sound, gpointer data, SwfdecBuffer *buffer)
-{
-  g_assert (sound->decoded == NULL);
-
-  if (sound->codec)
-    return swfdec_audio_codec_decode (sound->codec, data, buffer);
-  else
-    return NULL;
-}
-
-SwfdecAudioFormat
-swfdec_sound_get_decoder_format	(SwfdecSound *sound, gpointer data)
-{
-  g_assert (sound->decoded == NULL);
-
-  if (sound->codec)
-    return swfdec_audio_codec_get_format (sound->codec, data);
-  else
-    return sound->original_format;
-}
-
 /**
  * swfdec_sound_buffer_get_n_samples:
  * @buffer: data to examine
diff --git a/libswfdec/swfdec_sound.h b/libswfdec/swfdec_sound.h
index 7101675..7bf26ec 100644
--- a/libswfdec/swfdec_sound.h
+++ b/libswfdec/swfdec_sound.h
@@ -64,7 +64,6 @@ struct _SwfdecSound
   SwfdecCached		cached;
 
   SwfdecAudioFormat	format;			/* format in use */
-  const SwfdecAudioCodec *codec;		/* codec for this sound */
   gboolean		width;			/* TRUE for 16bit, FALSE for 8bit */
   SwfdecAudioOut	original_format;      	/* channel/rate information */
   unsigned int		n_samples;		/* total number of samples */
@@ -88,15 +87,6 @@ int tag_func_sound_stream_head (SwfdecSw
 int tag_func_start_sound (SwfdecSwfDecoder * s);
 int tag_func_define_button_sound (SwfdecSwfDecoder * s);
 
-gpointer		swfdec_sound_init_decoder	(SwfdecSound *		sound);
-SwfdecBuffer *		swfdec_sound_finish_decoder	(SwfdecSound *		sound,
-							 gpointer		data);
-SwfdecBuffer *		swfdec_sound_decode_buffer	(SwfdecSound *		sound,
-							 gpointer		data,
-							 SwfdecBuffer *		buffer);
-SwfdecAudioFormat	swfdec_sound_get_decoder_format	(SwfdecSound *		sound,
-							 gpointer		data);
-
 void			swfdec_sound_render		(SwfdecSound *		sound, 
 							 gint16 *		dest, 
 							 unsigned int		offset,
diff-tree 327ff632511845290eac307252b9e0441cb7fb43 (from 3fe8fea8d9594e3a6bc52152a2fe77629fa59063)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 21:56:23 2007 +0100

    use the cache
    
    makes SwfdecSound a SwfdecCached and decode sounds on demand. Has the nice
    side effect of keeping around the encoded sound should we later decide to
    extract it. (FIXME: make swfdec-extract do just that)

diff --git a/libswfdec/swfdec_sound.c b/libswfdec/swfdec_sound.c
index 061ba65..6e68f38 100644
--- a/libswfdec/swfdec_sound.c
+++ b/libswfdec/swfdec_sound.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -32,15 +32,26 @@
 #include "swfdec_sprite.h"
 #include "swfdec_swf_decoder.h"
 
-G_DEFINE_TYPE (SwfdecSound, swfdec_sound, SWFDEC_TYPE_CHARACTER)
+G_DEFINE_TYPE (SwfdecSound, swfdec_sound, SWFDEC_TYPE_CACHED)
+
+static void
+swfdec_sound_unload (SwfdecCached *cached)
+{
+  SwfdecSound * sound = SWFDEC_SOUND (cached);
+
+  if (sound->decoded) {
+    swfdec_buffer_unref (sound->decoded);
+    sound->decoded = NULL;
+  }
+}
 
 static void
 swfdec_sound_dispose (GObject *object)
 {
   SwfdecSound * sound = SWFDEC_SOUND (object);
 
-  if (sound->decoded)
-    swfdec_buffer_unref (sound->decoded);
+  if (sound->encoded)
+    swfdec_buffer_unref (sound->encoded);
 
   G_OBJECT_CLASS (swfdec_sound_parent_class)->dispose (object);
 }
@@ -49,8 +60,11 @@ static void
 swfdec_sound_class_init (SwfdecSoundClass * g_class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+  SwfdecCachedClass *cached_class = SWFDEC_CACHED_CLASS (g_class);
 
   object_class->dispose = swfdec_sound_dispose;
+
+  cached_class->unload = swfdec_sound_unload;
 }
 
 static void
@@ -67,8 +81,6 @@ tag_func_sound_stream_block (SwfdecSwfDe
   int n_samples;
   int skip;
 
-  /* for MPEG, data starts after 4 byte header */
-
   sound = SWFDEC_SOUND (s->parse_sprite->frames[s->parse_sprite->parse_frame].sound_head);
 
   if (!sound) {
@@ -114,8 +126,6 @@ tag_func_define_sound (SwfdecSwfDecoder 
   int type;
   int n_samples;
   SwfdecSound *sound;
-  unsigned int skip = 0;
-  SwfdecBuffer *orig_buffer = NULL;
 
   id = swfdec_bits_get_u16 (b);
   format = swfdec_bits_getbits (b, 4);
@@ -144,33 +154,68 @@ tag_func_define_sound (SwfdecSwfDecoder 
       /* fall through */
     case 3:
       sound->format = SWFDEC_AUDIO_FORMAT_UNCOMPRESSED;
-      orig_buffer = swfdec_bits_get_buffer (&s->b, -1);
+      sound->encoded = swfdec_bits_get_buffer (&s->b, -1);
       break;
     case 2:
       sound->format = SWFDEC_AUDIO_FORMAT_MP3;
-      /* FIXME: skip these samples */
-      skip = swfdec_bits_get_u16 (b);
-      orig_buffer = swfdec_bits_get_buffer (&s->b, -1);
+      sound->skip = swfdec_bits_get_u16 (b);
+      sound->encoded = swfdec_bits_get_buffer (&s->b, -1);
       break;
     case 1:
-      sound->format = SWFDEC_AUDIO_FORMAT_ADPCM;
-      orig_buffer = swfdec_bits_get_buffer (&s->b, -1);
-      break;
+    case 5:
     case 6:
-      sound->format = SWFDEC_AUDIO_FORMAT_NELLYMOSER;
-      SWFDEC_WARNING ("Nellymoser compression not implemented");
+      sound->format = format;
+      sound->encoded = swfdec_bits_get_buffer (&s->b, -1);
       break;
     default:
       SWFDEC_WARNING ("unknown format %d", format);
       sound->format = format;
   }
+  sound->n_samples *= rate;
+
+  return SWFDEC_STATUS_OK;
+}
+
+SwfdecBuffer *
+swfdec_sound_get_decoded (SwfdecSound *sound, SwfdecAudioOut *format)
+{
+  gpointer decoder;
+  SwfdecBuffer *tmp, *tmp2;
+  guint sample_bytes;
+
+  g_return_val_if_fail (SWFDEC_IS_SOUND (sound), NULL);
+  g_return_val_if_fail (format != NULL, NULL);
+
+  if (sound->decoded) {
+    swfdec_cached_use (SWFDEC_CACHED (sound));
+    *format = sound->decoded_format;
+    return sound->decoded;
+  }
+  if (sound->encoded == NULL)
+    return NULL;
   sound->codec = swfdec_codec_get_audio (sound->format);
-  if (sound->codec && orig_buffer) {
-    SwfdecBuffer *tmp, *tmp2;
-    gpointer data = swfdec_sound_init_decoder (sound);
-    sound->decoded_format = swfdec_sound_get_decoder_format (sound, data);
-    tmp = swfdec_sound_decode_buffer (sound, data, orig_buffer);
-    tmp2 = swfdec_sound_finish_decoder (sound, data);
+  if (sound->codec == NULL)
+    return NULL;
+
+  decoder = swfdec_sound_init_decoder (sound);
+  if (decoder == NULL)
+    return NULL;
+  sound->decoded_format = swfdec_sound_get_decoder_format (sound, decoder);
+  sample_bytes = 2 * SWFDEC_AUDIO_OUT_N_CHANNELS (sound->decoded_format);
+  /* FIXME: The size is only a guess */
+  swfdec_cached_load (SWFDEC_CACHED (sound), sound->n_samples * sample_bytes);
+  tmp = swfdec_sound_decode_buffer (sound, decoder, sound->encoded);
+  tmp2 = swfdec_sound_finish_decoder (sound, decoder);
+  if (tmp == NULL) {
+    if (tmp2) {
+      tmp = tmp2;
+    } else {
+      SWFDEC_ERROR ("got no data when decoding sound %u", 
+	  SWFDEC_CHARACTER (sound)->id);
+      swfdec_cached_unload (SWFDEC_CACHED (sound));
+      return NULL;
+    }
+  } else {
     if (tmp2) {
       /* and all this code just because mad sucks... */
       SwfdecBufferQueue *queue = swfdec_buffer_queue_new ();
@@ -179,45 +224,33 @@ tag_func_define_sound (SwfdecSwfDecoder 
       tmp = swfdec_buffer_queue_pull (queue, swfdec_buffer_queue_get_depth (queue));
       swfdec_buffer_queue_free (queue);
     }
-    swfdec_buffer_unref (orig_buffer);
-    if (tmp) {
-      guint sample_bytes = 2 * SWFDEC_AUDIO_OUT_N_CHANNELS (sound->decoded_format);
-      SWFDEC_LOG ("after decoding, got %u samples, should get %u and skip %u", 
-	  tmp->length / sample_bytes, 
-	  sound->n_samples, skip);
-      if (skip) {
-	SwfdecBuffer *tmp2 = swfdec_buffer_new_subbuffer (tmp, skip * sample_bytes, 
-	    tmp->length - skip * sample_bytes);
-	swfdec_buffer_unref (tmp);
-	tmp = tmp2;
-      }
-      /* sound buffer may be bigger due to mp3 not having sample boundaries */
-      if (tmp->length > sound->n_samples * sample_bytes) {
-	SwfdecBuffer *tmp2 = swfdec_buffer_new_subbuffer (tmp, 0, sound->n_samples * sample_bytes);
-	swfdec_buffer_unref (tmp);
-	tmp = tmp2;
-      }
-      /* only assign here, the decoding code checks this variable */
-      sound->decoded = tmp;
-      if (tmp->length < sound->n_samples * sample_bytes) {
-	/* we handle this case in swfdec_sound_render */
-	/* FIXME: this message is important when writing new codecs, so I made it a warning.
-	 * It's probably not worth more than INFO for the usual case though */
-	SWFDEC_WARNING ("%u samples in %u bytes should be available, but only %u bytes are",
-	    sound->n_samples, sound->n_samples * sample_bytes, tmp->length);
-      }
-    } else {
-      SWFDEC_ERROR ("failed decoding given data in format %u", format);
-    }
   }
-  sound->n_samples *= rate;
-  if (sound->decoded == NULL) {
-    SWFDEC_ERROR ("defective sound object (id %d)", SWFDEC_CHARACTER (sound)->id);
-    s->characters = g_list_remove (s->characters, sound);
-    g_object_unref (sound);
+  SWFDEC_LOG ("after decoding, got %u samples, should get %u and skip %u", 
+      tmp->length / sample_bytes, sound->n_samples, sound->skip);
+  if (sound->skip) {
+    SwfdecBuffer *tmp2 = swfdec_buffer_new_subbuffer (tmp, sound->skip * sample_bytes, 
+	tmp->length - sound->skip * sample_bytes);
+    swfdec_buffer_unref (tmp);
+    tmp = tmp2;
+  }
+  /* sound buffer may be bigger due to mp3 not having sample boundaries */
+  if (tmp->length > sound->n_samples * sample_bytes) {
+    SwfdecBuffer *tmp2 = swfdec_buffer_new_subbuffer (tmp, 0, sound->n_samples * sample_bytes);
+    swfdec_buffer_unref (tmp);
+    tmp = tmp2;
+  }
+  if (tmp->length < sound->n_samples * sample_bytes) {
+    /* we handle this case in swfdec_sound_render */
+    /* FIXME: this message is important when writing new codecs, so I made it a warning.
+     * It's probably not worth more than INFO for the usual case though */
+    SWFDEC_WARNING ("%u samples in %u bytes should be available, but only %u bytes are",
+	sound->n_samples, sound->n_samples * sample_bytes, tmp->length);
   }
+  /* only assign here, the decoding code checks this variable */
+  sound->decoded = tmp;
 
-  return SWFDEC_STATUS_OK;
+  *format = sound->decoded_format;
+  return sound->decoded;
 }
 
 int
@@ -621,9 +654,14 @@ void
 swfdec_sound_render (SwfdecSound *sound, gint16 *dest,
     unsigned int offset, unsigned int n_samples)
 {
+  SwfdecBuffer *buffer;
+  SwfdecAudioOut format;
   g_return_if_fail (SWFDEC_IS_SOUND (sound));
-  g_return_if_fail (sound->decoded != NULL);
+  /* FIXME: I need a return_if_fail for !created_by_define_sound */
 
-  swfdec_sound_buffer_render (dest, sound->decoded, sound->decoded_format, 
+  buffer = swfdec_sound_get_decoded (sound, &format);
+  if (buffer == NULL)
+    return;
+  swfdec_sound_buffer_render (dest, buffer, format, 
       NULL, offset, n_samples);
 }
diff --git a/libswfdec/swfdec_sound.h b/libswfdec/swfdec_sound.h
index 1032b6b..7101675 100644
--- a/libswfdec/swfdec_sound.h
+++ b/libswfdec/swfdec_sound.h
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,7 @@
 #ifndef _SWFDEC_SOUND_H_
 #define _SWFDEC_SOUND_H_
 
-#include <libswfdec/swfdec_character.h>
+#include <libswfdec/swfdec_cached.h>
 #include <libswfdec/swfdec_codec.h>
 #include <libswfdec/swfdec_swf_decoder.h>
 #include <libswfdec/swfdec_types.h>
@@ -61,13 +61,15 @@ struct _SwfdecSoundChunk
 
 struct _SwfdecSound
 {
-  SwfdecCharacter	character;
+  SwfdecCached		cached;
 
   SwfdecAudioFormat	format;			/* format in use */
   const SwfdecAudioCodec *codec;		/* codec for this sound */
   gboolean		width;			/* TRUE for 16bit, FALSE for 8bit */
   SwfdecAudioOut	original_format;      	/* channel/rate information */
   unsigned int		n_samples;		/* total number of samples */
+  unsigned int		skip;			/* samples to skip at start */
+  SwfdecBuffer *	encoded;		/* encoded data */
 
   SwfdecAudioOut	decoded_format;		/* format of decoded data */
   SwfdecBuffer *	decoded;		/* decoded data */
@@ -75,7 +77,7 @@ struct _SwfdecSound
 
 struct _SwfdecSoundClass
 {
-  SwfdecCharacterClass	character_class;
+  SwfdecCachedClass	cached_class;
 };
 
 GType swfdec_sound_get_type (void);
diff-tree 3fe8fea8d9594e3a6bc52152a2fe77629fa59063 (from 5f2def54b59ff4937c94f6366206aaf29933f682)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 21:52:08 2007 +0100

    rename swfdec_cached_reload to swfdec_cached_use

diff --git a/libswfdec/swfdec_cached.c b/libswfdec/swfdec_cached.c
index ef5ea24..aa6a694 100644
--- a/libswfdec/swfdec_cached.c
+++ b/libswfdec/swfdec_cached.c
@@ -92,7 +92,7 @@ swfdec_cached_load (SwfdecCached *cached
 }
 
 void
-swfdec_cached_reload (SwfdecCached *cached)
+swfdec_cached_use (SwfdecCached *cached)
 {
   g_return_if_fail (SWFDEC_IS_CACHED (cached));
   g_return_if_fail (cached->handle.unload != NULL);
diff --git a/libswfdec/swfdec_cached.h b/libswfdec/swfdec_cached.h
index 5f40877..bc9a1f7 100644
--- a/libswfdec/swfdec_cached.h
+++ b/libswfdec/swfdec_cached.h
@@ -55,7 +55,7 @@ GType			swfdec_cached_get_type		(void);
 
 void			swfdec_cached_load		(SwfdecCached *	cached,
 							 guint		size);
-void			swfdec_cached_reload		(SwfdecCached *	cached);
+void			swfdec_cached_use		(SwfdecCached *	cached);
 void			swfdec_cached_unload		(SwfdecCached *	cached);
 void			swfdec_cached_set_cache		(SwfdecCached *	cached,
 							 SwfdecCache *	cache);
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 64daf19..6c2dcae 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -597,7 +597,7 @@ swfdec_image_get_surface (SwfdecImage *i
   g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
 
   if (image->surface) {
-    swfdec_cached_reload (SWFDEC_CACHED (image));
+    swfdec_cached_use (SWFDEC_CACHED (image));
     return image->surface;
   }
 
diff-tree 5f2def54b59ff4937c94f6366206aaf29933f682 (from 89329b9198530b63a11129990780439dd2cf99f8)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 14:46:10 2007 +0100

    add new class SwfdecCached
    
    SwfdecCached is used by characters that can have their contents dynamically
    decoded and use a SwfdecCache.
    Make SwfdecImage use it. SwfdecSound will follow

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 8ab165c..485f97f 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -25,6 +25,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_button.c \
 	swfdec_button_movie.c \
 	swfdec_cache.c \
+	swfdec_cached.c \
 	swfdec_character.c \
 	swfdec_codec.c \
 	swfdec_codec_adpcm.c \
@@ -104,6 +105,7 @@ noinst_HEADERS = \
 	swfdec_button.h \
 	swfdec_button_movie.h \
 	swfdec_cache.h \
+	swfdec_cached.h \
 	swfdec_character.h \
 	swfdec_codec.h \
 	swfdec_color.h \
diff --git a/libswfdec/swfdec_cached.c b/libswfdec/swfdec_cached.c
new file mode 100644
index 0000000..ef5ea24
--- /dev/null
+++ b/libswfdec/swfdec_cached.c
@@ -0,0 +1,123 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_cached.h"
+#include "swfdec_debug.h"
+
+
+G_DEFINE_ABSTRACT_TYPE (SwfdecCached, swfdec_cached, SWFDEC_TYPE_CHARACTER)
+
+static void
+swfdec_cached_dispose (GObject *object)
+{
+  SwfdecCached * cached = SWFDEC_CACHED (object);
+
+  swfdec_cached_unload (cached);
+
+  G_OBJECT_CLASS (swfdec_cached_parent_class)->dispose (object);
+}
+
+static void
+swfdec_cached_class_init (SwfdecCachedClass * g_class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+
+  object_class->dispose = swfdec_cached_dispose;
+}
+
+static void
+swfdec_cached_init (SwfdecCached * cached)
+{
+}
+
+void
+swfdec_cached_set_cache (SwfdecCached *cached, SwfdecCache *cache)
+{
+  g_return_if_fail (SWFDEC_IS_CACHED (cached));
+  g_return_if_fail (cache != NULL);
+
+  if (cached->cache) {
+    if (cached->handle.unload)
+      swfdec_cache_remove_handle (cached->cache, &cached->handle);
+    swfdec_cache_unref (cached->cache);
+  }
+  cached->cache = cache;
+  if (cache) {
+    swfdec_cache_ref (cache);
+    if (cached->handle.unload)
+      swfdec_cache_add_handle (cached->cache, &cached->handle);
+  }
+}
+
+static void
+swfdec_cached_unload_func (gpointer data)
+{
+  SwfdecCached *cached = SWFDEC_CACHED (data - G_STRUCT_OFFSET (SwfdecCached, handle));
+
+  cached->handle.unload = NULL;
+  swfdec_cached_unload (cached);
+}
+
+void
+swfdec_cached_load (SwfdecCached *cached, guint size)
+{
+  g_return_if_fail (SWFDEC_IS_CACHED (cached));
+  g_return_if_fail (cached->handle.unload == NULL);
+  g_return_if_fail (size > 0);
+
+  cached->handle.unload = swfdec_cached_unload_func;
+  cached->handle.size = size;
+  if (cached->cache)
+    swfdec_cache_add_handle (cached->cache, &cached->handle);
+}
+
+void
+swfdec_cached_reload (SwfdecCached *cached)
+{
+  g_return_if_fail (SWFDEC_IS_CACHED (cached));
+  g_return_if_fail (cached->handle.unload != NULL);
+
+  if (cached->cache)
+    swfdec_cache_add_handle (cached->cache, &cached->handle);
+}
+
+void
+swfdec_cached_unload (SwfdecCached *cached)
+{
+  g_return_if_fail (SWFDEC_IS_CACHED (cached));
+
+  if (cached->handle.unload) {
+    if (cached->cache)
+      swfdec_cache_remove_handle (cached->cache, &cached->handle);
+    cached->handle.unload = NULL;
+  }
+  if (cached->handle.size) {
+    SwfdecCachedClass *klass;
+
+    klass = SWFDEC_CACHED_GET_CLASS (cached);
+    cached->handle.size = 0;
+    g_return_if_fail (klass->unload != NULL);
+    klass->unload (cached);
+  }
+}
+
diff --git a/libswfdec/swfdec_cached.h b/libswfdec/swfdec_cached.h
new file mode 100644
index 0000000..5f40877
--- /dev/null
+++ b/libswfdec/swfdec_cached.h
@@ -0,0 +1,65 @@
+/* Swfdec
+ * Copyright (c) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _SWFDEC_CACHED_H_
+#define _SWFDEC_CACHED_H_
+
+#include <cairo.h>
+#include <libswfdec/swfdec_cache.h>
+#include <libswfdec/swfdec_character.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecCached SwfdecCached;
+typedef struct _SwfdecCachedClass SwfdecCachedClass;
+
+#define SWFDEC_TYPE_CACHED                    (swfdec_cached_get_type())
+#define SWFDEC_IS_CACHED(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_CACHED))
+#define SWFDEC_IS_CACHED_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_CACHED))
+#define SWFDEC_CACHED(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_CACHED, SwfdecCached))
+#define SWFDEC_CACHED_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_CACHED, SwfdecCachedClass))
+#define SWFDEC_CACHED_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_CACHED, SwfdecCachedClass))
+
+
+struct _SwfdecCached {
+  SwfdecCharacter	character;
+
+  SwfdecCache *		cache;		/* cache to use for cached */
+  SwfdecCacheHandle	handle;		/* handle to unload surface */
+};
+
+struct _SwfdecCachedClass
+{
+  SwfdecCharacterClass	character_class;
+
+  void			(* unload)			(SwfdecCached *	cached);
+};
+
+GType			swfdec_cached_get_type		(void);
+
+void			swfdec_cached_load		(SwfdecCached *	cached,
+							 guint		size);
+void			swfdec_cached_reload		(SwfdecCached *	cached);
+void			swfdec_cached_unload		(SwfdecCached *	cached);
+void			swfdec_cached_set_cache		(SwfdecCached *	cached,
+							 SwfdecCache *	cache);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index a08d2d4..64daf19 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -40,12 +40,12 @@ static void swfdec_image_colormap_decode
     unsigned char *dest,
     unsigned char *src, unsigned char *colormap, int colormap_len);
 
-G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CHARACTER)
+G_DEFINE_TYPE (SwfdecImage, swfdec_image, SWFDEC_TYPE_CACHED)
 
 static void
-swfdec_image_unload (gpointer data)
+swfdec_image_unload (SwfdecCached *cached)
 {
-  SwfdecImage *image = SWFDEC_IMAGE (data - G_STRUCT_OFFSET (SwfdecImage, handle));
+  SwfdecImage *image = SWFDEC_IMAGE (cached);
 
   if (image->surface) {
     cairo_surface_destroy (image->surface);
@@ -58,7 +58,6 @@ swfdec_image_dispose (GObject *object)
 {
   SwfdecImage * image = SWFDEC_IMAGE (object);
 
-  swfdec_image_unload (&image->handle);
   if (image->jpegtables) {
     swfdec_buffer_unref (image->jpegtables);
     image->jpegtables = NULL;
@@ -75,14 +74,16 @@ static void
 swfdec_image_class_init (SwfdecImageClass * g_class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+  SwfdecCachedClass *cached_class = SWFDEC_CACHED_CLASS (g_class);
 
   object_class->dispose = swfdec_image_dispose;
+
+  cached_class->unload = swfdec_image_unload;
 }
 
 static void
 swfdec_image_init (SwfdecImage * image)
 {
-  image->handle.unload = swfdec_image_unload;
 }
 
 
@@ -211,9 +212,11 @@ swfdec_image_jpeg_load (SwfdecImage *ima
       image->raw_data->length - 2);
   jpeg_rgb_decoder_parse (dec);
   jpeg_rgb_decoder_get_image_size (dec, &image->width, &image->height);
-  image->handle.size = 4 * image->width * image->height;
-  if (image->cache)
-    swfdec_cache_add_handle (image->cache, &image->handle);
+  if (image->width == 0 || image->height == 0) {
+    jpeg_rgb_decoder_free (dec);
+    return;
+  }
+  swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
   jpeg_rgb_decoder_get_image (dec, &image_data,
       &image->rowstride, NULL, NULL);
   jpeg_rgb_decoder_free (dec);
@@ -257,9 +260,11 @@ swfdec_image_jpeg2_load (SwfdecImage *im
       image->raw_data->length - 2);
   jpeg_rgb_decoder_parse (dec);
   jpeg_rgb_decoder_get_image_size (dec, &image->width, &image->height);
-  image->handle.size = 4 * image->width * image->height;
-  if (image->cache)
-    swfdec_cache_add_handle (image->cache, &image->handle);
+  if (image->width == 0 || image->height == 0) {
+    jpeg_rgb_decoder_free (dec);
+    return;
+  }
+  swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
   jpeg_rgb_decoder_get_image (dec, &image_data,
       &image->rowstride, &image->width, &image->height);
   jpeg_rgb_decoder_free (dec);
@@ -318,9 +323,11 @@ swfdec_image_jpeg3_load (SwfdecImage *im
   jpeg_rgb_decoder_addbits (dec, bits.ptr, jpeg_length);
   jpeg_rgb_decoder_parse (dec);
   jpeg_rgb_decoder_get_image_size (dec, &image->width, &image->height);
-  image->handle.size = 4 * image->width * image->height;
-  if (image->cache)
-    swfdec_cache_add_handle (image->cache, &image->handle);
+  if (image->width == 0 || image->height == 0) {
+    jpeg_rgb_decoder_free (dec);
+    return;
+  }
+  swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
   jpeg_rgb_decoder_get_image (dec, &image_data,
       &image->rowstride, &image->width, &image->height);
   jpeg_rgb_decoder_free (dec);
@@ -385,9 +392,6 @@ swfdec_image_lossless_load (SwfdecImage 
   SWFDEC_LOG ("  width = %d", image->width);
   image->height = swfdec_bits_get_u16 (&bits);
   SWFDEC_LOG ("  height = %d", image->height);
-  image->handle.size = 4 * image->width * image->height;
-  if (image->cache)
-    swfdec_cache_add_handle (image->cache, &image->handle);
   if (format == 3) {
     color_table_size = swfdec_bits_get_u8 (&bits) + 1;
   } else {
@@ -399,6 +403,9 @@ swfdec_image_lossless_load (SwfdecImage 
   SWFDEC_LOG ("height = %d", image->height);
   SWFDEC_LOG ("color_table_size = %d", color_table_size);
 
+  if (image->width == 0 || image->height == 0)
+    return;
+  swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
   ptr = lossless (bits.ptr, endptr - bits.ptr, &len);
   bits.ptr = endptr;
 
@@ -590,8 +597,7 @@ swfdec_image_get_surface (SwfdecImage *i
   g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL);
 
   if (image->surface) {
-    if (image->cache)
-      swfdec_cache_add_handle (image->cache, &image->handle);
+    swfdec_cached_reload (SWFDEC_CACHED (image));
     return image->surface;
   }
 
@@ -617,27 +623,6 @@ swfdec_image_get_surface (SwfdecImage *i
       break;
   }
 
-  g_assert (image->handle.size);
-  g_assert (image->surface);
   return image->surface;
 }
 
-void
-swfdec_image_set_cache (SwfdecImage *image, SwfdecCache *cache)
-{
-  g_return_if_fail (SWFDEC_IS_IMAGE (image));
-  g_return_if_fail (cache != NULL);
-
-  if (image->cache) {
-    if (image->surface)
-      swfdec_cache_remove_handle (image->cache, &image->handle);
-    swfdec_cache_unref (image->cache);
-  }
-  image->cache = cache;
-  if (cache) {
-    swfdec_cache_ref (cache);
-    if (image->surface)
-      swfdec_cache_add_handle (image->cache, &image->handle);
-  }
-}
-
diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h
index 2fa7a68..af230f2 100644
--- a/libswfdec/swfdec_image.h
+++ b/libswfdec/swfdec_image.h
@@ -23,8 +23,7 @@
 #define _SWFDEC_IMAGE_H_
 
 #include <cairo.h>
-#include <libswfdec/swfdec_cache.h>
-#include <libswfdec/swfdec_character.h>
+#include <libswfdec/swfdec_cached.h>
 #include <libswfdec/swfdec_decoder.h>
 
 G_BEGIN_DECLS
@@ -46,34 +45,27 @@ typedef enum {
   SWFDEC_IMAGE_TYPE_LOSSLESS2,
 } SwfdecImageType;
 
-struct _SwfdecImage
-{
-  SwfdecCharacter	character;
+struct _SwfdecImage {
+  SwfdecCached		cached;
 
   cairo_surface_t *	surface;	/* surface that is on-demand loaded */
-  SwfdecCache *		cache;		/* cache to use for image */
-  SwfdecCacheHandle	handle;		/* handle to unload surface */
-
-  int width, height;
-  int rowstride;
-
-  SwfdecBuffer *jpegtables;
-  SwfdecBuffer *raw_data;
-
-  SwfdecImageType type;
+  int			width;
+  int			height;
+  int			rowstride;
+
+  SwfdecImageType	type;
+  SwfdecBuffer *	jpegtables;
+  SwfdecBuffer *	raw_data;
 };
 
-struct _SwfdecImageClass
-{
-  SwfdecCharacterClass	character_class;
+struct _SwfdecImageClass {
+  SwfdecCachedClass	cached_class;
 
 };
 
 GType			swfdec_image_get_type		(void);
 
 cairo_surface_t *	swfdec_image_get_surface	(SwfdecImage *	image);
-void			swfdec_image_set_cache		(SwfdecImage *	image,
-							 SwfdecCache *	cache);
 
 int swfdec_image_jpegtables (SwfdecSwfDecoder * s);
 int tag_func_define_bits_jpeg (SwfdecSwfDecoder * s);
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index 60bc99e..e7be205 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -32,8 +32,8 @@
 #include "swfdec_swf_decoder.h"
 #include "swfdec.h"
 #include "swfdec_bits.h"
+#include "swfdec_cached.h"
 #include "swfdec_debug.h"
-#include "swfdec_image.h"
 #include "swfdec_js.h"
 #include "swfdec_player_internal.h"
 #include "swfdec_sprite.h"
@@ -457,9 +457,8 @@ swfdec_swf_decoder_create_character (Swf
     g_assert (SWFDEC_DECODER (s)->player);
     SWFDEC_SPRITE (result)->player = SWFDEC_DECODER (s)->player;
   }
-  /* FIXME: generalize this for cache-using classes */
-  if (SWFDEC_IS_IMAGE (result)) {
-    swfdec_image_set_cache (SWFDEC_IMAGE (result), SWFDEC_DECODER (s)->player->cache);
+  if (SWFDEC_IS_CACHED (result)) {
+    swfdec_cached_set_cache (SWFDEC_CACHED (result), SWFDEC_DECODER (s)->player->cache);
   }
 
   return result;
diff-tree 89329b9198530b63a11129990780439dd2cf99f8 (from 56c277e18cee8bf64152e1ad3e5f7e2af5b1ec5f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 14:44:02 2007 +0100

    call unload function after adjusting size
    
    This way the unload function can do with the handle what it likes
    (including freeing it)
    Also add some debugging

diff --git a/libswfdec/swfdec_cache.c b/libswfdec/swfdec_cache.c
index 6881337..0620b51 100644
--- a/libswfdec/swfdec_cache.c
+++ b/libswfdec/swfdec_cache.c
@@ -22,7 +22,8 @@
 #include "config.h"
 #endif
 
-#include <swfdec_cache.h>
+#include "swfdec_cache.h"
+#include "swfdec_debug.h"
 
 SwfdecCache *
 swfdec_cache_new (unsigned int max_size)
@@ -77,8 +78,10 @@ swfdec_cache_shrink (SwfdecCache *cache,
   while (cache->usage > max_usage) {
     SwfdecCacheHandle *handle = g_queue_pop_tail (cache->queue);
     g_assert (handle);
-    handle->unload (handle);
     cache->usage -= handle->size;
+    SWFDEC_LOG ("%p removing %p (%u => %u)", cache, handle, 
+	cache->usage + handle->size, cache->usage);
+    handle->unload (handle);
   }
 }
 
@@ -111,6 +114,8 @@ swfdec_cache_add_handle (SwfdecCache *ca
     swfdec_cache_shrink (cache, cache->max_size - handle->size);
     g_queue_push_head (cache->queue, (gpointer) handle);
     cache->usage += handle->size;
+    SWFDEC_LOG ("%p adding %p (%u => %u)", cache, handle, 
+	cache->usage - handle->size, cache->usage);
   }
 }
 
@@ -136,5 +141,7 @@ swfdec_cache_remove_handle (SwfdecCache 
   if (list) {
     g_queue_delete_link (cache->queue, list);
     cache->usage -= handle->size;
+    SWFDEC_LOG ("%p removing %p (%u => %u)", cache, handle, 
+	cache->usage + handle->size, cache->usage);
   }
 }
diff-tree 56c277e18cee8bf64152e1ad3e5f7e2af5b1ec5f (from 097b676f528d2d0e5c0a972823cdffdf4e9b0134)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 11:57:12 2007 +0100

    make SwfdecNetStream a SwfdecScriptable (nothing else changed)

diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 21458d5..eee3f72 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -200,7 +200,7 @@ swfdec_net_stream_input_finalize (Swfdec
 
 /*** SWFDEC_NET_STREAM ***/
 
-G_DEFINE_TYPE_WITH_CODE (SwfdecNetStream, swfdec_net_stream, G_TYPE_OBJECT,
+G_DEFINE_TYPE_WITH_CODE (SwfdecNetStream, swfdec_net_stream, SWFDEC_TYPE_SCRIPTABLE,
     G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_net_stream_loader_target_init))
 
 static void
diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h
index 97de110..cf5fd5a 100644
--- a/libswfdec/swfdec_net_stream.h
+++ b/libswfdec/swfdec_net_stream.h
@@ -23,6 +23,7 @@
 #include <libswfdec/swfdec.h>
 #include <libswfdec/swfdec_flv_decoder.h>
 #include <libswfdec/swfdec_player_internal.h>
+#include <libswfdec/swfdec_scriptable.h>
 #include <libswfdec/swfdec_video_movie.h>
 
 G_BEGIN_DECLS
@@ -39,7 +40,7 @@ typedef struct _SwfdecNetStreamClass Swf
 
 struct _SwfdecNetStream
 {
-  GObject		object;
+  SwfdecScriptable	scriptable;
 
   SwfdecPlayer *	player;		/* the player we play in */
   SwfdecLoader *	loader;		/* input connection */
@@ -63,7 +64,7 @@ struct _SwfdecNetStream
 
 struct _SwfdecNetStreamClass
 {
-  GObjectClass		object_class;
+  SwfdecScriptableClass	scriptable_class;
 };
 
 GType			swfdec_net_stream_get_type	(void);
diff-tree 097b676f528d2d0e5c0a972823cdffdf4e9b0134 (from a98207b6015a3cfbbd3fc287ad6aaa6e7dc39938)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 11:54:24 2007 +0100

    Add a SwfdecScriptable class that functions as the frontend for objects accessible from AS
    
    Make SwfdecMovie a SwfdecScriptable

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 08e39de..8ab165c 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -63,6 +63,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_rect.c \
 	swfdec_ringbuffer.c \
 	swfdec_root_movie.c \
+	swfdec_scriptable.c \
 	swfdec_shape.c \
 	swfdec_sound.c \
 	swfdec_sprite.c \
@@ -131,6 +132,7 @@ noinst_HEADERS = \
 	swfdec_rect.h \
 	swfdec_ringbuffer.h \
 	swfdec_root_movie.h \
+	swfdec_scriptable.h \
 	swfdec_shape.h \
 	swfdec_sound.h \
 	swfdec_sprite.h \
diff --git a/libswfdec/swfdec_edittext_movie.c b/libswfdec/swfdec_edittext_movie.c
index 872f7f9..421f6bc 100644
--- a/libswfdec/swfdec_edittext_movie.c
+++ b/libswfdec/swfdec_edittext_movie.c
@@ -68,24 +68,23 @@ static void
 swfdec_edit_text_movie_iterate (SwfdecMovie *movie)
 {
   SwfdecEditTextMovie *text = SWFDEC_EDIT_TEXT_MOVIE (movie);
-  SwfdecPlayer *player;
+  SwfdecScriptable *parent;
+  JSObject *jsobj;
   jsval val;
   const char *s;
 
   if (text->text->variable == NULL)
     return;
 
-  player = SWFDEC_ROOT_MOVIE (movie->root)->player;
-  if (movie->parent->jsobj == NULL) {
-    swfdec_js_add_movie (movie->parent);
-    if (movie->parent->jsobj == NULL)
-      return;
-  }
-  val = swfdec_js_eval (player->jscx, movie->parent->jsobj, text->text->variable);
+  parent = SWFDEC_SCRIPTABLE (movie->parent);
+  jsobj = swfdec_scriptable_get_object (parent);
+  if (jsobj == NULL)
+    return;
+  val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable);
   if (JSVAL_IS_VOID (val))
     return;
 
-  s = swfdec_js_to_string (player->jscx, val);
+  s = swfdec_js_to_string (parent->jscx, val);
   if (!s && !text->str)
     return;
   if (s && text->str && g_str_equal (s, text->str))
@@ -98,31 +97,28 @@ static void
 swfdec_edit_text_movie_init_movie (SwfdecMovie *movie)
 {
   SwfdecEditTextMovie *text = SWFDEC_EDIT_TEXT_MOVIE (movie);
-  SwfdecPlayer *player;
-  JSObject *object;
+  SwfdecScriptable *parent;
+  JSObject *jsobj;
   JSString *string;
   jsval val;
 
   if (text->text->variable == NULL)
     return;
 
-  player = SWFDEC_ROOT_MOVIE (movie->root)->player;
-  if (movie->parent->jsobj == NULL) {
-    swfdec_js_add_movie (movie->parent);
-    if (movie->parent->jsobj == NULL)
-      return;
-  }
-  object = movie->parent->jsobj;
+  parent = SWFDEC_SCRIPTABLE (movie->parent);
+  jsobj = swfdec_scriptable_get_object (parent);
+  if (jsobj == NULL)
+    return;
   if (text->text->variable_prefix) {
-    val = swfdec_js_eval (player->jscx, object, text->text->variable_prefix);
+    val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable_prefix);
     if (!JSVAL_IS_OBJECT (val))
       return;
-    object = JSVAL_TO_OBJECT (val);
+    jsobj = JSVAL_TO_OBJECT (val);
   }
-  if (!JS_GetProperty (player->jscx, object, text->text->variable_name, &val))
+  if (!JS_GetProperty (parent->jscx, jsobj, text->text->variable_name, &val))
     return;
   if (!JSVAL_IS_VOID (val)) {
-    const char *s = swfdec_js_to_string (player->jscx, val);
+    const char *s = swfdec_js_to_string (parent->jscx, val);
     if (!s && !text->str)
       return;
     if (s && text->str && g_str_equal (s, text->str))
@@ -134,11 +130,11 @@ swfdec_edit_text_movie_init_movie (Swfde
 
   SWFDEC_LOG ("setting variable %s (%s) to \"%s\"", text->text->variable_name,
       text->text->variable, text->str ? text->str : "");
-  string = JS_NewStringCopyZ (player->jscx, text->str ? text->str : "");
+  string = JS_NewStringCopyZ (parent->jscx, text->str ? text->str : "");
   if (string == NULL)
     return;
   val = STRING_TO_JSVAL (string);
-  JS_SetProperty (player->jscx, object, text->text->variable_name, &val);
+  JS_SetProperty (parent->jscx, jsobj, text->text->variable_name, &val);
 }
 
 static void
diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c
index 3824fb6..4ce01a5 100644
--- a/libswfdec/swfdec_js.c
+++ b/libswfdec/swfdec_js.c
@@ -130,29 +130,6 @@ swfdec_js_finish_player (SwfdecPlayer *p
   }
 }
 
-JSBool
-swfdec_js_push_state (SwfdecMovie *movie)
-{
-  SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (movie->root)->player;
-  JSBool old_case, new_case;
-  
-  old_case = JS_GetContextCaseSensitive (player->jscx);
-  if (SWFDEC_IS_SWF_DECODER (SWFDEC_ROOT_MOVIE (movie->root)->decoder))
-    new_case = SWFDEC_SWF_DECODER (SWFDEC_ROOT_MOVIE (movie->root)->decoder)->version >= 7 ? 
-      JS_TRUE : JS_FALSE;
-  else
-    new_case = JS_TRUE;
-  JS_SetContextCaseSensitive (player->jscx, new_case);
-  return old_case;
-}
-
-void
-swfdec_js_pop_state (SwfdecMovie *movie, JSBool state)
-{
-  SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (movie->root)->player;
-  JS_SetContextCaseSensitive (player->jscx, state);
-}
-
 /**
  * swfdec_js_execute_script:
  * @s: a @SwfdecPlayer
@@ -171,7 +148,8 @@ swfdec_js_execute_script (SwfdecPlayer *
     JSScript *script, jsval *rval)
 {
   jsval returnval = JSVAL_VOID;
-  JSBool ret, old_state;
+  JSObject *jsobj;
+  JSBool ret;
 
   g_return_val_if_fail (s != NULL, FALSE);
   g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), FALSE);
@@ -183,20 +161,13 @@ swfdec_js_execute_script (SwfdecPlayer *
   }
   if (rval == NULL)
     rval = &returnval;
-  if (movie->jsobj == NULL) {
-    swfdec_js_add_movie (movie);
-    if (movie->jsobj == NULL)
-      return FALSE;
-  }
-  /* setup execution state */
-  old_state = swfdec_js_push_state (movie);
-  ret = JS_ExecuteScript (s->jscx, movie->jsobj, script, rval);
-  
-  /* restore execution state */
-  swfdec_js_pop_state (movie, old_state);
+  if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie))))
+    return FALSE;
+  ret = JS_ExecuteScript (s->jscx, jsobj, script, rval);
   if (!ret) {
     SWFDEC_WARNING ("executing script %p for movie %s failed", script, movie->name);
   }
+
   if (ret && returnval != JSVAL_VOID) {
     JSString * str = JS_ValueToString (s->jscx, returnval);
     if (str)
diff --git a/libswfdec/swfdec_js.h b/libswfdec/swfdec_js.h
index acf9392..ced8046 100644
--- a/libswfdec/swfdec_js.h
+++ b/libswfdec/swfdec_js.h
@@ -36,10 +36,6 @@ gboolean	swfdec_js_execute_script	(Swfde
 gboolean	swfdec_js_run			(SwfdecPlayer *		player,
 						 const char *		s,
 						 jsval *		rval);
-/* FIXME: someone figure out if case sensitivity is global or per-movie */
-JSBool		swfdec_js_push_state		(SwfdecMovie *		movie);
-void		swfdec_js_pop_state		(SwfdecMovie *		movie,
-						 JSBool			state);
 
 void		swfdec_js_add_color		(SwfdecPlayer *		player);
 void		swfdec_js_add_globals		(SwfdecPlayer *		player);
@@ -47,9 +43,6 @@ void		swfdec_js_add_mouse		(SwfdecPlayer
 void		swfdec_js_add_movieclip_class	(SwfdecPlayer *		player);
 void		swfdec_js_add_sound		(SwfdecPlayer *		player);
 
-SwfdecMovie *	swfdec_js_val_to_movie		(JSContext *		cx,
-						 jsval			val);
-gboolean	swfdec_js_add_movie		(SwfdecMovie *		movie);
 void		swfdec_js_movie_add_property	(SwfdecMovie *		movie);
 void		swfdec_js_movie_remove_property	(SwfdecMovie *		movie);
 
diff --git a/libswfdec/swfdec_js_color.c b/libswfdec/swfdec_js_color.c
index b72d3c3..a117118 100644
--- a/libswfdec/swfdec_js_color.c
+++ b/libswfdec/swfdec_js_color.c
@@ -180,7 +180,7 @@ swfdec_js_color_new (JSContext *cx, JSOb
   SwfdecMovie *movie;
   JSObject *new;
 
-  movie = swfdec_js_val_to_movie (cx, argv[0]);
+  movie = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_MOVIE);
   if (movie == NULL) {
     SWFDEC_INFO ("attempted to construct a color without a movie");
     return JS_TRUE;
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index 8b85bb8..30eb161 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -39,30 +39,12 @@
 
 JSBool swfdec_js_global_eval (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
 
-static void
-movie_finalize (JSContext *cx, JSObject *obj)
-{
-  SwfdecMovie *movie;
-
-  movie = JS_GetPrivate (cx, obj);
-  /* since we also finalize the class, not everyone has a private object */
-  if (movie) {
-    g_assert (movie->jsobj != NULL);
-
-    SWFDEC_LOG ("destroying JSObject %p for movie %p", obj, movie);
-    movie->jsobj = NULL;
-    g_object_unref (movie);
-  } else {
-    SWFDEC_LOG ("destroying JSObject %p", obj);
-  }
-}
-
-static JSClass movieclip_class = {
+const JSClass movieclip_class = {
     "MovieClip", JSCLASS_HAS_PRIVATE,
     JS_PropertyStub,  JS_PropertyStub,
     JS_PropertyStub,  JS_PropertyStub,
     JS_EnumerateStub, JS_ResolveStub,
-    JS_ConvertStub,   movie_finalize,
+    JS_ConvertStub,   swfdec_scriptable_finalize,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
@@ -213,9 +195,9 @@ mc_hitTest (JSContext *cx, JSObject *obj
   
   if (argc == 1) {
     SwfdecMovie *other;
-    other = swfdec_js_val_to_movie (cx, argv[0]);
+    other = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_MOVIE);
     if (other == NULL) {
-      g_assert_not_reached ();
+      SWFDEC_ERROR ("FIXME: what happens now?");
       return JS_TRUE;
     }
     other = SWFDEC_MOVIE (JS_GetPrivate(cx, JSVAL_TO_OBJECT (argv[0])));
@@ -251,10 +233,11 @@ swfdec_js_getProperty (JSContext *cx, JS
 {
   uint32 id;
   SwfdecMovie *movie;
+  JSObject *jsobj;
   jsval tmp;
 
   swfdec_js_global_eval (cx, obj, 1, argv, &tmp);
-  movie = swfdec_js_val_to_movie (cx, tmp);
+  movie = swfdec_scriptable_from_jsval (cx, tmp, SWFDEC_TYPE_MOVIE);
   if (movie == NULL) {
     SWFDEC_WARNING ("specified target does not reference a movie clip");
     return JS_TRUE;
@@ -265,10 +248,9 @@ swfdec_js_getProperty (JSContext *cx, JS
   if (id > 19)
     return JS_FALSE;
 
-  if (movie->jsobj == NULL &&
-      !swfdec_js_add_movie (movie))
+  if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie))))
     return JS_FALSE;
-  return movieclip_props[id].getter (cx, movie->jsobj, INT_TO_JSVAL (id) /* FIXME */, rval);
+  return movieclip_props[id].getter (cx, jsobj, INT_TO_JSVAL (id) /* FIXME */, rval);
 }
 
 static JSBool
@@ -277,9 +259,10 @@ swfdec_js_setProperty (JSContext *cx, JS
   uint32 id;
   SwfdecMovie *movie;
   jsval tmp;
+  JSObject *jsobj;
 
   swfdec_js_global_eval (cx, obj, 1, argv, &tmp);
-  movie = swfdec_js_val_to_movie (cx, tmp);
+  movie = swfdec_scriptable_from_jsval (cx, tmp, SWFDEC_TYPE_MOVIE);
   if (movie == NULL) {
     SWFDEC_WARNING ("specified target does not reference a movie clip");
     return JS_TRUE;
@@ -290,11 +273,10 @@ swfdec_js_setProperty (JSContext *cx, JS
   if (id > 19)
     return JS_FALSE;
 
-  if (movie->jsobj == NULL &&
-      !swfdec_js_add_movie (movie))
+  if (!(jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie))))
     return JS_FALSE;
   *rval = argv[2];
-  return movieclip_props[id].setter (cx, movie->jsobj, INT_TO_JSVAL (id) /* FIXME */, rval);
+  return movieclip_props[id].setter (cx, jsobj, INT_TO_JSVAL (id) /* FIXME */, rval);
 }
 
 static JSBool
@@ -351,7 +333,7 @@ swfdec_js_movie_swapDepths (JSContext *c
   g_assert (movie);
 
   if (JSVAL_IS_OBJECT (argv[0])) {
-    other = swfdec_js_val_to_movie (cx, argv[0]);
+    other = swfdec_scriptable_from_jsval (cx, argv[0], SWFDEC_TYPE_MOVIE);
     if (other == NULL)
       return JS_TRUE;
     if (other->parent != movie->parent)
@@ -433,11 +415,11 @@ swfdec_js_movie_duplicateMovieClip (JSCo
   ret = swfdec_movie_new (movie->parent, content);
   g_object_weak_ref (G_OBJECT (ret), (GWeakNotify) swfdec_content_free, content);
   /* must be set by now, the movie has a name */
-  if (ret->jsobj == NULL)
+  if (SWFDEC_SCRIPTABLE (ret)->jsobj == NULL)
     return JS_FALSE;
   swfdec_js_copy_props (ret, movie);
   SWFDEC_LOG ("duplicated %s as %s to depth %u", movie->name, ret->name, ret->depth);
-  *rval = OBJECT_TO_JSVAL (ret->jsobj);
+  *rval = OBJECT_TO_JSVAL (SWFDEC_SCRIPTABLE (ret)->jsobj);
   return JS_TRUE;
 }
 
@@ -980,6 +962,7 @@ static JSBool
 mc_parent (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 {
   SwfdecMovie *movie;
+  JSObject *jsobj;
 
   movie = JS_GetPrivate (cx, obj);
   g_assert (movie);
@@ -988,12 +971,11 @@ mc_parent (JSContext *cx, JSObject *obj,
   if (movie->parent)
     movie = movie->parent;
 
-  if (movie->jsobj == NULL)
-    swfdec_js_add_movie (movie);
-  if (movie->jsobj == NULL)
+  jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie));
+  if (jsobj == NULL)
     return JS_FALSE;
-
-  *vp = OBJECT_TO_JSVAL (movie->jsobj);
+  
+  *vp = OBJECT_TO_JSVAL (jsobj);
 
   return JS_TRUE;
 }
@@ -1002,21 +984,17 @@ static JSBool
 mc_root (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
 {
   SwfdecMovie *movie;
+  JSObject *jsobj;
 
   movie = JS_GetPrivate (cx, obj);
   g_assert (movie);
 
   movie = movie->root;
-  if (movie->jsobj == NULL) {
-    /* the root movie only holds this as long as there's no parent */
-    movie = movie->list->data;
-    if (movie->jsobj == NULL)
-      swfdec_js_add_movie (movie);
-  }
-  if (movie->jsobj == NULL)
+  jsobj = swfdec_scriptable_get_object (SWFDEC_SCRIPTABLE (movie));
+  if (jsobj == NULL)
     return JS_FALSE;
 
-  *vp = OBJECT_TO_JSVAL (movie->jsobj);
+  *vp = OBJECT_TO_JSVAL (jsobj);
 
   return JS_TRUE;
 }
@@ -1185,112 +1163,47 @@ swfdec_js_add_movieclip_class (SwfdecPla
 void
 swfdec_js_movie_add_property (SwfdecMovie *movie)
 {
-  JSBool state;
+  SwfdecScriptable *script = SWFDEC_SCRIPTABLE (movie);
   jsval val;
   JSObject *jsobj;
   JSContext *cx;
 
-  if (movie->jsobj == NULL) {
-    if (!swfdec_js_add_movie (movie))
-      return;
-  }
-  val = OBJECT_TO_JSVAL (movie->jsobj);
-  cx = SWFDEC_ROOT_MOVIE (movie->root)->player->jscx;
+  jsobj = swfdec_scriptable_get_object (script);
+  val = OBJECT_TO_JSVAL (jsobj);
+  cx = script->jscx;
   if (movie->parent) {
-    jsobj = movie->parent->jsobj;
+    jsobj = SWFDEC_SCRIPTABLE (movie->parent)->jsobj;
     if (jsobj == NULL)
       return;
     SWFDEC_LOG ("setting %s as property for %s", movie->name, 
 	movie->parent->name);
   } else {
-    jsobj = SWFDEC_ROOT_MOVIE (movie->root)->player->jsobj;
+    jsobj = SWFDEC_ROOT_MOVIE (movie)->player->jsobj;
     SWFDEC_LOG ("setting %s as property for _global", movie->name);
   }
-  state = swfdec_js_push_state (movie);
   JS_SetProperty (cx, jsobj, movie->name, &val);
-  swfdec_js_pop_state (movie, state);
 }
 
 void
 swfdec_js_movie_remove_property (SwfdecMovie *movie)
 {
-  JSBool state;
+  SwfdecScriptable *script = SWFDEC_SCRIPTABLE (movie);
   JSObject *jsobj;
   JSContext *cx;
 
-  if (movie->jsobj == NULL)
+  if (script->jsobj == NULL)
     return;
 
-  cx = SWFDEC_ROOT_MOVIE (movie->root)->player->jscx;
+  cx = script->jscx;
   if (movie->parent) {
-    jsobj = movie->parent->jsobj;
+    jsobj = SWFDEC_SCRIPTABLE (movie->parent)->jsobj;
     if (jsobj == NULL)
       return;
   } else {
-    jsobj = SWFDEC_ROOT_MOVIE (movie->root)->player->jsobj;
+    jsobj = SWFDEC_ROOT_MOVIE (movie)->player->jsobj;
   }
 
   SWFDEC_LOG ("removing %s as property", movie->name);
-  state = swfdec_js_push_state (movie);
   JS_DeleteProperty (cx, jsobj, movie->name);
-  swfdec_js_pop_state (movie, state);
-}
-
-/**
- * swfdec_js_add_movie:
- * @movie: a #SwfdecMovie
- *
- * Ensures that a JSObject for the given @movie exists.
- **/
-gboolean
-swfdec_js_add_movie (SwfdecMovie *movie)
-{
-  JSContext *cx;
-  GList *walk;
-
-  g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), FALSE);
-  g_return_val_if_fail (movie->jsobj == NULL, FALSE);
-
-  cx = SWFDEC_ROOT_MOVIE (movie->root)->player->jscx;
-
-  movie->jsobj = JS_NewObject (cx, &movieclip_class, NULL, NULL);
-  if (movie->jsobj == NULL) {
-    SWFDEC_ERROR ("failed to create JS object for movie %p", movie);
-    return FALSE;
-  }
-  SWFDEC_LOG ("created JSObject %p for movie %p", movie->jsobj, movie);
-  g_object_ref (movie);
-  JS_SetPrivate (cx, movie->jsobj, movie);
-  /* add all children */
-  for (walk = movie->list; walk; walk = walk->next) {
-    SwfdecMovie *child = walk->data;
-    if (child->has_name)
-      swfdec_js_movie_add_property (child);
-  }
-  return TRUE;
-}
-
-/**
- * swfdec_js_val_to_movie:
- * @cx: the relevant #JSContext
- * @val: value hat might reference a #SwfdecMovie
- *
- * Extracts the #SwfdecMovie referenced by @val and returns it. This function
- * performs all the necessary error checking to ensure that @val really
- * references a movie.
- *
- * Returns: the movie referenced or NULL if no movie was referenced.
- **/
-SwfdecMovie *
-swfdec_js_val_to_movie (JSContext *cx, jsval val)
-{
-  JSObject *object;
-
-  if (!JSVAL_IS_OBJECT (val))
-    return NULL;
-  object = JSVAL_TO_OBJECT (val);
-  if (JS_GetClass (object) != &movieclip_class)
-    return NULL;
-  return JS_GetPrivate (cx, object);
 }
 
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 2d52336..16ff859 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2006 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,7 +38,7 @@
 
 static const SwfdecContent default_content = SWFDEC_CONTENT_DEFAULT;
 
-G_DEFINE_ABSTRACT_TYPE (SwfdecMovie, swfdec_movie, G_TYPE_OBJECT)
+G_DEFINE_ABSTRACT_TYPE (SwfdecMovie, swfdec_movie, SWFDEC_TYPE_SCRIPTABLE)
 
 static void
 swfdec_movie_init (SwfdecMovie * movie)
@@ -308,7 +308,7 @@ swfdec_movie_destroy (SwfdecMovie *movie
   if (movie->parent) {
     movie->parent->list = g_list_remove (movie->parent->list, movie);
   }
-  if (movie->jsobj)
+  if (SWFDEC_SCRIPTABLE (movie)->jsobj)
     swfdec_js_movie_remove_property (movie);
   player->movies = g_list_remove (player->movies, movie);
   g_object_unref (movie);
@@ -607,7 +607,6 @@ swfdec_movie_dispose (GObject *object)
 {
   SwfdecMovie * movie = SWFDEC_MOVIE (object);
 
-  g_assert (movie->jsobj == NULL);
   g_assert (movie->list == NULL);
   g_assert (movie->content == &default_content);
 
@@ -626,13 +625,37 @@ swfdec_movie_iterate_end (SwfdecMovie *m
 	 g_list_find (movie->parent->list, movie) != NULL;
 }
 
+static JSObject *
+swfdec_movie_create_js_object (SwfdecScriptable *script)
+{
+  GList *walk;
+  JSObject *ret;
+
+  ret = SWFDEC_SCRIPTABLE_CLASS (swfdec_movie_parent_class)->create_js_object (script);
+  if (ret == NULL)
+    return NULL;
+  script->jsobj = ret;
+  /* add all children */
+  for (walk = SWFDEC_MOVIE (script)->list; walk; walk = walk->next) {
+    SwfdecMovie *child = walk->data;
+    if (child->has_name)
+      swfdec_js_movie_add_property (child);
+  }
+  return ret;
+}
+
+extern const JSClass movieclip_class;
 static void
 swfdec_movie_class_init (SwfdecMovieClass * movie_class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (movie_class);
+  SwfdecScriptableClass *script_class = SWFDEC_SCRIPTABLE_CLASS (movie_class);
 
   object_class->dispose = swfdec_movie_dispose;
 
+  script_class->jsclass = &movieclip_class;
+  script_class->create_js_object = swfdec_movie_create_js_object;
+
   movie_class->iterate_end = swfdec_movie_iterate_end;
 }
 
@@ -723,6 +746,7 @@ swfdec_movie_new (SwfdecMovie *parent, c
   g_return_val_if_fail (klass->create_movie != NULL, NULL);
   ret = klass->create_movie (content->graphic);
   ret->parent = parent;
+  SWFDEC_SCRIPTABLE (ret)->jscx = SWFDEC_SCRIPTABLE (parent)->jscx;
   g_object_ref (parent);
   ret->root = parent->root;
   swfdec_movie_initialize (ret, content);
@@ -742,6 +766,7 @@ swfdec_movie_new_for_player (SwfdecPlaye
   ret = g_object_new (SWFDEC_TYPE_ROOT_MOVIE, NULL);
   g_object_weak_ref (G_OBJECT (ret), (GWeakNotify) swfdec_content_free, content);
   SWFDEC_ROOT_MOVIE (ret)->player = player;
+  SWFDEC_SCRIPTABLE (ret)->jscx = player->jscx;
   ret->root = ret;
   swfdec_movie_initialize (ret, content);
   ret->has_name = FALSE;
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index 7787ee1..61f495c 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2006 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,8 +25,8 @@
 #include <libswfdec/swfdec.h>
 #include <libswfdec/swfdec_rect.h>
 #include <libswfdec/swfdec_event.h>
+#include <libswfdec/swfdec_scriptable.h>
 #include <libswfdec/swfdec_types.h>
-#include <libswfdec/js/jspubtd.h>
 
 G_BEGIN_DECLS
 
@@ -75,11 +75,10 @@ typedef enum {
 } SwfdecMovieState;
 
 struct _SwfdecMovie {
-  GObject		object;
+  SwfdecScriptable	scriptable;
 
   char *		name;			/* name used in to_string */
   gboolean		has_name;		/* TRUE if name wasn't given automagically */
-  JSObject *		jsobj;			/* our object in javascript */
   GList *		list;			/* our contained movie clips (ordered by depth) */
   int			depth;			/* depth of movie (equals content->depth unless explicitly set) */
   const SwfdecContent *	content;           	/* the content we are displaying */
@@ -116,7 +115,7 @@ struct _SwfdecMovie {
 };
 
 struct _SwfdecMovieClass {
-  GObjectClass		object_class;
+  SwfdecScriptableClass	scriptable_class;
 
   /* general vfuncs */
   void			(* init_movie)		(SwfdecMovie *		movie);
diff --git a/libswfdec/swfdec_scriptable.c b/libswfdec/swfdec_scriptable.c
new file mode 100644
index 0000000..479bad9
--- /dev/null
+++ b/libswfdec/swfdec_scriptable.c
@@ -0,0 +1,154 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_scriptable.h"
+#include "swfdec_debug.h"
+#include "js/jsapi.h"
+
+G_DEFINE_ABSTRACT_TYPE (SwfdecScriptable, swfdec_scriptable, G_TYPE_OBJECT)
+
+static void
+swfdec_scriptable_dispose (GObject *object)
+{
+  SwfdecScriptable *script = SWFDEC_SCRIPTABLE (object);
+
+  g_assert (script->jsobj == NULL);
+
+  G_OBJECT_CLASS (swfdec_scriptable_parent_class)->dispose (object);
+}
+
+static JSObject *
+swfdec_scriptable_create_js_object (SwfdecScriptable *scriptable)
+{
+  SwfdecScriptableClass *klass;
+  JSContext *cx;
+  JSObject *obj;
+
+  klass = SWFDEC_SCRIPTABLE_GET_CLASS (scriptable);
+  g_return_val_if_fail (klass->jsclass != NULL, NULL);
+  cx = scriptable->jscx;
+
+  obj = JS_NewObject (cx, (JSClass *) klass->jsclass, NULL, NULL);
+  if (obj == NULL) {
+    SWFDEC_ERROR ("failed to create JS object for %s %p", 
+	G_OBJECT_TYPE_NAME (scriptable), scriptable);
+    return NULL;
+  }
+  SWFDEC_LOG ("created JSObject %p for %s %p", obj, 
+      G_OBJECT_TYPE_NAME (scriptable), scriptable);
+  g_object_ref (scriptable);
+  JS_SetPrivate (cx, obj, scriptable);
+  return obj;
+}
+
+static void
+swfdec_scriptable_class_init (SwfdecScriptableClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = swfdec_scriptable_dispose;
+
+  klass->create_js_object = swfdec_scriptable_create_js_object;
+}
+
+static void
+swfdec_scriptable_init (SwfdecScriptable *stream)
+{
+}
+
+/*** PUBLIC API ***/
+
+/**
+ * swfdec_scriptable_finalize:
+ * @cx: a #JSContext
+ * @obj: a #JSObject to finalize
+ *
+ * This function is intended to be used as the finalizer in the #JSClass used
+ * by a scriptable subtype.
+ **/
+void
+swfdec_scriptable_finalize (JSContext *cx, JSObject *obj)
+{
+  SwfdecScriptable *script;
+
+  script = JS_GetPrivate (cx, obj);
+  /* since we also finalize the prototype, not everyone has a private object */
+  if (script) {
+    g_assert (SWFDEC_IS_SCRIPTABLE (script));
+    g_assert (script->jsobj != NULL);
+
+    SWFDEC_LOG ("destroying JSObject %p for %s %p", obj, 
+	G_OBJECT_TYPE_NAME (script), script);
+    script->jsobj = NULL;
+    g_object_unref (script);
+  } else {
+    SWFDEC_LOG ("destroying JSObject %p without Scriptable (probably a prototype)", obj);
+  }
+}
+
+JSObject *
+swfdec_scriptable_get_object (SwfdecScriptable *scriptable)
+{
+  SwfdecScriptableClass *klass;
+
+  g_return_val_if_fail (SWFDEC_IS_SCRIPTABLE (scriptable), NULL);
+
+  if (scriptable->jsobj)
+    return scriptable->jsobj;
+  klass = SWFDEC_SCRIPTABLE_GET_CLASS (scriptable);
+  g_return_val_if_fail (klass->create_js_object, NULL);
+  scriptable->jsobj = klass->create_js_object (scriptable);
+
+  return scriptable->jsobj;
+}
+
+/**
+ * swfdec_scriptable_from_jsval:
+ * @cx: a #JSContext
+ * @val: the jsval to convert
+ * @type: type of the object to get.
+ *
+ * Converts the given value @val to a #SwfdecScriptable, if it represents one.
+ * The object must be of @type, otherwise %NULL will be returned.
+ *
+ * Returns: the scriptable represented by @val or NULL if @val does not 
+ *          reference a @scriptable
+ **/
+gpointer
+swfdec_scriptable_from_jsval (JSContext *cx, jsval val, GType type)
+{
+  SwfdecScriptableClass *klass;
+  JSObject *object;
+
+  g_return_val_if_fail (g_type_is_a (type, SWFDEC_TYPE_SCRIPTABLE), NULL);
+
+  if (!JSVAL_IS_OBJECT (val))
+    return NULL;
+  object = JSVAL_TO_OBJECT (val);
+  klass = g_type_class_peek (type);
+  if (klass == NULL)
+    return NULL; /* class doesn't exist -> no object of this type exists */
+  if (!JS_InstanceOf (cx, object, klass->jsclass, NULL))
+    return NULL;
+  return JS_GetPrivate (cx, object);
+}
diff --git a/libswfdec/swfdec_scriptable.h b/libswfdec/swfdec_scriptable.h
new file mode 100644
index 0000000..45190c4
--- /dev/null
+++ b/libswfdec/swfdec_scriptable.h
@@ -0,0 +1,66 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _SWFDEC_SCRIPTABLE_H_
+#define _SWFDEC_SCRIPTABLE_H_
+
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_types.h>
+#include <libswfdec/js/jspubtd.h>
+
+G_BEGIN_DECLS
+
+//typedef struct _SwfdecScriptable SwfdecScriptable;
+typedef struct _SwfdecScriptableClass SwfdecScriptableClass;
+
+#define SWFDEC_TYPE_SCRIPTABLE                    (swfdec_scriptable_get_type())
+#define SWFDEC_IS_SCRIPTABLE(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_SCRIPTABLE))
+#define SWFDEC_IS_SCRIPTABLE_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_SCRIPTABLE))
+#define SWFDEC_SCRIPTABLE(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_SCRIPTABLE, SwfdecScriptable))
+#define SWFDEC_SCRIPTABLE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_SCRIPTABLE, SwfdecScriptableClass))
+#define SWFDEC_SCRIPTABLE_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_SCRIPTABLE, SwfdecScriptableClass))
+
+struct _SwfdecScriptable {
+  GObject		object;
+
+  JSContext *		jscx;		/* context for jsobj */
+  JSObject *		jsobj;		/* JS object belonging to us or NULL if none */
+};
+
+struct _SwfdecScriptableClass {
+  GObjectClass		object_class;
+
+  const JSClass *	jsclass;	/* class used by objects of this type (filled by subclasses) */
+  /* the default should be good enough most of the time */
+  JSObject *		(* create_js_object)		(SwfdecScriptable *	scriptable);
+};
+
+GType			swfdec_scriptable_get_type	(void);
+
+void			swfdec_scriptable_finalize	(JSContext *		cx,
+							 JSObject *		obj);
+
+JSObject *		swfdec_scriptable_get_object	(SwfdecScriptable *	scriptable);
+gpointer		swfdec_scriptable_from_jsval	(JSContext *		cx,
+							 jsval			val,
+							 GType			type);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_types.h b/libswfdec/swfdec_types.h
index 774486e..49212d5 100644
--- a/libswfdec/swfdec_types.h
+++ b/libswfdec/swfdec_types.h
@@ -44,6 +44,7 @@ typedef struct _SwfdecShape SwfdecShape;
 typedef struct _SwfdecShapeVec SwfdecShapeVec;
 typedef struct _SwfdecRect SwfdecRect;
 typedef struct _SwfdecRootMovie SwfdecRootMovie;
+typedef struct _SwfdecScriptable SwfdecScriptable;
 typedef struct _SwfdecSound SwfdecSound;
 typedef struct _SwfdecSoundChunk SwfdecSoundChunk;
 typedef struct _SwfdecSprite SwfdecSprite;
diff-tree a98207b6015a3cfbbd3fc287ad6aaa6e7dc39938 (from 80aba02f5745e1aaa6cbf16370dfcda5f8bb5d9d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 11:45:22 2007 +0100

    apparently we need even more const

diff --git a/libswfdec/js/jsapi.c b/libswfdec/js/jsapi.c
index b98e232..e33b846 100644
--- a/libswfdec/js/jsapi.c
+++ b/libswfdec/js/jsapi.c
@@ -1889,7 +1889,7 @@ JS_FinalizeStub(JSContext *cx, JSObject 
 
 JS_PUBLIC_API(JSObject *)
 JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
-             JSClass *clasp, JSNative constructor, uintN nargs,
+             const JSClass *clasp, JSNative constructor, uintN nargs,
              JSPropertySpec *ps, JSFunctionSpec *fs,
              JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
 {
@@ -1979,7 +1979,7 @@ JS_GetClass(JSObject *obj)
 #endif
 
 JS_PUBLIC_API(JSBool)
-JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
+JS_InstanceOf(JSContext *cx, JSObject *obj, const JSClass *clasp, jsval *argv)
 {
     JSFunction *fun;
 
diff --git a/libswfdec/js/jsapi.h b/libswfdec/js/jsapi.h
index 1718acc..9cc1dd0 100644
--- a/libswfdec/js/jsapi.h
+++ b/libswfdec/js/jsapi.h
@@ -877,7 +877,7 @@ struct JSFunctionSpec {
 
 extern JS_PUBLIC_API(JSObject *)
 JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
-             JSClass *clasp, JSNative constructor, uintN nargs,
+             const JSClass *clasp, JSNative constructor, uintN nargs,
              JSPropertySpec *ps, JSFunctionSpec *fs,
              JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
 
@@ -894,7 +894,7 @@ JS_GetClass(JSObject *obj);
 #endif
 
 extern JS_PUBLIC_API(JSBool)
-JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv);
+JS_InstanceOf(JSContext *cx, JSObject *obj, const JSClass *clasp, jsval *argv);
 
 extern JS_PUBLIC_API(void *)
 JS_GetPrivate(JSContext *cx, JSObject *obj);
diff --git a/libswfdec/js/jsfun.h b/libswfdec/js/jsfun.h
index 1a36d6b..5dad235 100644
--- a/libswfdec/js/jsfun.h
+++ b/libswfdec/js/jsfun.h
@@ -58,7 +58,7 @@ struct JSFunction {
     uint8        flags;         /* bound method and other flags, see jsapi.h */
     uint8        spare;         /* reserved for future use */
     JSAtom       *atom;         /* name for diagnostics and decompiling */
-    JSClass      *clasp;        /* if non-null, constructor for this class */
+    const JSClass *clasp;       /* if non-null, constructor for this class */
     void	*priv;
 };
 
diff --git a/libswfdec/js/jsinterp.c b/libswfdec/js/jsinterp.c
index a9b4982..ff45d22 100644
--- a/libswfdec/js/jsinterp.c
+++ b/libswfdec/js/jsinterp.c
@@ -1393,7 +1393,7 @@ js_Interpret(JSContext *cx, jsval *resul
     JSString *str, *str2;
     jsint i, j;
     jsdouble d, d2;
-    JSClass *clasp, *funclasp;
+    const JSClass *clasp, *funclasp;
     JSFunction *fun;
     JSType type;
 #ifdef DEBUG
diff-tree 80aba02f5745e1aaa6cbf16370dfcda5f8bb5d9d (from e6fa9c03b3333781cfaa260d0001885c1527e368)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jan 16 10:01:06 2007 +0100

    constify JSClass functions as far as we need them

diff --git a/libswfdec/js/jsapi.c b/libswfdec/js/jsapi.c
index 75194b7..b98e232 100644
--- a/libswfdec/js/jsapi.c
+++ b/libswfdec/js/jsapi.c
@@ -2098,7 +2098,7 @@ JS_GetObjectId(JSContext *cx, JSObject *
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
+JS_NewObject(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent)
 {
     CHECK_REQUEST(cx);
     if (!clasp)
diff --git a/libswfdec/js/jsapi.h b/libswfdec/js/jsapi.h
index 441bf74..1718acc 100644
--- a/libswfdec/js/jsapi.h
+++ b/libswfdec/js/jsapi.h
@@ -930,7 +930,7 @@ extern JS_PUBLIC_API(JSBool)
 JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
+JS_NewObject(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep);
diff --git a/libswfdec/js/jsobj.c b/libswfdec/js/jsobj.c
index e7bb433..2033c97 100644
--- a/libswfdec/js/jsobj.c
+++ b/libswfdec/js/jsobj.c
@@ -1692,7 +1692,7 @@ JS_FRIEND_DATA(JSObjectOps) js_WithObjec
 };
 
 static JSObjectOps *
-with_getObjectOps(JSContext *cx, JSClass *clasp)
+with_getObjectOps(JSContext *cx, const JSClass *clasp)
 {
     return &js_WithObjectOps;
 }
@@ -1782,7 +1782,7 @@ js_InitObjectClass(JSContext *cx, JSObje
 
 void
 js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
-                 JSClass *clasp)
+                 const JSClass *clasp)
 {
     map->nrefs = nrefs;
     map->ops = ops;
@@ -1792,7 +1792,7 @@ js_InitObjectMap(JSObjectMap *map, jsref
 
 JSObjectMap *
 js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
-                JSClass *clasp, JSObject *obj)
+                const JSClass *clasp, JSObject *obj)
 {
     return (JSObjectMap *) js_NewScope(cx, nrefs, ops, clasp, obj);
 }
@@ -1830,7 +1830,7 @@ GetClassPrototype(JSContext *cx, JSObjec
                   JSObject **protop);
 
 JSObject *
-js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
+js_NewObject(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent)
 {
     JSObject *obj, *ctor;
     JSObjectOps *ops;
diff --git a/libswfdec/js/jsobj.h b/libswfdec/js/jsobj.h
index fd7b665..c358d79 100644
--- a/libswfdec/js/jsobj.h
+++ b/libswfdec/js/jsobj.h
@@ -277,11 +277,11 @@ extern const char js_lookupSetter_str[];
 
 extern void
 js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
-		 JSClass *clasp);
+		 const JSClass *clasp);
 
 extern JSObjectMap *
 js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
-		JSClass *clasp, JSObject *obj);
+		const JSClass *clasp, JSObject *obj);
 
 extern void
 js_DestroyObjectMap(JSContext *cx, JSObjectMap *map);
@@ -293,7 +293,7 @@ extern JSObjectMap *
 js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj);
 
 extern JSObject *
-js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
+js_NewObject(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent);
 
 extern JSObject *
 js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
diff --git a/libswfdec/js/jspubtd.h b/libswfdec/js/jspubtd.h
index 9dbfdff..1112e58 100644
--- a/libswfdec/js/jspubtd.h
+++ b/libswfdec/js/jspubtd.h
@@ -271,7 +271,7 @@ typedef void
  * code and data used by the native (js_ObjectOps, see jsobj.c) ops.
  */
 typedef JSObjectOps *
-(* JS_DLL_CALLBACK JSGetObjectOps)(JSContext *cx, JSClass *clasp);
+(* JS_DLL_CALLBACK JSGetObjectOps)(JSContext *cx, const JSClass *clasp);
 
 /*
  * JSClass.checkAccess type: check whether obj[id] may be accessed per mode,
@@ -343,7 +343,7 @@ typedef uint32
  */
 typedef JSObjectMap *
 (* JS_DLL_CALLBACK JSNewObjectMapOp)(JSContext *cx, jsrefcount nrefs,
-                                     JSObjectOps *ops, JSClass *clasp,
+                                     JSObjectOps *ops, const JSClass *clasp,
                                      JSObject *obj);
 
 /*
diff --git a/libswfdec/js/jsscope.c b/libswfdec/js/jsscope.c
index 20243e9..4b85a66 100644
--- a/libswfdec/js/jsscope.c
+++ b/libswfdec/js/jsscope.c
@@ -132,7 +132,7 @@ CreateScopeTable(JSScope *scope)
 }
 
 JSScope *
-js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
+js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, const JSClass *clasp,
             JSObject *obj)
 {
     JSScope *scope;
diff --git a/libswfdec/js/jsscope.h b/libswfdec/js/jsscope.h
index 4f66441..5d5ca45 100644
--- a/libswfdec/js/jsscope.h
+++ b/libswfdec/js/jsscope.h
@@ -336,7 +336,7 @@ extern JSScope *
 js_GetMutableScope(JSContext *cx, JSObject *obj);
 
 extern JSScope *
-js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
+js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, const JSClass *clasp,
             JSObject *obj);
 
 extern void


More information about the Swfdec mailing list