[Swfdec-commits] 10 commits - swfdec/swfdec_actor.c swfdec/swfdec_actor.h swfdec/swfdec_key_as.c swfdec/swfdec_movie.c swfdec/swfdec_player.c swfdec/swfdec_player_internal.h swfdec/swfdec_sprite.c swfdec/swfdec_sprite.h swfdec/swfdec_sprite_movie_as.c swfdec/swfdec_sprite_movie.c swfdec/swfdec_tag.c test/custom test/trace

Pekka Lampila medar at kemper.freedesktop.org
Sun May 4 11:09:40 PDT 2008


 swfdec/swfdec_actor.c                   |   28 ++++++--
 swfdec/swfdec_actor.h                   |    6 +
 swfdec/swfdec_key_as.c                  |   17 ++++
 swfdec/swfdec_movie.c                   |    2 
 swfdec/swfdec_player.c                  |   64 +++++++++++++++++-
 swfdec/swfdec_player_internal.h         |    1 
 swfdec/swfdec_sprite.c                  |   13 ++-
 swfdec/swfdec_sprite.h                  |    2 
 swfdec/swfdec_sprite_movie.c            |    2 
 swfdec/swfdec_sprite_movie_as.c         |    2 
 swfdec/swfdec_tag.c                     |   12 ++-
 test/custom/Makefile.am                 |    5 +
 test/custom/key-isdown-mouse.as         |   17 ++++
 test/custom/key-isdown-mouse.stas       |   58 ++++++++++++++++
 test/custom/key-isdown-mouse.sts        |binary
 test/custom/key-isdown-mouse.swf        |binary
 test/trace/Makefile.am                  |    6 +
 test/trace/gotolabel-multiple.swf       |binary
 test/trace/gotolabel-multiple.swf.trace |    3 
 test/trace/gotolabel-multiple.xml       |  110 ++++++++++++++++++++++++++++++++
 test/trace/gotolabel.swf                |binary
 test/trace/gotolabel.swf.trace          |    2 
 test/trace/gotolabel.xml                |   70 ++++++++++++++++++++
 23 files changed, 394 insertions(+), 26 deletions(-)

New commits:
commit 881f351b88b56d04c75d5e3db97c23a423d4ab23
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun May 4 19:38:07 2008 +0300

    Implement key press events

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index fd69cc6..b2478cd 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -1568,10 +1568,52 @@ swfdec_player_handle_special_keys_after (SwfdecPlayer *player, guint key)
   }
 }
 
+static guint8
+swfdec_player_get_conditional_key (guint keycode, guint character)
+{
+  static guint special_keys[] = {
+    0,
+    SWFDEC_KEY_LEFT,
+    SWFDEC_KEY_RIGHT,
+    SWFDEC_KEY_HOME,
+    SWFDEC_KEY_END,
+    SWFDEC_KEY_INSERT,
+    SWFDEC_KEY_DELETE,
+    0,
+    SWFDEC_KEY_BACKSPACE,
+    0,
+    0,
+    0,
+    0,
+    SWFDEC_KEY_ENTER,
+    SWFDEC_KEY_UP,
+    SWFDEC_KEY_DOWN,
+    SWFDEC_KEY_PAGE_UP,
+    SWFDEC_KEY_PAGE_DOWN,
+    SWFDEC_KEY_TAB,
+    SWFDEC_KEY_ESCAPE
+  };
+  guint i;
+
+  if (keycode != 0) {
+    for (i = 0; i < G_N_ELEMENTS (special_keys); i++) {
+      if (special_keys[i] == keycode)
+	return i;
+    }
+  }
+
+  if (character >= 32 && character <= 126)
+    return character;
+
+  return 0;
+}
+
 static gboolean
 swfdec_player_do_handle_key (SwfdecPlayer *player, guint keycode, guint character, gboolean down)
 {
   SwfdecPlayerPrivate *priv = player->priv;
+  GList *walk;
+
   g_assert (keycode < 256);
 
   if (!swfdec_player_lock (player))
@@ -1584,10 +1626,22 @@ swfdec_player_do_handle_key (SwfdecPlayer *player, guint keycode, guint characte
   } else {
     priv->key_pressed[keycode / 8] &= ~(1 << keycode % 8);
   }
+
   if (down)
     swfdec_player_handle_special_keys_before (player, keycode);
+
+  if (down) {
+    guint8 cond = swfdec_player_get_conditional_key (keycode, character);
+
+    for (walk = priv->actors; walk; walk = walk->next) {
+      swfdec_actor_queue_script_with_key (walk->data, SWFDEC_EVENT_KEY_PRESS,
+	  cond);
+    }
+  }
+
   swfdec_player_broadcast (player, SWFDEC_AS_STR_Key, 
       down ? SWFDEC_AS_STR_onKeyDown : SWFDEC_AS_STR_onKeyUp, 0, NULL);
+
   if (priv->focus) {
     SwfdecActorClass *klass = SWFDEC_ACTOR_GET_CLASS (priv->focus);
     if (down) {
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 7735dd6..fa3fba8 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -284,7 +284,7 @@ swfdec_sprite_movie_perform_place (SwfdecSpriteMovie *movie, SwfdecBits *bits, g
 
       SWFDEC_INFO ("clip event with flags 0x%X, key code %d", event_flags, key_code);
 #define SWFDEC_UNIMPLEMENTED_EVENTS \
-  ((1<< SWFDEC_EVENT_DATA) | (1<<SWFDEC_EVENT_KEY_PRESS))
+  ((1<< SWFDEC_EVENT_DATA))
       if (event_flags & SWFDEC_UNIMPLEMENTED_EVENTS) {
 	SWFDEC_ERROR ("using non-implemented clip events %u", event_flags & SWFDEC_UNIMPLEMENTED_EVENTS);
       }
commit 85b68f4c952ecffa1cfea3c6fc6c8d12dacc2b6f
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun May 4 17:19:40 2008 +0300

    Add swfdec_actor_queue_script_with_key and related functionality

diff --git a/swfdec/swfdec_actor.c b/swfdec/swfdec_actor.c
index f6b3e53..e173f3f 100644
--- a/swfdec/swfdec_actor.c
+++ b/swfdec/swfdec_actor.c
@@ -187,7 +187,8 @@ swfdec_sprite_movie_set_constructor (SwfdecSpriteMovie *movie)
 }
 
 void
-swfdec_actor_execute (SwfdecActor *actor, SwfdecEventType condition)
+swfdec_actor_execute (SwfdecActor *actor, SwfdecEventType condition,
+    guint8 key)
 {
   SwfdecAsObject *thisp;
   const char *name;
@@ -233,7 +234,7 @@ swfdec_actor_execute (SwfdecActor *actor, SwfdecEventType condition)
 
   swfdec_sandbox_use (SWFDEC_MOVIE (actor)->resource->sandbox);
   if (actor->events) {
-    swfdec_event_list_execute (actor->events, thisp, condition, 0);
+    swfdec_event_list_execute (actor->events, thisp, condition, key);
   }
   /* FIXME: how do we compute the version correctly here? */
   if (version > 5) {
@@ -248,14 +249,16 @@ swfdec_actor_execute (SwfdecActor *actor, SwfdecEventType condition)
 }
 
 /**
- * swfdec_actor_queue_script:
+ * swfdec_actor_queue_script_with_key:
  * @movie: a #SwfdecMovie
  * @condition: the event that should happen
+ * @key: the key for this event
  *
- * Queues execution of all scripts associated with the given event.
+ * Queues execution of all scripts associated with the given event and key.
  **/
 void
-swfdec_actor_queue_script (SwfdecActor *actor, SwfdecEventType condition)
+swfdec_actor_queue_script_with_key (SwfdecActor *actor,
+    SwfdecEventType condition, guint8 key)
 {
   SwfdecPlayer *player;
   guint importance;
@@ -303,7 +306,20 @@ swfdec_actor_queue_script (SwfdecActor *actor, SwfdecEventType condition)
   }
 
   player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (actor)->context);
-  swfdec_player_add_action (player, actor, condition, importance);
+  swfdec_player_add_action (player, actor, condition, key, importance);
+}
+
+/**
+ * swfdec_actor_queue_script:
+ * @movie: a #SwfdecMovie
+ * @condition: the event that should happen
+ *
+ * Queues execution of all scripts associated with the given event.
+ **/
+void
+swfdec_actor_queue_script (SwfdecActor *actor, SwfdecEventType condition)
+{
+  swfdec_actor_queue_script_with_key (actor, condition, 0);
 }
 
 /**
diff --git a/swfdec/swfdec_actor.h b/swfdec/swfdec_actor.h
index fac49f2..5c30bfd 100644
--- a/swfdec/swfdec_actor.h
+++ b/swfdec/swfdec_actor.h
@@ -80,7 +80,11 @@ struct _SwfdecActorClass
 GType		swfdec_actor_get_type		(void);
 
 void		swfdec_actor_execute		(SwfdecActor *		actor,
-						 SwfdecEventType	condition);
+						 SwfdecEventType	condition,
+						 guint8			key);
+void		swfdec_actor_queue_script_with_key (SwfdecActor *		actor,
+  						 SwfdecEventType	condition,
+						 guint8			key);
 void		swfdec_actor_queue_script	(SwfdecActor *		actor,
   						 SwfdecEventType	condition);
 
diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index 48eb40b..5060b14 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -1532,7 +1532,7 @@ swfdec_movie_duplicate (SwfdecMovie *movie, const char *name, int depth)
     SwfdecActor *actor = SWFDEC_ACTOR (copy);
     swfdec_actor_queue_script (actor, SWFDEC_EVENT_INITIALIZE);
     swfdec_actor_queue_script (actor, SWFDEC_EVENT_LOAD);
-    swfdec_actor_execute (actor, SWFDEC_EVENT_CONSTRUCT);
+    swfdec_actor_execute (actor, SWFDEC_EVENT_CONSTRUCT, 0);
   }
   swfdec_movie_initialize (copy);
   swfdec_sandbox_use (sandbox);
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 232521e..fd69cc6 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -372,6 +372,7 @@ typedef struct {
   SwfdecActor *		actor;		/* the actor to trigger the action on */
   SwfdecScript *	script;		/* script to execute or NULL to trigger action */
   SwfdecEventType	event;		/* the action to trigger */
+  guint8		key;
 } SwfdecPlayerAction;
 
 typedef struct {
@@ -430,6 +431,7 @@ swfdec_player_do_add_action (SwfdecPlayer *player, guint importance, SwfdecPlaye
  * @player: a #SwfdecPlayer
  * @movie: the movie on which to trigger the event
  * @type: type of the event
+ * @type: key of the event
  * @importance: importance of the event
  *
  * Adds an action to the @player. Actions are used by Flash player to solve
@@ -438,10 +440,10 @@ swfdec_player_do_add_action (SwfdecPlayer *player, guint importance, SwfdecPlaye
  * is calling Actionscript code, you want to do this by using actions.
  **/
 void
-swfdec_player_add_action (SwfdecPlayer *player, SwfdecActor *actor, SwfdecEventType type,
-    guint importance)
+swfdec_player_add_action (SwfdecPlayer *player, SwfdecActor *actor,
+    SwfdecEventType type, guint8 key, guint importance)
 {
-  SwfdecPlayerAction action = { actor, NULL, type };
+  SwfdecPlayerAction action = { actor, NULL, type, key };
 
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
   g_return_if_fail (SWFDEC_IS_ACTOR (actor));
@@ -519,7 +521,7 @@ swfdec_player_do_action (SwfdecPlayer *player)
 	swfdec_as_object_run (SWFDEC_AS_OBJECT (action->actor), action->script);
 	swfdec_sandbox_unuse (sandbox);
       } else {
-	swfdec_actor_execute (action->actor, action->event);
+	swfdec_actor_execute (action->actor, action->event, action->key);
       }
       return TRUE;
     }
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index c2f97e7..2bbf40a 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -216,6 +216,7 @@ void		swfdec_player_remove_all_external_actions
 void		swfdec_player_add_action	(SwfdecPlayer *		player,
 						 SwfdecActor *		actor,
 						 SwfdecEventType	type,
+						 guint8			key,
 						 guint			importance);
 void		swfdec_player_add_action_script	(SwfdecPlayer *		player,
 						 SwfdecActor *		actor,
diff --git a/swfdec/swfdec_sprite_movie_as.c b/swfdec/swfdec_sprite_movie_as.c
index da8e367..b848bfb 100644
--- a/swfdec/swfdec_sprite_movie_as.c
+++ b/swfdec/swfdec_sprite_movie_as.c
@@ -690,7 +690,7 @@ swfdec_sprite_movie_init_from_object (SwfdecMovie *movie,
     swfdec_actor_queue_script (actor, SWFDEC_EVENT_LOAD);
     swfdec_sandbox_unuse (sandbox);
     swfdec_movie_initialize (movie);
-    swfdec_actor_execute (actor, SWFDEC_EVENT_CONSTRUCT);
+    swfdec_actor_execute (actor, SWFDEC_EVENT_CONSTRUCT, 0);
     swfdec_sandbox_use (sandbox);
   } else {
     swfdec_movie_initialize (movie);
commit 24ce6bd24cb8add9c866ef906a62a8ad2cc5d512
Merge: 984156d... bd7b717...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun May 4 15:49:28 2008 +0300

    Merge branch 'master' of ssh://medar@git.freedesktop.org/git/swfdec/swfdec

commit 984156deb7c0c1266e28e8ee9f0726ef3425455f
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 3 18:08:24 2008 +0300

    Oops, fix an error I just added to Key.isDown

diff --git a/swfdec/swfdec_key_as.c b/swfdec/swfdec_key_as.c
index 399eb21..f89b2b8 100644
--- a/swfdec/swfdec_key_as.c
+++ b/swfdec/swfdec_key_as.c
@@ -70,8 +70,10 @@ swfdec_key_isDown (SwfdecAsContext *cx, SwfdecAsObject *object,
     SWFDEC_AS_VALUE_SET_BOOLEAN (retval, swfdec_player_is_mouse_pressed (player));
   } else if (id == 2) {
     SWFDEC_FIXME ("Key.isDown (2) should give status of the second mouse button");
+    SWFDEC_AS_VALUE_SET_BOOLEAN (retval, FALSE);
   } else if (id == 4) {
     SWFDEC_FIXME ("Key.isDown (4) should give status of the middle mouse button");
+    SWFDEC_AS_VALUE_SET_BOOLEAN (retval, FALSE);
   } else {
     if (id < 8)
       SWFDEC_FIXME ("Should Key.isDown (%i) give mouse button status?", id);
commit d7cdd893ea857d76fff9fc54f0f36d9cca2face5
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 3 18:07:03 2008 +0300

    Add a test for Key.isDown (1) to detect first mouse button's status

diff --git a/test/custom/Makefile.am b/test/custom/Makefile.am
index 531447e..6ae3773 100644
--- a/test/custom/Makefile.am
+++ b/test/custom/Makefile.am
@@ -50,6 +50,11 @@ EXTRA_DIST = \
 	definebutton.stas \
 	definebutton.sts \
 	definebutton.xml \
+	key-isdown-mouse.as \
+	key-isdown-mouse.stas \
+	key-isdown-mouse.sts \
+	key-isdown-mouse.swf \
+	key-isdown-mouse.swf.trace \
 	mouse-addProperty-relevant.as \
 	mouse-addProperty-relevant.stas \
 	mouse-addProperty-relevant.sts \
diff --git a/test/custom/key-isdown-mouse.as b/test/custom/key-isdown-mouse.as
new file mode 100644
index 0000000..98a75f2
--- /dev/null
+++ b/test/custom/key-isdown-mouse.as
@@ -0,0 +1,17 @@
+// makeswf -v 7 -s 200x150 -r 1 -o key-isdown-mouse.swf key-isdown-mouse.as
+
+trace ("Check if mouse presses show up as in Key.isDown and Key.getCode");
+
+dump = function () {
+  trace ("1: " + Key.isDown (1));
+  trace ("2: " + Key.isDown (2));
+  trace ("code: " + Key.getCode ());
+};
+Mouse.addListener ({ onMouseDown: dump, onMouseUp: dump });
+dump ();
+
+function quit () {
+  dump ();
+  getURL ("FSCommand:quit", "");
+};
+setTimeout (quit, 3000);
diff --git a/test/custom/key-isdown-mouse.stas b/test/custom/key-isdown-mouse.stas
new file mode 100644
index 0000000..0dcb1b4
--- /dev/null
+++ b/test/custom/key-isdown-mouse.stas
@@ -0,0 +1,58 @@
+/* Swfdec
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *               2008 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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
+ */
+
+run_test = function (t, file) {
+  var e;
+  print ("Testing " + file);
+  try {
+    t.reset (file);
+    var expected = Buffer.load (file + ".trace");
+    t.advance (1000);
+    t.mouse_press (50, 50);
+    t.advance (1000);
+    t.mouse_release (50, 50);
+    t.advance (1000);
+    var diff = t.trace.diff (expected);
+    if (diff) {
+      error ("different trace output");
+      Native.print (diff);
+      return false;
+    }
+  } catch (e) {
+    if (e) {
+      error (e);
+      return false;
+    }
+  };
+  Native.print ("  OK\n");
+  return true;
+};
+
+filenames.sort ();
+t = new Test ();
+fail = [];
+for (var i = 0; i < filenames.length; i++) {
+  if (!run_test (t, filenames[i]))
+    fail.push (filenames[i]);
+};
+if (fail.length > 0) {
+  error (fail.join ("\n       "));
+  throw (fail.length + " failures");
+}
diff --git a/test/custom/key-isdown-mouse.sts b/test/custom/key-isdown-mouse.sts
new file mode 100644
index 0000000..7db0a14
Binary files /dev/null and b/test/custom/key-isdown-mouse.sts differ
diff --git a/test/custom/key-isdown-mouse.swf b/test/custom/key-isdown-mouse.swf
new file mode 100644
index 0000000..7216b90
Binary files /dev/null and b/test/custom/key-isdown-mouse.swf differ
commit dc31270f427bef3fa8332da7d2bc430990fa15fd
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 3 18:04:21 2008 +0300

    Make Key.isDown (1) return status of the first mouse button
    
    Add FIXMES to other ids that are smaller than 8
    2 should be the second mouse button and 4 should be the middle one
    Others I don't know
    
    With Adobe's player these codes seem to only work on Windows version

diff --git a/swfdec/swfdec_key_as.c b/swfdec/swfdec_key_as.c
index ca7a949..399eb21 100644
--- a/swfdec/swfdec_key_as.c
+++ b/swfdec/swfdec_key_as.c
@@ -63,7 +63,20 @@ swfdec_key_isDown (SwfdecAsContext *cx, SwfdecAsObject *object,
     SWFDEC_FIXME ("id %u too big for a keycode", id);
     id %= 256;
   }
-  SWFDEC_AS_VALUE_SET_BOOLEAN (retval, (player->priv->key_pressed[id / 8] & (1 << (id % 8))) ? TRUE : FALSE);
+
+  // special case for the mouse buttons, with Adobe's player these are only
+  // supported on Windows
+  if (id == 1) {
+    SWFDEC_AS_VALUE_SET_BOOLEAN (retval, swfdec_player_is_mouse_pressed (player));
+  } else if (id == 2) {
+    SWFDEC_FIXME ("Key.isDown (2) should give status of the second mouse button");
+  } else if (id == 4) {
+    SWFDEC_FIXME ("Key.isDown (4) should give status of the middle mouse button");
+  } else {
+    if (id < 8)
+      SWFDEC_FIXME ("Should Key.isDown (%i) give mouse button status?", id);
+    SWFDEC_AS_VALUE_SET_BOOLEAN (retval, (player->priv->key_pressed[id / 8] & (1 << (id % 8))) ? TRUE : FALSE);
+  }
 }
 
 SWFDEC_AS_NATIVE (800, 3, swfdec_key_isToggled)
commit 00ee8c5ed1fcb52f7cde13cd45cee4af903a5331
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 3 12:15:11 2008 +0300

    Forgot to update Makefile.am for the tests

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index a95f2c1..17fa03e 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -1405,6 +1405,9 @@ EXTRA_DIST = \
 	gotolabel.xml \
 	gotolabel.swf \
 	gotolabel.swf.trace \
+	gotolabel-multiple.xml \
+	gotolabel-multiple.swf \
+	gotolabel-multiple.swf.trace \
 	gradient-bevel-filter-properties.as \
 	gradient-bevel-filter-properties-5.swf \
 	gradient-bevel-filter-properties-5.swf.trace \
commit 3f7ebf1ac972023c73a36bb332019f44848ce5b2
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat May 3 00:01:37 2008 +0300

    Add a test for single frame having multiple labels

diff --git a/test/trace/gotolabel-multiple.swf b/test/trace/gotolabel-multiple.swf
new file mode 100644
index 0000000..e5c5f58
Binary files /dev/null and b/test/trace/gotolabel-multiple.swf differ
diff --git a/test/trace/gotolabel-multiple.swf.trace b/test/trace/gotolabel-multiple.swf.trace
new file mode 100644
index 0000000..403ec31
--- /dev/null
+++ b/test/trace/gotolabel-multiple.swf.trace
@@ -0,0 +1,3 @@
+1
+3
+5
diff --git a/test/trace/gotolabel-multiple.xml b/test/trace/gotolabel-multiple.xml
new file mode 100644
index 0000000..301878e
--- /dev/null
+++ b/test/trace/gotolabel-multiple.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0"?>
+<swf version="8" compressed="1">
+  <Header framerate="15" frames="5">
+    <size>
+      <Rectangle left="0" right="2000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <FileAttributes hasMetaData="0" useNetwork="0"/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <GotoLabel label="lal"/>
+          <Play/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <GotoLabel label="lol"/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <FrameLabel label="lal"/>
+      <FrameLabel label="lel"/>
+      <ShowFrame/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <Stop/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <FrameLabel label="lul"/>
+      <FrameLabel label="lol"/>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit 79a79d6bd272aa501f22331148f14bf0afe786dd
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 2 23:59:30 2008 +0300

    Allow multiple labels for single SpriteFrame

diff --git a/swfdec/swfdec_sprite.c b/swfdec/swfdec_sprite.c
index 645cf09..0a06bb0 100644
--- a/swfdec/swfdec_sprite.c
+++ b/swfdec/swfdec_sprite.c
@@ -44,7 +44,8 @@ swfdec_sprite_dispose (GObject *object)
 
   if (sprite->frames) {
     for (i = 0; i < sprite->n_frames; i++) {
-      g_free (sprite->frames[i].label);
+      g_slist_foreach (sprite->frames[i].labels, (GFunc) g_free, NULL);
+      g_slist_free (sprite->frames[i].labels);
       if (sprite->frames[i].sound_head)
 	g_object_unref (sprite->frames[i].sound_head);
       if (sprite->frames[i].sound_block) {
@@ -190,10 +191,12 @@ swfdec_sprite_get_frame (SwfdecSprite *sprite, const char *label)
 
   for (i = 0; i < SWFDEC_SPRITE (sprite)->n_frames; i++) {
     SwfdecSpriteFrame *frame = &sprite->frames[i];
-    if (frame->label == NULL)
-      continue;
-    if (g_str_equal (frame->label, label))
-      return i;
+    GSList *iter;
+
+    for (iter = frame->labels; iter != NULL; iter = iter->next) {
+      if (g_str_equal (iter->data, label))
+	return i;
+    }
   }
   return -1;
 }
diff --git a/swfdec/swfdec_sprite.h b/swfdec/swfdec_sprite.h
index 1559642..ae1d035 100644
--- a/swfdec/swfdec_sprite.h
+++ b/swfdec/swfdec_sprite.h
@@ -51,7 +51,7 @@ struct _SwfdecSpriteAction {
 
 struct _SwfdecSpriteFrame
 {
-  char *label;				/* name of the frame for "GotoLabel" */
+  GSList *labels;                       /* names of the frame for "GotoLabel" */
 
   /* sound */
   SwfdecSound *sound_head;		/* sound head for this frame */
diff --git a/swfdec/swfdec_tag.c b/swfdec/swfdec_tag.c
index 2f91b7d..c9e4512 100644
--- a/swfdec/swfdec_tag.c
+++ b/swfdec/swfdec_tag.c
@@ -74,12 +74,14 @@ tag_func_frame_label (SwfdecSwfDecoder * s, guint tag)
 {
   SwfdecSpriteFrame *frame = &s->parse_sprite->frames[s->parse_sprite->parse_frame];
   
-  if (frame->label) {
-    SWFDEC_WARNING ("frame %d already has a label (%s)", s->parse_sprite->parse_frame, frame->label);
-    g_free (frame->label);
+  if (frame->labels) {
+    SWFDEC_WARNING ("adding another label for frame %d (%s)",
+        s->parse_sprite->parse_frame, (char *)frame->labels->data);
   }
-  frame->label = swfdec_bits_get_string (&s->b, s->version);
-  SWFDEC_LOG ("frame %d named %s", s->parse_sprite->parse_frame, frame->label);
+  frame->labels = g_slist_prepend (frame->labels,
+      swfdec_bits_get_string (&s->b, s->version));
+  SWFDEC_LOG ("frame %d named %s", s->parse_sprite->parse_frame,
+      (char *)frame->labels->data);
 
   return SWFDEC_STATUS_OK;
 }
commit 91588f9aea308955bc85ca7b8ab4646d45858c5c
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri May 2 23:59:19 2008 +0300

    Add a test for GotoLabel

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 99ee381..a95f2c1 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -1402,6 +1402,9 @@ EXTRA_DIST = \
 	goto5.swf.trace \
 	gotoframe.swf \
 	gotoframe.swf.trace \
+	gotolabel.xml \
+	gotolabel.swf \
+	gotolabel.swf.trace \
 	gradient-bevel-filter-properties.as \
 	gradient-bevel-filter-properties-5.swf \
 	gradient-bevel-filter-properties-5.swf.trace \
diff --git a/test/trace/gotolabel.swf b/test/trace/gotolabel.swf
new file mode 100644
index 0000000..107890c
Binary files /dev/null and b/test/trace/gotolabel.swf differ
diff --git a/test/trace/gotolabel.swf.trace b/test/trace/gotolabel.swf.trace
new file mode 100644
index 0000000..2b2f2e1
--- /dev/null
+++ b/test/trace/gotolabel.swf.trace
@@ -0,0 +1,2 @@
+1
+3
diff --git a/test/trace/gotolabel.xml b/test/trace/gotolabel.xml
new file mode 100644
index 0000000..85923af
--- /dev/null
+++ b/test/trace/gotolabel.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<swf version="8" compressed="1">
+  <Header framerate="15" frames="3">
+    <size>
+      <Rectangle left="0" right="2000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <FileAttributes hasMetaData="0" useNetwork="0"/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <GotoLabel label="lal"/>
+          <Play/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <ShowFrame/>
+      <DoAction>
+        <actions>
+          <Dictionary>
+            <strings>
+              <String value="_currentframe"/>
+            </strings>
+          </Dictionary>
+          <PushData>
+            <items>
+              <StackDictionaryLookup index="0"/>
+            </items>
+          </PushData>
+          <GetVariable/>
+          <Trace/>
+          <Stop/>
+          <EndAction/>
+        </actions>
+      </DoAction>
+      <FrameLabel label="lal"/>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>


More information about the Swfdec-commits mailing list