[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