Benjamin Otte
2007-Mar-07 02:24 UTC
[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
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@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@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@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@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@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@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@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@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@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@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@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@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@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@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@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; }
Possibly Parallel Threads
- Branch 'as' - 8 commits - libswfdec/swfdec_movie.c libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_sprite_movie.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_swf_decoder.h
- Branch 'as' - 6 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_morph_movie.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_player.c libswfdec/swfdec_sprite.c
- libswfdec-gtk/swfdec_playback_alsa.c libswfdec/swfdec_audio_event.h libswfdec/swfdec_audio_flv.h libswfdec/swfdec_audio_stream.h libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_buffer.c libswfdec/swfdec_buffer.h libswfdec/swfdec_cache.c
- Branch 'as' - 9 commits - libswfdec-gtk/swfdec_playback_alsa.c libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c
- Branch 'as' - libswfdec/Makefile.am libswfdec/swfdec_root_movie.c libswfdec/swfdec_root_sprite.c libswfdec/swfdec_root_sprite.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_swf_decoder.h libswfdec/swfdec_tag.c