[Swfdec] 11 commits - libswfdec/swfdec_event.c
libswfdec/swfdec_event.h libswfdec/swfdec_js_movie.c
libswfdec/swfdec_movie.c libswfdec/swfdec_scriptable.c
libswfdec/swfdec_scriptable.h libswfdec/swfdec_script.c
libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h
libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_swf_decoder.h
libswfdec/swfdec_tag.c player/swfdec_player_manager.c
test/dump.c test/trace
Benjamin Otte
company at kemper.freedesktop.org
Wed Mar 7 02:24:09 PST 2007
libswfdec/swfdec_event.c | 90 +++++++++++++++++++++++++++++++++---
libswfdec/swfdec_event.h | 3 +
libswfdec/swfdec_js_movie.c | 6 +-
libswfdec/swfdec_movie.c | 24 +++++++--
libswfdec/swfdec_script.c | 2
libswfdec/swfdec_scriptable.c | 68 +++++++++++++++++++++++++++
libswfdec/swfdec_scriptable.h | 6 ++
libswfdec/swfdec_sprite.c | 102 ++++++++++++++++++++---------------------
libswfdec/swfdec_sprite.h | 3 -
libswfdec/swfdec_swf_decoder.c | 39 +++------------
libswfdec/swfdec_swf_decoder.h | 8 +--
libswfdec/swfdec_tag.c | 3 -
player/swfdec_player_manager.c | 69 ++++++++++++++++-----------
test/dump.c | 68 ++++++++++++---------------
test/trace/Makefile.am | 2
15 files changed, 323 insertions(+), 170 deletions(-)
New commits:
diff-tree ca675ea7b69b11cbc58c1ee4ea94e95a50ef4a90 (from b83df26d3c0ff337c64e3108907b4b8f8f674805)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 21:30:53 2007 +0100
update to list -> hash table change in SwfdecSwfDecoder
diff --git a/test/dump.c b/test/dump.c
index efddeee..e248729 100644
--- a/test/dump.c
+++ b/test/dump.c
@@ -317,43 +317,39 @@ dump_image (SwfdecImage *image)
}
static void
-dump_objects (SwfdecSwfDecoder *s)
+dump_object (gpointer key, gpointer value, gpointer unused)
{
- GList *g;
- SwfdecCharacter *c;
+ SwfdecCharacter *c = value;
- for (g = g_list_last (s->characters); g; g = g->prev) {
- c = g->data;
- g_print ("%d: %s\n", c->id, G_OBJECT_TYPE_NAME (c));
- if (verbose && SWFDEC_IS_GRAPHIC (c)) {
- SwfdecGraphic *graphic = SWFDEC_GRAPHIC (c);
- g_print (" extents: %g %g %g %g\n", graphic->extents.x0, graphic->extents.y0,
- graphic->extents.x1, graphic->extents.y1);
- }
- if (SWFDEC_IS_IMAGE (c)) {
- dump_image (SWFDEC_IMAGE (c));
- }
- if (SWFDEC_IS_SPRITE (c)) {
- dump_sprite (SWFDEC_SPRITE (c));
- }
- if (SWFDEC_IS_SHAPE(c)) {
- dump_shape(SWFDEC_SHAPE(c));
- }
- if (SWFDEC_IS_TEXT (c)) {
- dump_text (SWFDEC_TEXT (c));
- }
- if (SWFDEC_IS_EDIT_TEXT (c)) {
- dump_edit_text (SWFDEC_EDIT_TEXT (c));
- }
- if (SWFDEC_IS_FONT (c)) {
- dump_font (SWFDEC_FONT (c));
- }
- if (SWFDEC_IS_BUTTON (c)) {
- dump_button (SWFDEC_BUTTON (c));
- }
- if (SWFDEC_IS_SOUND (c)) {
- dump_sound (SWFDEC_SOUND (c));
- }
+ g_print ("%d: %s\n", c->id, G_OBJECT_TYPE_NAME (c));
+ if (verbose && SWFDEC_IS_GRAPHIC (c)) {
+ SwfdecGraphic *graphic = SWFDEC_GRAPHIC (c);
+ g_print (" extents: %g %g %g %g\n", graphic->extents.x0, graphic->extents.y0,
+ graphic->extents.x1, graphic->extents.y1);
+ }
+ if (SWFDEC_IS_IMAGE (c)) {
+ dump_image (SWFDEC_IMAGE (c));
+ }
+ if (SWFDEC_IS_SPRITE (c)) {
+ dump_sprite (SWFDEC_SPRITE (c));
+ }
+ if (SWFDEC_IS_SHAPE(c)) {
+ dump_shape(SWFDEC_SHAPE(c));
+ }
+ if (SWFDEC_IS_TEXT (c)) {
+ dump_text (SWFDEC_TEXT (c));
+ }
+ if (SWFDEC_IS_EDIT_TEXT (c)) {
+ dump_edit_text (SWFDEC_EDIT_TEXT (c));
+ }
+ if (SWFDEC_IS_FONT (c)) {
+ dump_font (SWFDEC_FONT (c));
+ }
+ if (SWFDEC_IS_BUTTON (c)) {
+ dump_button (SWFDEC_BUTTON (c));
+ }
+ if (SWFDEC_IS_SOUND (c)) {
+ dump_sound (SWFDEC_SOUND (c));
}
}
@@ -406,7 +402,7 @@ main (int argc, char *argv[])
g_print (" rate : %g fps\n", SWFDEC_DECODER (s)->rate / 256.0);
g_print (" size : %ux%u pixels\n", SWFDEC_DECODER (s)->width, SWFDEC_DECODER (s)->height);
g_print ("objects:\n");
- dump_objects(s);
+ g_hash_table_foreach (s->characters, dump_object, NULL);
g_print ("main sprite:\n");
dump_sprite(s->main_sprite);
diff-tree b83df26d3c0ff337c64e3108907b4b8f8f674805 (from 99028e122d8c91ad4d6f56ef3d38205a4347b374)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 21:29:47 2007 +0100
keep a list of current contents while parsing for faster lookup when
tags affect them
diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index af7e913..84e6973 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -50,6 +50,10 @@ swfdec_sprite_dispose (GObject *object)
SwfdecSprite * sprite = SWFDEC_SPRITE (object);
unsigned int i;
+ if (sprite->live_content) {
+ g_hash_table_destroy (sprite->live_content);
+ sprite->live_content = NULL;
+ }
if (sprite->frames) {
for (i = 0; i < sprite->n_frames; i++) {
g_free (sprite->frames[i].label);
@@ -123,39 +127,7 @@ swfdec_sprite_add_sound_chunk (SwfdecSpr
static SwfdecContent *
swfdec_content_find (SwfdecSprite *sprite, int depth)
{
- guint i, j;
- SwfdecContent *content;
- static unsigned long long int count = 0;
-
- if (++count % 10000 == 0)
- g_print ("%llu\n", count);
-
- for (i = sprite->parse_frame; i <= sprite->parse_frame /* wait for underflow */; i--) {
- SwfdecSpriteFrame *frame = &sprite->frames[i];
- if (frame->actions == NULL)
- continue;
- for (j = frame->actions->len - 1; j < frame->actions->len; j--) {
- SwfdecSpriteAction *action =
- &g_array_index (frame->actions, SwfdecSpriteAction, j);
- switch (action->type) {
- case SWFDEC_SPRITE_ACTION_SCRIPT:
- break;
- case SWFDEC_SPRITE_ACTION_ADD:
- case SWFDEC_SPRITE_ACTION_UPDATE:
- content = action->data;
- if (content->depth == depth)
- return content;
- break;
- case SWFDEC_SPRITE_ACTION_REMOVE:
- if (GPOINTER_TO_INT (action->data) == depth)
- return NULL;
- break;
- default:
- g_assert_not_reached ();
- }
- }
- }
- return NULL;
+ return g_hash_table_lookup (sprite->live_content, GINT_TO_POINTER (depth));
}
static void
@@ -184,6 +156,30 @@ swfdec_content_update_lifetime (SwfdecSp
content->sequence->end = sprite->parse_frame;
}
+static void
+swfdec_content_update_live (SwfdecSprite *sprite,
+ SwfdecSpriteActionType type, gpointer data)
+{
+ SwfdecContent *content;
+ switch (type) {
+ case SWFDEC_SPRITE_ACTION_SCRIPT:
+ return;
+ case SWFDEC_SPRITE_ACTION_UPDATE:
+ case SWFDEC_SPRITE_ACTION_ADD:
+ content = data;
+ g_hash_table_insert (sprite->live_content,
+ GINT_TO_POINTER (content->depth), content);
+ break;
+ case SWFDEC_SPRITE_ACTION_REMOVE:
+ /* data is GINT_TO_POINTER (depth) */
+ g_hash_table_remove (sprite->live_content, data);
+ break;
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+}
+
/* NB: does not free the action data */
static void
swfdec_sprite_remove_last_action (SwfdecSprite * sprite, unsigned int frame_id)
@@ -212,6 +208,7 @@ swfdec_sprite_add_action (SwfdecSprite *
frame->actions = g_array_new (FALSE, FALSE, sizeof (SwfdecSpriteAction));
swfdec_content_update_lifetime (sprite, type, data);
+ swfdec_content_update_live (sprite, type, data);
action.type = type;
action.data = data;
g_array_append_val (frame->actions, action);
@@ -505,7 +502,7 @@ swfdec_sprite_class_init (SwfdecSpriteCl
static void
swfdec_sprite_init (SwfdecSprite * sprite)
{
-
+ sprite->live_content = g_hash_table_new (g_direct_hash, g_direct_equal);
}
void
diff --git a/libswfdec/swfdec_sprite.h b/libswfdec/swfdec_sprite.h
index d0e3bb8..f2e7be5 100644
--- a/libswfdec/swfdec_sprite.h
+++ b/libswfdec/swfdec_sprite.h
@@ -76,6 +76,7 @@ struct _SwfdecSprite
/* parse state */
unsigned int parse_frame; /* frame we're currently parsing. == n_frames if done parsing */
+ GHashTable * live_content; /* depth->SwfdecSpriteContent for every content in parse_frame */
};
struct _SwfdecSpriteClass
diff-tree 99028e122d8c91ad4d6f56ef3d38205a4347b374 (from 324a772186b03ab45ba730faa742ff35041d6a2a)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 17:21:10 2007 +0100
even more functions don't take a frame_id anymore but use parse_frame
diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index 1eeac3b..af7e913 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -121,12 +121,16 @@ swfdec_sprite_add_sound_chunk (SwfdecSpr
/* NB: we look in the current frame, too - so call this before adding actions
* that might modify the frame you're looking for */
static SwfdecContent *
-swfdec_content_find (SwfdecSprite *sprite, unsigned int frame_id, int depth)
+swfdec_content_find (SwfdecSprite *sprite, int depth)
{
guint i, j;
SwfdecContent *content;
+ static unsigned long long int count = 0;
- for (i = frame_id; i <= frame_id /* wait for underflow */; i--) {
+ if (++count % 10000 == 0)
+ g_print ("%llu\n", count);
+
+ for (i = sprite->parse_frame; i <= sprite->parse_frame /* wait for underflow */; i--) {
SwfdecSpriteFrame *frame = &sprite->frames[i];
if (frame->actions == NULL)
continue;
@@ -155,7 +159,7 @@ swfdec_content_find (SwfdecSprite *sprit
}
static void
-swfdec_content_update_lifetime (SwfdecSprite *sprite, unsigned int frame_id,
+swfdec_content_update_lifetime (SwfdecSprite *sprite,
SwfdecSpriteActionType type, gpointer data)
{
SwfdecContent *content;
@@ -174,10 +178,10 @@ swfdec_content_update_lifetime (SwfdecSp
g_assert_not_reached ();
return;
}
- content = swfdec_content_find (sprite, frame_id, depth);
+ content = swfdec_content_find (sprite, depth);
if (content == NULL)
return;
- content->sequence->end = frame_id;
+ content->sequence->end = sprite->parse_frame;
}
/* NB: does not free the action data */
@@ -207,7 +211,7 @@ swfdec_sprite_add_action (SwfdecSprite *
if (frame->actions == NULL)
frame->actions = g_array_new (FALSE, FALSE, sizeof (SwfdecSpriteAction));
- swfdec_content_update_lifetime (sprite, sprite->parse_frame, type, data);
+ swfdec_content_update_lifetime (sprite, type, data);
action.type = type;
action.data = data;
g_array_append_val (frame->actions, action);
@@ -289,7 +293,7 @@ swfdec_contents_create (SwfdecSprite *sp
if (copy) {
SwfdecContent *copy;
- copy = swfdec_content_find (sprite, sprite->parse_frame, depth);
+ copy = swfdec_content_find (sprite, depth);
if (copy == NULL) {
SWFDEC_WARNING ("Couldn't copy depth %u in frame %u", depth, sprite->parse_frame);
} else {
diff-tree 324a772186b03ab45ba730faa742ff35041d6a2a (from ed9874096d7a17d4a9b37235ff1a777c263a7c44)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 15:02:06 2007 +0100
make the frame_id implicit in some calls
diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index f5496b9..1eeac3b 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -195,19 +195,19 @@ swfdec_sprite_remove_last_action (Swfdec
}
void
-swfdec_sprite_add_action (SwfdecSprite * sprite, unsigned int frame_id,
- SwfdecSpriteActionType type, gpointer data)
+swfdec_sprite_add_action (SwfdecSprite *sprite, SwfdecSpriteActionType type,
+ gpointer data)
{
SwfdecSpriteAction action;
SwfdecSpriteFrame *frame;
- g_assert (frame_id < sprite->n_frames);
- frame = &sprite->frames[frame_id];
+ g_assert (sprite->parse_frame < sprite->n_frames);
+ frame = &sprite->frames[sprite->parse_frame];
if (frame->actions == NULL)
frame->actions = g_array_new (FALSE, FALSE, sizeof (SwfdecSpriteAction));
- swfdec_content_update_lifetime (sprite, frame_id, type, data);
+ swfdec_content_update_lifetime (sprite, sprite->parse_frame, type, data);
action.type = type;
action.data = data;
g_array_append_val (frame->actions, action);
@@ -279,19 +279,19 @@ swfdec_content_new (int depth)
}
static SwfdecContent *
-swfdec_contents_create (SwfdecSprite *sprite, unsigned int frame_id,
+swfdec_contents_create (SwfdecSprite *sprite,
int depth, gboolean copy, gboolean new)
{
SwfdecContent *content = swfdec_content_new (depth);
- content->start = frame_id;
+ content->start = sprite->parse_frame;
content->end = sprite->n_frames;
if (copy) {
SwfdecContent *copy;
- copy = swfdec_content_find (sprite, frame_id, depth);
+ copy = swfdec_content_find (sprite, sprite->parse_frame, depth);
if (copy == NULL) {
- SWFDEC_WARNING ("Couldn't copy depth %u in frame %u", depth, frame_id);
+ SWFDEC_WARNING ("Couldn't copy depth %u in frame %u", depth, sprite->parse_frame);
} else {
*content = *copy;
SWFDEC_LOG ("Copying from content %p", copy);
@@ -300,15 +300,15 @@ swfdec_contents_create (SwfdecSprite *sp
if (content->events)
content->events = swfdec_event_list_copy (copy->events);
if (new) {
- content->start = frame_id;
+ content->start = sprite->parse_frame;
content->end = sprite->n_frames;
}
- swfdec_sprite_add_action (sprite, frame_id,
+ swfdec_sprite_add_action (sprite,
new ? SWFDEC_SPRITE_ACTION_ADD : SWFDEC_SPRITE_ACTION_UPDATE, content);
return content;
}
}
- swfdec_sprite_add_action (sprite, frame_id, SWFDEC_SPRITE_ACTION_ADD, content);
+ swfdec_sprite_add_action (sprite, SWFDEC_SPRITE_ACTION_ADD, content);
return content;
}
@@ -349,8 +349,7 @@ swfdec_spriteseg_place_object_2 (SwfdecS
depth -= 16384;
/* new name always means new object */
- content = swfdec_contents_create (s->parse_sprite,
- s->parse_sprite->parse_frame, depth, move, has_character || has_name);
+ content = swfdec_contents_create (s->parse_sprite, depth, move, has_character || has_name);
if (has_character) {
int id = swfdec_bits_get_u16 (bits);
content->graphic = swfdec_swf_decoder_get_character (s, id);
@@ -460,8 +459,7 @@ swfdec_spriteseg_remove_object (SwfdecSw
depth = swfdec_bits_get_u16 (&s->b);
SWFDEC_LOG (" depth = %d (=> %d)", depth, depth - 16384);
depth -= 16384;
- swfdec_sprite_add_action (s->parse_sprite, s->parse_sprite->parse_frame,
- SWFDEC_SPRITE_ACTION_REMOVE, GINT_TO_POINTER (depth));
+ swfdec_sprite_add_action (s->parse_sprite, SWFDEC_SPRITE_ACTION_REMOVE, GINT_TO_POINTER (depth));
return SWFDEC_STATUS_OK;
}
@@ -474,8 +472,7 @@ swfdec_spriteseg_remove_object_2 (Swfdec
depth = swfdec_bits_get_u16 (&s->b);
SWFDEC_LOG (" depth = %u", depth);
depth -= 16384;
- swfdec_sprite_add_action (s->parse_sprite, s->parse_sprite->parse_frame,
- SWFDEC_SPRITE_ACTION_REMOVE, GINT_TO_POINTER (depth));
+ swfdec_sprite_add_action (s->parse_sprite, SWFDEC_SPRITE_ACTION_REMOVE, GINT_TO_POINTER (depth));
return SWFDEC_STATUS_OK;
}
diff --git a/libswfdec/swfdec_sprite.h b/libswfdec/swfdec_sprite.h
index e4c7467..d0e3bb8 100644
--- a/libswfdec/swfdec_sprite.h
+++ b/libswfdec/swfdec_sprite.h
@@ -89,7 +89,7 @@ int tag_func_define_sprite (SwfdecSwfDec
void swfdec_sprite_add_sound_chunk (SwfdecSprite * sprite, unsigned int frame,
SwfdecBuffer * chunk, int skip, unsigned int n_samples);
void swfdec_sprite_set_n_frames (SwfdecSprite *sprite, unsigned int n_frames, unsigned int rate);
-void swfdec_sprite_add_action (SwfdecSprite * sprite, unsigned int frame,
+void swfdec_sprite_add_action (SwfdecSprite * sprite,
SwfdecSpriteActionType type, gpointer data);
unsigned int swfdec_sprite_get_next_frame (SwfdecSprite *sprite, unsigned int current_frame);
int swfdec_sprite_get_frame (SwfdecSprite * sprite,
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index fab6c1f..c81d3b9 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -276,8 +276,7 @@ tag_func_do_action (SwfdecSwfDecoder * s
script = swfdec_script_new_for_player (SWFDEC_DECODER (s)->player, &s->b, name, s->version);
g_free (name);
if (script)
- swfdec_sprite_add_action (s->parse_sprite, s->parse_sprite->parse_frame,
- SWFDEC_SPRITE_ACTION_SCRIPT, script);
+ swfdec_sprite_add_action (s->parse_sprite, SWFDEC_SPRITE_ACTION_SCRIPT, script);
return SWFDEC_STATUS_OK;
}
diff-tree ed9874096d7a17d4a9b37235ff1a777c263a7c44 (from 0edfa987b4002895c7634cd98a4302b5af0ed02f)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 14:55:32 2007 +0100
use a hash table to store characters for faster indexing by id
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index 2a45d5e..5ceb57b 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.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
@@ -52,8 +52,7 @@ swfdec_decoder_dispose (GObject *object)
{
SwfdecSwfDecoder *s = SWFDEC_SWF_DECODER (object);
- g_list_foreach (s->characters, (GFunc) g_object_unref, NULL);
- g_list_free (s->characters);
+ g_hash_table_destroy (s->characters);
g_object_unref (s->main_sprite);
g_hash_table_destroy (s->exports);
@@ -85,20 +84,6 @@ zfree (void *opaque, void *addr)
g_free (addr);
}
-#if 0
-static void
-dumpbits (SwfdecBits * b)
-{
- int i;
-
- printf (" ");
- for (i = 0; i < 16; i++) {
- printf ("%02x ", swfdec_bits_get_u8 (b));
- }
- printf ("\n");
-}
-#endif
-
static gboolean
swfdec_swf_decoder_deflate_all (SwfdecSwfDecoder * s)
{
@@ -359,6 +344,8 @@ swfdec_swf_decoder_init (SwfdecSwfDecode
{
s->main_sprite = g_object_new (SWFDEC_TYPE_SPRITE, NULL);
+ s->characters = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_object_unref);
s->input_queue = swfdec_buffer_queue_new ();
s->exports = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
@@ -376,20 +363,11 @@ swfdec_swf_decoder_get_export (SwfdecSwf
}
gpointer
-swfdec_swf_decoder_get_character (SwfdecSwfDecoder * s, int id)
+swfdec_swf_decoder_get_character (SwfdecSwfDecoder * s, unsigned int id)
{
- SwfdecCharacter *character;
- GList *g;
-
g_return_val_if_fail (SWFDEC_IS_SWF_DECODER (s), NULL);
- for (g = s->characters; g; g = g_list_next (g)) {
- character = SWFDEC_CHARACTER (g->data);
- if (character->id == id)
- return character;
- }
-
- return NULL;
+ return g_hash_table_lookup (s->characters, GUINT_TO_POINTER (id));
}
/**
@@ -405,12 +383,11 @@ swfdec_swf_decoder_get_character (Swfdec
* Returns: The requested character or NULL on failure;
**/
gpointer
-swfdec_swf_decoder_create_character (SwfdecSwfDecoder * s, int id, GType type)
+swfdec_swf_decoder_create_character (SwfdecSwfDecoder * s, unsigned int id, GType type)
{
SwfdecCharacter *result;
g_return_val_if_fail (SWFDEC_IS_DECODER (s), NULL);
- g_return_val_if_fail (id >= 0, NULL);
g_return_val_if_fail (g_type_is_a (type, SWFDEC_TYPE_CHARACTER), NULL);
SWFDEC_INFO (" id = %d", id);
@@ -421,7 +398,7 @@ swfdec_swf_decoder_create_character (Swf
}
result = g_object_new (type, NULL);
result->id = id;
- s->characters = g_list_prepend (s->characters, result);
+ g_hash_table_insert (s->characters, GUINT_TO_POINTER (id), result);
if (SWFDEC_IS_CACHED (result)) {
swfdec_cached_set_cache (SWFDEC_CACHED (result), SWFDEC_DECODER (s)->player->cache);
}
diff --git a/libswfdec/swfdec_swf_decoder.h b/libswfdec/swfdec_swf_decoder.h
index 5d2109f..48541eb 100644
--- a/libswfdec/swfdec_swf_decoder.h
+++ b/libswfdec/swfdec_swf_decoder.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
@@ -59,7 +59,7 @@ struct _SwfdecSwfDecoder
SwfdecBits b; /* temporary state while parsing */
/* defined objects */
- GList *characters; /* list of all objects with an id (called characters) */
+ GHashTable *characters; /* list of all objects with an id (called characters) */
SwfdecSprite *main_sprite;
SwfdecSprite *parse_sprite;
@@ -79,9 +79,9 @@ struct _SwfdecSwfDecoderClass {
GType swfdec_swf_decoder_get_type (void);
gpointer swfdec_swf_decoder_get_character (SwfdecSwfDecoder * s,
- int id);
+ unsigned int id);
gpointer swfdec_swf_decoder_create_character (SwfdecSwfDecoder * s,
- int id,
+ unsigned int id,
GType type);
gpointer swfdec_swf_decoder_get_export (SwfdecSwfDecoder * s,
const char * name);
diff-tree 0edfa987b4002895c7634cd98a4302b5af0ed02f (from 6a39b304d10aecf93c35c23390e649a9994cca89)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 13:15:19 2007 +0100
add event-order tets that checks onFoo and foo events are executed in the right order
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index d087ed3..e1c8e02 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -55,6 +55,8 @@ EXTRA_DIST = \
currentframe.swf.trace \
double.swf \
double.swf.trace \
+ event-order.swf \
+ event-order.swf.trace \
function1.swf \
function1.swf.trace \
function2.swf \
diff-tree 6a39b304d10aecf93c35c23390e649a9994cca89 (from e472a12007feae2e81d257b5f1e826cc68d7586a)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 13:14:20 2007 +0100
add support for onFoo events in addition to frame events loaded from the file
diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c
index d988ad3..06526fa 100644
--- a/libswfdec/swfdec_event.c
+++ b/libswfdec/swfdec_event.c
@@ -41,6 +41,75 @@ struct _SwfdecEventList {
GArray * events;
};
+static const char *event_names[] = {
+ "onLoad",
+ "onEnterFrame",
+ "onUnload",
+ "onMouseMove",
+ "onMouseDown",
+ "onMouseUp",
+ "onKeyUp",
+ "onKeyDown",
+ "onData",
+ NULL,
+ "onPress",
+ "onRelease",
+ "onReleaseOutside",
+ "onRollOver",
+ "onRollOut",
+ "onDragOver",
+ "onDragOut",
+ NULL,
+ NULL
+};
+
+const char *
+swfdec_event_type_get_name (SwfdecEventType type)
+{
+ switch (type) {
+ case SWFDEC_EVENT_LOAD:
+ return event_names[0];
+ case SWFDEC_EVENT_ENTER:
+ return event_names[1];
+ case SWFDEC_EVENT_UNLOAD:
+ return event_names[2];
+ case SWFDEC_EVENT_MOUSE_MOVE:
+ return event_names[3];
+ case SWFDEC_EVENT_MOUSE_DOWN:
+ return event_names[4];
+ case SWFDEC_EVENT_MOUSE_UP:
+ return event_names[5];
+ case SWFDEC_EVENT_KEY_UP:
+ return event_names[6];
+ case SWFDEC_EVENT_KEY_DOWN:
+ return event_names[7];
+ case SWFDEC_EVENT_DATA:
+ return event_names[8];
+ case SWFDEC_EVENT_INITIALIZE:
+ return event_names[9];
+ case SWFDEC_EVENT_PRESS:
+ return event_names[10];
+ case SWFDEC_EVENT_RELEASE:
+ return event_names[11];
+ case SWFDEC_EVENT_RELEASE_OUTSIDE:
+ return event_names[12];
+ case SWFDEC_EVENT_ROLL_OVER:
+ return event_names[13];
+ case SWFDEC_EVENT_ROLL_OUT:
+ return event_names[14];
+ case SWFDEC_EVENT_DRAG_OVER:
+ return event_names[15];
+ case SWFDEC_EVENT_DRAG_OUT:
+ return event_names[16];
+ case SWFDEC_EVENT_KEY_PRESS:
+ return event_names[17];
+ case SWFDEC_EVENT_CONSTRUCT:
+ return event_names[18];
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+}
SwfdecEventList *
swfdec_event_list_new (SwfdecPlayer *player)
@@ -154,36 +223,45 @@ swfdec_event_list_parse (SwfdecEventList
void
swfdec_event_list_execute (SwfdecEventList *list, SwfdecScriptable *scriptable,
- unsigned int conditions, guint8 key)
+ unsigned int condition, guint8 key)
{
unsigned int i;
+ const char *name;
g_return_if_fail (list != NULL);
for (i = 0; i < list->events->len; i++) {
SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
- if ((event->conditions & conditions) &&
+ if ((event->conditions & condition) &&
event->key == key) {
- SWFDEC_LOG ("executing script for event %u on scriptable %p", conditions, scriptable);
+ SWFDEC_LOG ("executing script for event %u on scriptable %p", condition, scriptable);
swfdec_script_execute (event->script, scriptable);
}
}
+ name = swfdec_event_type_get_name (condition);
+ if (name)
+ swfdec_scriptable_execute (scriptable, name, 0, NULL);
}
gboolean
-swfdec_event_list_has_conditions (SwfdecEventList *list,
- unsigned int conditions, guint8 key)
+swfdec_event_list_has_conditions (SwfdecEventList *list, SwfdecScriptable *scriptable,
+ unsigned int condition, guint8 key)
{
unsigned int i;
+ const char *name;
g_return_val_if_fail (list != NULL, FALSE);
+ g_return_val_if_fail (SWFDEC_IS_SCRIPTABLE (scriptable), FALSE);
for (i = 0; i < list->events->len; i++) {
SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i);
- if ((event->conditions & conditions) &&
+ if ((event->conditions & condition) &&
event->key == key)
return TRUE;
}
+ name = swfdec_event_type_get_name (condition);
+ if (name)
+ return swfdec_scriptable_can_execute (scriptable, name);
return FALSE;
}
diff --git a/libswfdec/swfdec_event.h b/libswfdec/swfdec_event.h
index 2906bb4..768dc8d 100644
--- a/libswfdec/swfdec_event.h
+++ b/libswfdec/swfdec_event.h
@@ -48,6 +48,8 @@ typedef enum _SwfdecEventType {
SWFDEC_EVENT_CONSTRUCT = (1 << 18)
} SwfdecEventType;
+const char * swfdec_event_type_get_name (SwfdecEventType type);
+
SwfdecEventList * swfdec_event_list_new (SwfdecPlayer * player);
SwfdecEventList * swfdec_event_list_copy (SwfdecEventList * list);
void swfdec_event_list_free (SwfdecEventList * list);
@@ -63,6 +65,7 @@ void swfdec_event_list_execute (Swfdec
unsigned int condition,
guint8 key);
gboolean swfdec_event_list_has_conditions(SwfdecEventList * list,
+ SwfdecScriptable * scriptable,
unsigned int conditions,
guint8 key);
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index a1df353..0e7715c 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -339,8 +339,14 @@ swfdec_movie_execute_script (gpointer mo
SwfdecMovie *movie = moviep;
guint condition = GPOINTER_TO_UINT (data);
- g_assert (movie->content->events);
- swfdec_event_list_execute (movie->content->events, SWFDEC_SCRIPTABLE (movie), condition, 0);
+ if (movie->content->events) {
+ swfdec_event_list_execute (movie->content->events,
+ SWFDEC_SCRIPTABLE (movie), condition, 0);
+ } else {
+ const char *name = swfdec_event_type_get_name (condition);
+ if (name != NULL)
+ swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (movie), name, 0, NULL);
+ }
}
/**
@@ -360,10 +366,16 @@ swfdec_movie_queue_script (SwfdecMovie *
g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), FALSE);
g_return_val_if_fail (condition != 0, FALSE);
- if (movie->content->events == NULL)
- return FALSE;
- if (!swfdec_event_list_has_conditions (movie->content->events, condition, 0))
- return FALSE;
+ if (movie->content->events) {
+ if (!swfdec_event_list_has_conditions (movie->content->events,
+ SWFDEC_SCRIPTABLE (movie), condition, 0))
+ return FALSE;
+ } else {
+ const char *name = swfdec_event_type_get_name (condition);
+ if (name == NULL ||
+ !swfdec_scriptable_can_execute (SWFDEC_SCRIPTABLE (movie), name))
+ return FALSE;
+ }
player = SWFDEC_ROOT_MOVIE (movie->root)->player;
swfdec_player_add_action (player, movie, swfdec_movie_execute_script,
diff-tree e472a12007feae2e81d257b5f1e826cc68d7586a (from ce1244ddd18afd0ce1b83999304ac5b9282c7564)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 13:03:53 2007 +0100
output trace messages in the window
requires some refactoring of the order in which functions are defined, so
this diff looks bigger than it really is
diff --git a/player/swfdec_player_manager.c b/player/swfdec_player_manager.c
index 31e9772..b0bdc55 100644
--- a/player/swfdec_player_manager.c
+++ b/player/swfdec_player_manager.c
@@ -41,9 +41,40 @@ enum {
MESSAGE,
LAST_SIGNAL
};
+guint signals[LAST_SIGNAL];
+
+/*** command handling ***/
+
+typedef enum {
+ SWFDEC_MESSAGE_INPUT,
+ SWFDEC_MESSAGE_OUTPUT,
+ SWFDEC_MESSAGE_ERROR
+} SwfdecMessageType;
+
+static void
+swfdec_player_manager_send_message (SwfdecPlayerManager *manager,
+ SwfdecMessageType type, char *format, ...) G_GNUC_PRINTF (3, 4);
+static void
+swfdec_player_manager_send_message (SwfdecPlayerManager *manager,
+ SwfdecMessageType type, char *format, ...)
+{
+ va_list args;
+ char *msg;
+
+ va_start (args, format);
+ msg = g_strdup_vprintf (format, args);
+ va_end (args);
+ g_signal_emit (manager, signals[MESSAGE], 0, (guint) type, msg);
+ g_free (msg);
+}
+#define swfdec_player_manager_output(manager, ...) \
+ swfdec_player_manager_send_message (manager, SWFDEC_MESSAGE_OUTPUT, __VA_ARGS__)
+#define swfdec_player_manager_error(manager, ...) \
+ swfdec_player_manager_send_message (manager, SWFDEC_MESSAGE_ERROR, __VA_ARGS__)
+
+/*** SWFDEC_PLAYER_MANAGER ***/
G_DEFINE_TYPE (SwfdecPlayerManager, swfdec_player_manager, G_TYPE_OBJECT)
-guint signals[LAST_SIGNAL];
static void
swfdec_player_manager_get_property (GObject *object, guint param_id, GValue *value,
@@ -89,6 +120,12 @@ swfdec_player_manager_set_property (GObj
static void breakpoint_hit_cb (SwfdecDebugger *debugger, guint id, SwfdecPlayerManager *manager);
static void
+trace_cb (SwfdecPlayer *player, const char *str, SwfdecPlayerManager *manager)
+{
+ swfdec_player_manager_output (manager, "Trace: %s", str);
+}
+
+static void
swfdec_player_manager_set_player (SwfdecPlayerManager *manager, SwfdecPlayer *player)
{
if (manager->player == player)
@@ -102,6 +139,7 @@ swfdec_player_manager_set_player (Swfdec
if (player) {
g_object_ref (player);
g_signal_connect (player, "breakpoint", G_CALLBACK (breakpoint_hit_cb), manager);
+ g_signal_connect (player, "trace", G_CALLBACK (trace_cb), manager);
}
}
@@ -293,34 +331,7 @@ swfdec_player_manager_continue (SwfdecPl
g_main_loop_quit (manager->interrupt_loop);
}
-/*** command handling ***/
-
-typedef enum {
- SWFDEC_MESSAGE_INPUT,
- SWFDEC_MESSAGE_OUTPUT,
- SWFDEC_MESSAGE_ERROR
-} SwfdecMessageType;
-
-static void
-swfdec_player_manager_send_message (SwfdecPlayerManager *manager,
- SwfdecMessageType type, char *format, ...) G_GNUC_PRINTF (3, 4);
-static void
-swfdec_player_manager_send_message (SwfdecPlayerManager *manager,
- SwfdecMessageType type, char *format, ...)
-{
- va_list args;
- char *msg;
-
- va_start (args, format);
- msg = g_strdup_vprintf (format, args);
- va_end (args);
- g_signal_emit (manager, signals[MESSAGE], 0, (guint) type, msg);
- g_free (msg);
-}
-#define swfdec_player_manager_output(manager, ...) \
- swfdec_player_manager_send_message (manager, SWFDEC_MESSAGE_OUTPUT, __VA_ARGS__)
-#define swfdec_player_manager_error(manager, ...) \
- swfdec_player_manager_send_message (manager, SWFDEC_MESSAGE_ERROR, __VA_ARGS__)
+/*** commands ***/
const char *
parse_skip (const char *input)
diff-tree ce1244ddd18afd0ce1b83999304ac5b9282c7564 (from 5e9b7d35d8857e9eb5377b28205ec1ba1bba6ea0)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 13:02:49 2007 +0100
Add swfdec_scriptable_(can_)execute
- swfdec_scriptable_can_execute checks if a property of a given name exists
and can be executed
- swfdec_scriptable_execute executes that property if it exists
diff --git a/libswfdec/swfdec_scriptable.c b/libswfdec/swfdec_scriptable.c
index 6554666..951a726 100644
--- a/libswfdec/swfdec_scriptable.c
+++ b/libswfdec/swfdec_scriptable.c
@@ -25,6 +25,8 @@
#include "swfdec_debug.h"
#include "swfdec_loader_internal.h"
#include "js/jsapi.h"
+#include "js/jsfun.h"
+#include "js/jsinterp.h"
G_DEFINE_ABSTRACT_TYPE (SwfdecScriptable, swfdec_scriptable, G_TYPE_OBJECT)
@@ -234,3 +236,69 @@ swfdec_scriptable_set_variables (SwfdecS
}
}
+/**
+ * swfdec_scriptable_execute:
+ * @script: a #SwfdecScriptable
+ * @name: property name that contains the handler
+ * @n_args: number of arguments to pass to handler
+ * @args: @n_args arguments that will be passed to handler
+ *
+ * Executes a callback function (like onMouseMove) on the scriptable if it is
+ * defined.
+ **/
+void
+swfdec_scriptable_execute (SwfdecScriptable *script, const char *name,
+ guint n_args, jsval *args)
+{
+ JSObject *obj;
+ jsval fun;
+
+ g_return_if_fail (SWFDEC_IS_SCRIPTABLE (script));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (n_args == 0 || args != NULL);
+
+ obj = swfdec_scriptable_get_object (script);
+ if (!obj)
+ return;
+ if (!JS_GetProperty (script->jscx, obj, name, &fun))
+ return;
+ if (!JSVAL_IS_OBJECT (fun) || fun == JSVAL_NULL ||
+ JS_GetClass (JSVAL_TO_OBJECT (fun)) != &js_FunctionClass) {
+ SWFDEC_LOG ("scriptable has no handler for %s event", name);
+ return;
+ }
+ js_InternalCall (script->jscx, obj, fun, n_args, args, &fun);
+}
+
+/**
+ * swfdec_scriptable_can_execute:
+ * @script: a #SwfdecScriptable
+ * @name: name of the function
+ *
+ * Checks if @script contains a function property named @name that can be
+ * executed via swfdec_scriptable_execute().
+ *
+ * Returns: %TRUE if such a function exists, %FALSE otherwise
+ **/
+gboolean
+swfdec_scriptable_can_execute (SwfdecScriptable *script, const char *name)
+{
+ JSObject *obj;
+ jsval fun;
+
+ g_return_val_if_fail (SWFDEC_IS_SCRIPTABLE (script), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ obj = swfdec_scriptable_get_object (script);
+ if (!obj)
+ return FALSE;
+ if (!JS_GetProperty (script->jscx, obj, name, &fun))
+ return FALSE;
+ if (!JSVAL_IS_OBJECT (fun) || fun == JSVAL_NULL ||
+ JS_GetClass (JSVAL_TO_OBJECT (fun)) != &js_FunctionClass) {
+ SWFDEC_LOG ("scriptable has no handler for %s event", name);
+ return FALSE;
+ }
+ return TRUE;
+}
+
diff --git a/libswfdec/swfdec_scriptable.h b/libswfdec/swfdec_scriptable.h
index a197d8f..a53ca4a 100644
--- a/libswfdec/swfdec_scriptable.h
+++ b/libswfdec/swfdec_scriptable.h
@@ -66,6 +66,12 @@ gpointer swfdec_scriptable_from_object
void swfdec_scriptable_set_variables (SwfdecScriptable * script,
const char * variables);
+gboolean swfdec_scriptable_can_execute (SwfdecScriptable * script,
+ const char * name);
+void swfdec_scriptable_execute (SwfdecScriptable * script,
+ const char * name,
+ guint n_args,
+ jsval * args);
G_END_DECLS
diff-tree 5e9b7d35d8857e9eb5377b28205ec1ba1bba6ea0 (from c2b82521e27908e41d3f3fd354f9a73c51ee26df)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 12:57:32 2007 +0100
really delete properties, don't just pretend to
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index 1c4d80a..2a860a4 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1153,6 +1153,7 @@ swfdec_js_movie_remove_property (SwfdecM
JSObject *jsobj;
JSContext *cx;
JSBool found = JS_FALSE;
+ jsval deleted = JSVAL_FALSE;
if (!movie->has_name ||
script->jsobj == NULL)
@@ -1168,9 +1169,10 @@ swfdec_js_movie_remove_property (SwfdecM
}
SWFDEC_LOG ("removing %s as property", movie->name);
- if (!JS_SetPropertyAttributes (cx, jsobj, movie->name, JSPROP_READONLY | JSPROP_PERMANENT, &found) ||
+ if (!JS_SetPropertyAttributes (cx, jsobj, movie->name, 0, &found) ||
found != JS_TRUE ||
- !JS_DeleteProperty (cx, jsobj, movie->name)) {
+ !JS_DeleteProperty2 (cx, jsobj, movie->name, &deleted) ||
+ deleted == JSVAL_FALSE) {
SWFDEC_ERROR ("could not remove property %s correctly", movie->name);
}
}
diff-tree c2b82521e27908e41d3f3fd354f9a73c51ee26df (from beacb0853da743a6505e50517683ab6541db0b39)
Author: Benjamin Otte <otte at gnome.org>
Date: Tue Mar 6 12:56:51 2007 +0100
apaprently i'm too stupid to implement ActionSwap correctly
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index f00a6f1..88b1b1d 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1902,7 +1902,7 @@ swfdec_action_swap (JSContext *cx, guint
{
jsval tmp = cx->fp->sp[-2];
cx->fp->sp[-2] = cx->fp->sp[-1];
- cx->fp->sp[-2] = tmp;
+ cx->fp->sp[-1] = tmp;
return JS_TRUE;
}
More information about the Swfdec
mailing list