[Swfdec] 11 commits - libswfdec/swfdec_debugger.c libswfdec/swfdec_debugger.h libswfdec/swfdec_event.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_script.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_sprite_movie.h player/Makefile.am player/swfdebug.c player/swfdec_debug_movies.c player/swfdec_debug_movies.h player/swfdec_player_manager.c

Benjamin Otte company at kemper.freedesktop.org
Thu Mar 15 11:53:27 PDT 2007


 libswfdec/swfdec_debugger.c        |   48 ++++
 libswfdec/swfdec_debugger.h        |    3 
 libswfdec/swfdec_event.c           |    6 
 libswfdec/swfdec_js_movie.c        |   62 +++++-
 libswfdec/swfdec_movie.c           |   60 ++++-
 libswfdec/swfdec_movie.h           |    6 
 libswfdec/swfdec_net_stream.c      |    4 
 libswfdec/swfdec_player.c          |   44 ++--
 libswfdec/swfdec_player_internal.h |    2 
 libswfdec/swfdec_script.c          |    4 
 libswfdec/swfdec_sprite_movie.c    |  112 +++++------
 libswfdec/swfdec_sprite_movie.h    |    2 
 player/Makefile.am                 |    2 
 player/swfdebug.c                  |   46 ++++
 player/swfdec_debug_movies.c       |  371 +++++++++++++++++++++++++++++++++++++
 player/swfdec_debug_movies.h       |   64 ++++++
 player/swfdec_player_manager.c     |   22 --
 17 files changed, 741 insertions(+), 117 deletions(-)

New commits:
diff-tree c177682556b8107e82589593a0eee794e7f342b4 (from 78a3f9774427296b4382492369dec48c6a427c20)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 19:53:01 2007 +0100

    add debugging message

diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 48dd120..8840d78 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -36,6 +36,7 @@ swfdec_net_stream_onstatus (SwfdecNetStr
   JSObject *object;
   JSContext *cx;
 
+  SWFDEC_INFO ("emitting onStatus for %s %s", level, code);
   cx = stream->player->jscx;
   object = JS_NewObject (cx, NULL, NULL, NULL);
   if (!object)
diff-tree 78a3f9774427296b4382492369dec48c6a427c20 (from 165ab93606a6387834d2cc513085f02d8df3ac8e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 19:06:35 2007 +0100

    add swfdec_debugger_run and replace swfdebug's run command with it
    
    Also name the command "run" instead of "print"

diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c
index c37f337..5e3cebc 100644
--- a/libswfdec/swfdec_debugger.c
+++ b/libswfdec/swfdec_debugger.c
@@ -25,6 +25,7 @@
 #include "swfdec_debugger.h"
 #include "swfdec_debug.h"
 #include "swfdec_decoder.h"
+#include "swfdec_js.h"
 #include "swfdec_movie.h"
 #include "swfdec_player_internal.h"
 #include "js/jsdbgapi.h"
@@ -536,3 +537,42 @@ swfdec_debugger_get_stepping (SwfdecDebu
   return debugger->stepping;
 }
 
+const char *
+swfdec_debugger_run (SwfdecDebugger *debugger, const char *command)
+{
+  SwfdecPlayer *player;
+  GList *walk;
+  jsval rval;
+  const char *ret;
+
+  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), NULL);
+  g_return_val_if_fail (command != NULL, NULL);
+  
+  player = SWFDEC_PLAYER (debugger);
+  g_object_freeze_notify (G_OBJECT (debugger));
+
+
+  if (swfdec_js_run (player, command, &rval)) {
+    ret = swfdec_js_to_string (player->jscx, rval);
+  } else {
+    ret = NULL;
+  }
+
+
+  for (walk = player->roots; walk; walk = walk->next) {
+    swfdec_movie_update (walk->data);
+  }
+  if (!swfdec_rect_is_empty (&player->invalid)) {
+    double x, y, width, height;
+    x = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x0);
+    y = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y0);
+    width = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x1 - player->invalid.x0);
+    height = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y1 - player->invalid.y0);
+    g_signal_emit_by_name (player, "invalidate", x, y, width, height);
+    swfdec_rect_init_empty (&player->invalid);
+  }
+  g_object_thaw_notify (G_OBJECT (debugger));
+
+  return ret;
+}
+
diff --git a/libswfdec/swfdec_debugger.h b/libswfdec/swfdec_debugger.h
index 7c87604..228181c 100644
--- a/libswfdec/swfdec_debugger.h
+++ b/libswfdec/swfdec_debugger.h
@@ -96,6 +96,9 @@ void			swfdec_debugger_foreach_script	(S
 							 GFunc			func,
 							 gpointer		data);
 
+const char *	      	swfdec_debugger_run		(SwfdecDebugger *	debugger,
+							 const char *		command);
+
 
 G_END_DECLS
 #endif
diff --git a/player/swfdec_player_manager.c b/player/swfdec_player_manager.c
index 1307c32..0d22ab3 100644
--- a/player/swfdec_player_manager.c
+++ b/player/swfdec_player_manager.c
@@ -396,20 +396,18 @@ breakpoint_hit_cb (SwfdecDebugger *debug
 }
 
 static void
-command_print (SwfdecPlayerManager *manager, const char *arg)
+command_run (SwfdecPlayerManager *manager, const char *arg)
 {
-  jsval rval;
+  const char *s;
 
-  if (swfdec_js_run (manager->player, arg, &rval)) {
-    const char *s;
-    s = swfdec_js_to_string (manager->player->jscx, rval);
-    if (s)
-      swfdec_player_manager_output (manager, "%s", s);
-    else
-      swfdec_player_manager_error (manager, "Invalid return value");
-  } else {
-    swfdec_player_manager_error (manager, "Invalid command");
+  if (arg == NULL) {
+    swfdec_player_manager_error (manager, "Must give something to run");
   }
+  s = swfdec_debugger_run (SWFDEC_DEBUGGER (manager->player), arg);
+  if (s)
+    swfdec_player_manager_output (manager, "%s", s);
+  else
+    swfdec_player_manager_error (manager, "Error running given command");
 }
 
 static void
@@ -634,7 +632,7 @@ struct {
   const char *	description;
 } commands[] = {
   { "help",	command_help,		"print all available commands and a quick description" },
-  { "print",	command_print,	  	"evaluate the argument as a JavaScript script" },
+  { "run",	command_run,	  	"run the argument as a JavaScript script" },
   { "play",	command_play,		"play the movie" },
   { "stop",	command_stop,	 	"stop the movie" },
   { "iterate",	command_iterate,	"iterate the movie once" },
diff-tree 165ab93606a6387834d2cc513085f02d8df3ac8e (from dcb79d8d456dd148d4af43af2e22c4573427ed76)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 19:05:24 2007 +0100

    inherit the scope chain from the current scope chain, not from this
    
    YOUUUUUTUUUUUBE!!!!

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 210235e..7b520eb 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1662,11 +1662,11 @@ swfdec_action_define_function (JSContext
   if (*function_name == '\0') {
     /* anonymous function */
     fun = JS_NewFunction (cx, NULL, n_args, JSFUN_LAMBDA | JSFUN_HEAVYWEIGHT,
-	cx->fp->thisp, NULL);
+	cx->fp->scopeChain, NULL);
   } else {
     /* named function */
     fun = JS_NewFunction (cx, NULL, n_args, JSFUN_HEAVYWEIGHT, 
-	cx->fp->thisp, function_name);
+	cx->fp->scopeChain, function_name);
   }
   if (fun == NULL)
     return JS_FALSE;
diff-tree dcb79d8d456dd148d4af43af2e22c4573427ed76 (from 06afdd601fc3eb94c46d9731cbe4261b2e8044e8)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 17:21:44 2007 +0100

    display all live movies
    
    This includes a new TreeModel for displaying them

diff --git a/player/Makefile.am b/player/Makefile.am
index c56ee91..03217f0 100644
--- a/player/Makefile.am
+++ b/player/Makefile.am
@@ -22,6 +22,7 @@ swfplay_SOURCES = \
 
 swfdebug_SOURCES = \
 	swfdebug.c \
+	swfdec_debug_movies.c \
 	swfdec_debug_script.c \
 	swfdec_debug_scripts.c \
 	swfdec_debug_stack.c \
@@ -29,6 +30,7 @@ swfdebug_SOURCES = \
 	swfdec_debug_widget.c
 
 noinst_HEADERS = \
+	swfdec_debug_movies.h \
 	swfdec_debug_script.h \
 	swfdec_debug_scripts.h \
 	swfdec_debug_stack.h \
diff --git a/player/swfdebug.c b/player/swfdebug.c
index acb7490..c7f74d1 100644
--- a/player/swfdebug.c
+++ b/player/swfdebug.c
@@ -2,6 +2,7 @@
 #include <math.h>
 #include <libswfdec/swfdec.h>
 #include <libswfdec/swfdec_debugger.h>
+#include "swfdec_debug_movies.h"
 #include "swfdec_debug_script.h"
 #include "swfdec_debug_scripts.h"
 #include "swfdec_debug_stack.h"
@@ -205,11 +206,42 @@ signal_auto_connect (gpointer object, co
   g_object_weak_ref (G_OBJECT (data), disconnect_all, object);
 }
 
+static GtkWidget *
+create_movieview (SwfdecPlayer *player)
+{
+  GtkWidget *treeview;
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  SwfdecDebugMovies *movies;
+
+  movies = swfdec_debug_movies_new (player);
+  treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (movies));
+  renderer = gtk_cell_renderer_text_new ();
+
+  column = gtk_tree_view_column_new_with_attributes ("Movie", renderer,
+    "text", SWFDEC_DEBUG_MOVIES_COLUMN_NAME, NULL);
+  gtk_tree_view_column_set_resizable (column, TRUE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  column = gtk_tree_view_column_new_with_attributes ("Type", renderer,
+    "text", SWFDEC_DEBUG_MOVIES_COLUMN_TYPE, NULL);
+  gtk_tree_view_column_set_resizable (column, TRUE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  renderer = gtk_cell_renderer_toggle_new ();
+  column = gtk_tree_view_column_new_with_attributes ("V", renderer,
+    "active", SWFDEC_DEBUG_MOVIES_COLUMN_VISIBLE, NULL);
+  gtk_tree_view_column_set_resizable (column, TRUE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+  return treeview;
+}
+
 static void
 view_swf (SwfdecPlayer *player, double scale, gboolean use_image)
 {
   SwfdecPlayerManager *manager;
-  GtkWidget *window, *widget, *hpaned, *vbox, *hbox, *scroll, *scripts;
+  GtkWidget *window, *widget, *vpaned, *hpaned, *vbox, *hbox, *scroll, *scripts;
 
   manager = swfdec_player_manager_new (player);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@@ -218,8 +250,18 @@ view_swf (SwfdecPlayer *player, double s
   gtk_container_add (GTK_CONTAINER (window), hpaned);
 
   /* left side */
+  vpaned = gtk_vpaned_new ();
+  gtk_paned_add1 (GTK_PANED (hpaned), vpaned);
+
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), 
+      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_paned_add1 (GTK_PANED (vpaned), scroll);
+  widget = create_movieview (player);
+  gtk_container_add (GTK_CONTAINER (scroll), widget);
+
   vbox = gtk_vbox_new (FALSE, 3);
-  gtk_paned_add1 (GTK_PANED (hpaned), vbox);
+  gtk_paned_add2 (GTK_PANED (vpaned), vbox);
 
   scroll = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), 
diff --git a/player/swfdec_debug_movies.c b/player/swfdec_debug_movies.c
new file mode 100644
index 0000000..649f19a
--- /dev/null
+++ b/player/swfdec_debug_movies.c
@@ -0,0 +1,371 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, to_string to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <libswfdec/swfdec_debugger.h>
+#include <libswfdec/swfdec_movie.h>
+#include <libswfdec/swfdec_player_internal.h>
+#include <libswfdec/swfdec_root_movie.h>
+#include "swfdec_debug_movies.h"
+
+/*** GTK_TREE_MODEL ***/
+
+#if 0
+#  define REPORT g_print ("%s\n", G_STRFUNC)
+#else
+#  define REPORT 
+#endif
+static GtkTreeModelFlags 
+swfdec_debug_movies_get_flags (GtkTreeModel *tree_model)
+{
+  REPORT;
+  return 0;
+}
+
+static gint
+swfdec_debug_movies_get_n_columns (GtkTreeModel *tree_model)
+{
+  REPORT;
+  return SWFDEC_DEBUG_MOVIES_N_COLUMNS;
+}
+
+static GType
+swfdec_debug_movies_get_column_type (GtkTreeModel *tree_model, gint index_)
+{
+  REPORT;
+  switch (index_) {
+    case SWFDEC_DEBUG_MOVIES_COLUMN_MOVIE:
+      return G_TYPE_POINTER;
+    case SWFDEC_DEBUG_MOVIES_COLUMN_NAME:
+      return G_TYPE_STRING;
+    case SWFDEC_DEBUG_MOVIES_COLUMN_VISIBLE:
+      return G_TYPE_BOOLEAN;
+    case SWFDEC_DEBUG_MOVIES_COLUMN_TYPE:
+      return G_TYPE_STRING;
+    default:
+      break;
+  }
+  g_assert_not_reached ();
+  return G_TYPE_NONE;
+}
+
+static gboolean
+swfdec_debug_movies_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
+{
+  SwfdecDebugMovies *movies = SWFDEC_DEBUG_MOVIES (tree_model);
+  guint depth;
+  int *indices;
+  GList *walk;
+  SwfdecMovie *movie;
+
+  REPORT;
+  depth = gtk_tree_path_get_depth (path);
+  indices = gtk_tree_path_get_indices (path);
+  if (indices == NULL)
+    return FALSE;
+  walk = g_list_nth (movies->player->roots, *indices);
+  if (!walk)
+    return FALSE;
+  movie = walk->data;
+  indices++;
+  depth--;
+  for (; depth > 0; depth--) {
+    walk = g_list_nth (movie->list, *indices);
+    if (!walk)
+      return FALSE;
+    movie = walk->data;
+    indices++;
+  }
+  iter->user_data = movie;
+  return TRUE;
+}
+
+gint
+my_g_list_is_nth (GList *list, gpointer data)
+{
+  gint count;
+
+  count = 0;
+  for (; list; list = list->next) {
+    if (list->data == data)
+      return count;
+    count++;
+  }
+  return -1;
+}
+
+static GtkTreePath *
+swfdec_debug_movies_movie_to_path (SwfdecMovie *movie)
+{
+  GtkTreePath *path;
+  gint i;
+
+  if (movie->parent) {
+    i = my_g_list_is_nth (movie->parent->list, movie);
+    g_assert (i >= 0);
+    path = swfdec_debug_movies_movie_to_path (movie->parent);
+    gtk_tree_path_append_index (path, i);
+  } else {
+    i = my_g_list_is_nth (SWFDEC_ROOT_MOVIE (movie)->player->roots, movie);
+    g_assert (i >= 0);
+    path = gtk_tree_path_new ();
+    gtk_tree_path_append_index (path, i);
+  }
+  return path;
+}
+
+static GtkTreePath *
+swfdec_debug_movies_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  REPORT;
+  return swfdec_debug_movies_movie_to_path (iter->user_data);
+}
+
+static void 
+swfdec_debug_movies_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter,
+    gint column, GValue *value)
+{
+  SwfdecMovie *movie = iter->user_data;
+
+  REPORT;
+  switch (column) {
+    case SWFDEC_DEBUG_MOVIES_COLUMN_MOVIE:
+      g_value_init (value, G_TYPE_POINTER);
+      g_value_set_pointer (value, movie);
+      return;
+    case SWFDEC_DEBUG_MOVIES_COLUMN_NAME:
+      g_value_init (value, G_TYPE_STRING);
+      g_value_set_string (value, movie->name);
+      return;
+    case SWFDEC_DEBUG_MOVIES_COLUMN_VISIBLE:
+      g_value_init (value, G_TYPE_BOOLEAN);
+      g_value_set_boolean (value, movie->visible);
+      return;
+    case SWFDEC_DEBUG_MOVIES_COLUMN_TYPE:
+      g_value_init (value, G_TYPE_STRING);
+      /* big hack: we skip the "Swfdec" here */
+      g_value_set_string (value, G_OBJECT_TYPE_NAME (movie) + 6);
+      return;
+    default:
+      break;
+  }
+  g_assert_not_reached ();
+}
+
+static gboolean
+swfdec_debug_movies_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  GList *list;
+  SwfdecMovie *movie = iter->user_data;
+
+  REPORT;
+  if (movie->parent) {
+    list = movie->parent->list;
+  } else {
+    list = SWFDEC_ROOT_MOVIE (movie)->player->roots;
+  }
+  list = g_list_find (list, movie);
+  g_assert (list);
+  list = list->next;
+  if (list == NULL)
+    return FALSE;
+  iter->user_data = list->data;
+  return TRUE;
+}
+
+static gboolean
+swfdec_debug_movies_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
+{
+  GList *list;
+
+  REPORT;
+  if (parent) {
+    SwfdecMovie *movie = parent->user_data;
+    list = movie->list;
+  } else {
+    SwfdecPlayer *player = SWFDEC_DEBUG_MOVIES (tree_model)->player;
+    list = player->roots;
+  }
+  if (list == NULL)
+    return FALSE;
+  iter->user_data = list->data;
+  return TRUE;
+}
+
+static gboolean
+swfdec_debug_movies_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  GtkTreeIter unused;
+
+  REPORT;
+  return swfdec_debug_movies_iter_children (tree_model, &unused, iter);
+}
+
+static gint
+swfdec_debug_movies_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  GList *list;
+
+  REPORT;
+  if (iter) {
+    SwfdecMovie *movie = iter->user_data;
+    list = movie->list;
+  } else {
+    SwfdecPlayer *player = SWFDEC_DEBUG_MOVIES (tree_model)->player;
+    list = player->roots;
+  }
+  return g_list_length (list);
+}
+
+static gboolean
+swfdec_debug_movies_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter,
+    GtkTreeIter *parent, gint n)
+{
+  GList *list;
+
+  REPORT;
+  if (parent) {
+    SwfdecMovie *movie = parent->user_data;
+    list = movie->list;
+  } else {
+    SwfdecPlayer *player = SWFDEC_DEBUG_MOVIES (tree_model)->player;
+    list = player->roots;
+  }
+  list = g_list_nth (list, n);
+  if (list == NULL)
+    return FALSE;
+  iter->user_data = list->data;
+  return TRUE;
+}
+
+static gboolean
+swfdec_debug_movies_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
+{
+  SwfdecMovie *movie = SWFDEC_MOVIE (child->user_data);
+
+  REPORT;
+  if (movie->parent == NULL)
+    return FALSE;
+  iter->user_data = movie->parent;
+  return TRUE;
+}
+
+static void
+swfdec_debug_movies_tree_model_init (GtkTreeModelIface *iface)
+{
+  iface->get_flags = swfdec_debug_movies_get_flags;
+  iface->get_n_columns = swfdec_debug_movies_get_n_columns;
+  iface->get_column_type = swfdec_debug_movies_get_column_type;
+  iface->get_iter = swfdec_debug_movies_get_iter;
+  iface->get_path = swfdec_debug_movies_get_path;
+  iface->get_value = swfdec_debug_movies_get_value;
+  iface->iter_next = swfdec_debug_movies_iter_next;
+  iface->iter_children = swfdec_debug_movies_iter_children;
+  iface->iter_has_child = swfdec_debug_movies_iter_has_child;
+  iface->iter_n_children = swfdec_debug_movies_iter_n_children;
+  iface->iter_nth_child = swfdec_debug_movies_iter_nth_child;
+  iface->iter_parent = swfdec_debug_movies_iter_parent;
+}
+
+/*** SWFDEC_DEBUG_MOVIES ***/
+
+G_DEFINE_TYPE_WITH_CODE (SwfdecDebugMovies, swfdec_debug_movies, G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, swfdec_debug_movies_tree_model_init))
+
+static void
+swfdec_debug_movies_added (SwfdecPlayer *player, SwfdecMovie *movie, SwfdecDebugMovies *movies)
+{
+  GtkTreePath *path = swfdec_debug_movies_movie_to_path (movie);
+  GtkTreeIter iter;
+
+  iter.user_data = movie;
+  g_print ("movie %s added\n", movie->name);
+  gtk_tree_model_row_inserted (GTK_TREE_MODEL (movies), path, &iter);
+  gtk_tree_path_free (path);
+}
+
+static void
+swfdec_debug_movies_removed (SwfdecPlayer *player, SwfdecMovie *movie, SwfdecDebugMovies *movies)
+{
+  GList *list;
+  GtkTreePath *path;
+  int i = 0;
+
+  if (movie->parent) {
+    path = swfdec_debug_movies_movie_to_path (movie->parent);
+    list = movie->parent->list;
+  } else {
+    path = gtk_tree_path_new ();
+    list = player->roots;
+  }
+  for (;list; list = list->next) {
+    if (swfdec_movie_compare_depths (list->data, movie) >= 0)
+      break;
+    i++;
+  }
+  gtk_tree_path_append_index (path, i);
+  g_print ("movie %s removed\n", movie->name);
+  gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);
+  gtk_tree_path_free (path);
+}
+
+static void
+swfdec_debug_movies_dispose (GObject *object)
+{
+  SwfdecDebugMovies *movies = SWFDEC_DEBUG_MOVIES (object);
+
+  g_signal_handlers_disconnect_by_func (movies->player, swfdec_debug_movies_removed, movies);
+  g_signal_handlers_disconnect_by_func (movies->player, swfdec_debug_movies_added, movies);
+  g_object_unref (movies->player);
+
+  G_OBJECT_CLASS (swfdec_debug_movies_parent_class)->dispose (object);
+}
+
+static void
+swfdec_debug_movies_class_init (SwfdecDebugMoviesClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->dispose = swfdec_debug_movies_dispose;
+}
+
+static void
+swfdec_debug_movies_init (SwfdecDebugMovies *token)
+{
+}
+
+SwfdecDebugMovies *
+swfdec_debug_movies_new (SwfdecPlayer *player)
+{
+  SwfdecDebugMovies *movies;
+
+  movies = g_object_new (SWFDEC_TYPE_DEBUG_MOVIES, NULL);
+  movies->player = player;
+  g_object_ref (player);
+  if (SWFDEC_IS_DEBUGGER (player)) {
+    g_signal_connect (player, "movie-added", G_CALLBACK (swfdec_debug_movies_added), movies);
+    g_signal_connect (player, "movie-removed", G_CALLBACK (swfdec_debug_movies_removed), movies);
+  }
+  return movies;
+}
+
diff --git a/player/swfdec_debug_movies.h b/player/swfdec_debug_movies.h
new file mode 100644
index 0000000..66d10eb
--- /dev/null
+++ b/player/swfdec_debug_movies.h
@@ -0,0 +1,64 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _SWFDEC_DEBUG_MOVIES_H_
+#define _SWFDEC_DEBUG_MOVIES_H_
+
+#include <libswfdec/swfdec.h>
+
+G_BEGIN_DECLS
+
+enum {
+  SWFDEC_DEBUG_MOVIES_COLUMN_MOVIE,
+  SWFDEC_DEBUG_MOVIES_COLUMN_NAME,
+  SWFDEC_DEBUG_MOVIES_COLUMN_VISIBLE,
+  SWFDEC_DEBUG_MOVIES_COLUMN_TYPE,
+  /* add more */
+  SWFDEC_DEBUG_MOVIES_N_COLUMNS
+};
+
+typedef struct _SwfdecDebugMovies SwfdecDebugMovies;
+typedef struct _SwfdecDebugMoviesClass SwfdecDebugMoviesClass;
+
+#define SWFDEC_TYPE_DEBUG_MOVIES                    (swfdec_debug_movies_get_type())
+#define SWFDEC_IS_DEBUG_MOVIES(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_DEBUG_MOVIES))
+#define SWFDEC_IS_DEBUG_MOVIES_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_DEBUG_MOVIES))
+#define SWFDEC_DEBUG_MOVIES(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_DEBUG_MOVIES, SwfdecDebugMovies))
+#define SWFDEC_DEBUG_MOVIES_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_DEBUG_MOVIES, SwfdecDebugMoviesClass))
+
+struct _SwfdecDebugMovies
+{
+  GObject		object;
+
+  SwfdecPlayer *	player;		/* the video we play */
+};
+
+struct _SwfdecDebugMoviesClass
+{
+  GObjectClass		object_class;
+};
+
+GType		swfdec_debug_movies_get_type		(void);
+
+SwfdecDebugMovies *
+		swfdec_debug_movies_new			(SwfdecPlayer *		player);
+
+
+G_END_DECLS
+#endif
diff-tree 06afdd601fc3eb94c46d9731cbe4261b2e8044e8 (from de2cb93b584ab4b3069d1394adcdcb73c22c4565)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 17:21:04 2007 +0100

    handle adding/removing movies from parent differently, so that movie-added/removed signals work

diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 29e7d0d..c4a2733 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -27,6 +27,7 @@
 
 #include "swfdec_movie.h"
 #include "swfdec_debug.h"
+#include "swfdec_debugger.h"
 #include "swfdec_event.h"
 #include "swfdec_graphic.h"
 #include "swfdec_js.h"
@@ -283,8 +284,25 @@ swfdec_movie_do_remove (SwfdecMovie *mov
   if (SWFDEC_ROOT_MOVIE (movie->root)->player->mouse_drag == movie)
     SWFDEC_ROOT_MOVIE (movie->root)->player->mouse_drag = NULL;
   swfdec_movie_invalidate (movie);
-  if (movie->parent)
-    movie->parent->list = g_list_remove (movie->parent->list, movie);
+  if (movie->parent) {
+    SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (movie->root)->player;
+    if (SWFDEC_IS_DEBUGGER (player) &&
+	g_list_find (movie->parent->list, movie)) {
+      movie->parent->list = g_list_remove (movie->parent->list, movie);
+      g_signal_emit_by_name (player, "movie-removed", movie);
+    } else {
+      movie->parent->list = g_list_remove (movie->parent->list, movie);
+    }
+  } else {
+    SwfdecPlayer *player = SWFDEC_ROOT_MOVIE (movie)->player;
+    if (SWFDEC_IS_DEBUGGER (player) &&
+	g_list_find (player->roots, movie)) {
+      player->roots = g_list_remove (player->roots, movie);
+      g_signal_emit_by_name (player, "movie-removed", movie);
+    } else {
+      player->roots = g_list_remove (player->roots, movie);
+    }
+  }
 }
 
 /**
@@ -306,9 +324,6 @@ swfdec_movie_destroy (SwfdecMovie *movie
   swfdec_movie_set_content (movie, NULL);
   if (klass->finish_movie)
     klass->finish_movie (movie);
-  if (movie->parent) {
-    movie->parent->list = g_list_remove (movie->parent->list, movie);
-  }
   swfdec_js_movie_remove_jsobject (movie);
   player->movies = g_list_remove (player->movies, movie);
   g_object_unref (movie);
@@ -710,6 +725,8 @@ swfdec_movie_set_parent (SwfdecMovie *mo
     parent->list = g_list_insert_sorted (parent->list, movie, swfdec_movie_compare_depths);
     SWFDEC_DEBUG ("inserting %s %p (depth %d) into %s %p", G_OBJECT_TYPE_NAME (movie), movie,
 	movie->depth,  G_OBJECT_TYPE_NAME (parent), parent);
+  } else {
+    player->roots = g_list_insert_sorted (player->roots, movie, swfdec_movie_compare_depths);
   }
   swfdec_movie_set_name (movie);
   klass = SWFDEC_MOVIE_GET_CLASS (movie);
@@ -725,6 +742,8 @@ swfdec_movie_set_parent (SwfdecMovie *mo
     g_queue_push_tail (player->init_queue, movie);
     g_queue_push_tail (player->construct_queue, movie);
   }
+  if (SWFDEC_IS_DEBUGGER (player))
+    g_signal_emit_by_name (player, "movie-added", movie);
   if (klass->init_movie)
     klass->init_movie (movie);
   swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 285eae9..fd528fa 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -378,8 +378,8 @@ swfdec_player_dispose (GObject *object)
   g_hash_table_foreach_steal (player->registered_classes, free_registered_class, player);
   g_hash_table_destroy (player->registered_classes);
 
-  g_list_foreach (player->roots, (GFunc) swfdec_movie_destroy, NULL);
-  g_list_free (player->roots);
+  while (player->roots)
+    swfdec_movie_destroy (player->roots->data);
 
   swfdec_js_finish_player (player);
 
@@ -945,8 +945,8 @@ swfdec_player_add_level_from_loader (Swf
 {
   SwfdecMovie *movie;
   SwfdecRootMovie *root;
-  GList *found;
 
+  swfdec_player_remove_level (player, depth);
   movie = swfdec_movie_new_for_player (player, depth);
   root = SWFDEC_ROOT_MOVIE (movie);
   root->player = player;
@@ -954,13 +954,6 @@ swfdec_player_add_level_from_loader (Swf
   if (variables)
     swfdec_scriptable_set_variables (SWFDEC_SCRIPTABLE (movie), variables);
   swfdec_loader_set_target (root->loader, SWFDEC_LOADER_TARGET (root));
-  found = g_list_find_custom (player->roots, movie, swfdec_movie_compare_depths);
-  if (found) {
-    SWFDEC_DEBUG ("remove existing movie _level%u", depth);
-    swfdec_movie_remove (found->data);
-    player->roots = g_list_delete_link (player->roots, found);
-  }
-  player->roots = g_list_insert_sorted (player->roots, movie, swfdec_movie_compare_depths);
   return root;
 }
 
@@ -981,7 +974,6 @@ swfdec_player_remove_level (SwfdecPlayer
     if (movie->depth == real_depth) {
       SWFDEC_DEBUG ("remove existing movie _level%u", depth);
       swfdec_movie_remove (movie);
-      player->roots = g_list_delete_link (player->roots, walk);
       return;
     }
     break;
diff-tree de2cb93b584ab4b3069d1394adcdcb73c22c4565 (from 851c798228546fc6faed8c5c025d66b9c5740042)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 17:20:20 2007 +0100

    Add movie-added and movie-removed signals

diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c
index c17c315..c37f337 100644
--- a/libswfdec/swfdec_debugger.c
+++ b/libswfdec/swfdec_debugger.c
@@ -190,6 +190,8 @@ enum {
   BREAKPOINT,
   BREAKPOINT_ADDED,
   BREAKPOINT_REMOVED,
+  MOVIE_ADDED,
+  MOVIE_REMOVED,
   LAST_SIGNAL
 };
 
@@ -232,6 +234,12 @@ swfdec_debugger_class_init (SwfdecDebugg
   signals[BREAKPOINT_REMOVED] = g_signal_new ("breakpoint-removed", 
       G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
       g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
+  signals[MOVIE_ADDED] = g_signal_new ("movie-added", 
+      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
+      g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
+  signals[MOVIE_REMOVED] = g_signal_new ("movie-removed", 
+      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
+      g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
 }
 
 static void
diff-tree 851c798228546fc6faed8c5c025d66b9c5740042 (from d31d94e96ebbcbf4768d7e8801945d5d52a9abf9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 15:25:18 2007 +0100

    rework iterations to allow for construct and initialize events.

diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index 429a3dd..5137746 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -444,6 +444,15 @@ swfdec_js_copy_props (SwfdecMovie *targe
   swfdec_movie_queue_update (target, SWFDEC_MOVIE_INVALID_MATRIX);
 }
 
+static void
+swfdec_js_movie_init_from_object (SwfdecMovie *movie, JSObject *obj)
+{
+  SwfdecPlayer *player;
+
+  player = SWFDEC_ROOT_MOVIE (movie->root)->player;
+  g_queue_remove (player->init_queue, movie);
+}
+
 static JSBool
 swfdec_js_movie_attachMovie (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
@@ -494,6 +503,9 @@ swfdec_js_movie_attachMovie (JSContext *
     return JS_FALSE;
   SWFDEC_LOG ("attached %s (%u) as %s to depth %u", export, SWFDEC_CHARACTER (sprite)->id,
       ret->name, ret->depth);
+  /* run init and construct */
+  swfdec_js_movie_init_from_object (ret, NULL);
+  swfdec_movie_run_construct (ret);
   *rval = OBJECT_TO_JSVAL (SWFDEC_SCRIPTABLE (ret)->jsobj);
   return JS_TRUE;
 }
@@ -1197,8 +1209,7 @@ static JSPropertySpec movieclip_props[] 
 static JSBool
 swfdec_js_movieclip_new (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
-  SWFDEC_ERROR ("This should not exist, but currently has to for instanceof to work");
-  return JS_FALSE;
+  return JS_TRUE;
 }
 
 /**
@@ -1229,6 +1240,7 @@ swfdec_js_movie_lookup_class (SwfdecSpri
   name = swfdec_root_movie_get_export_name (root, SWFDEC_CHARACTER (movie->sprite));
   if (name == NULL)
     return JSVAL_NULL;
+  SWFDEC_LOG ("found name %s for movie %s", name, SWFDEC_MOVIE (movie)->name);
   return swfdec_player_get_export_class (root->player, name);
 }
 
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index ab46a2f..29e7d0d 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -273,6 +273,7 @@ typedef void (* SwfdecMovieRemoveFunc) (
 static void
 swfdec_movie_do_remove (SwfdecMovie *movie, gpointer child_remove)
 {
+  movie->will_be_removed = TRUE;
   /* remove all children */
   while (movie->list) {
     (*(SwfdecMovieRemoveFunc) child_remove) (movie->list->data, child_remove);
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 760fe43..285eae9 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -625,11 +625,14 @@ swfdec_player_iterate (SwfdecTimeout *ti
   GList *walk;
 
   SWFDEC_INFO ("=== START ITERATION ===");
-  /* The handling of this list is rather tricky. This code assumes that no 
-   * movies get removed that haven't been iterated yet. This should not be a 
-   * problem without using Javascript, because the only way to remove movies
-   * is when a sprite removes a child. But all children are in front of their
-   * parent in this list, since they got added later.
+  /* First, we prepare the iteration. We flag all movies for removal that will 
+   * be removed */
+  for (walk = player->movies; walk; walk = walk->next) {
+    if (SWFDEC_IS_SPRITE_MOVIE (walk->data))
+      swfdec_sprite_movie_prepare (walk->data);
+  }
+  /* Step 2: start the iteration. This performs a goto next frame on all 
+   * movies that are not stopped. It also queues onEnterFrame.
    */
   for (walk = player->movies; walk; walk = walk->next) {
     SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (walk->data);
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 74d2160..f23c4c1 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -123,20 +123,59 @@ swfdec_sprite_movie_perform_one_action (
 }
 
 static void
-swfdec_sprite_movie_do_goto_frame (gpointer moviep, gpointer data)
+swfdec_movie_tell_about_removal (SwfdecMovie *movie)
+{
+  GList *walk;
+  if (movie->will_be_removed)
+    return;
+  movie->will_be_removed = TRUE;
+  for (walk = movie->list; walk; walk = walk->next) {
+    swfdec_movie_tell_about_removal (walk->data);
+  }
+}
+
+void
+swfdec_sprite_movie_prepare (SwfdecSpriteMovie *movie)
+{
+  GList *walk;
+  guint frame;
+
+  g_return_if_fail (SWFDEC_IS_SPRITE_MOVIE (movie));
+
+  if (SWFDEC_MOVIE (movie)->stopped ||
+      movie->sprite == NULL)
+    return;
+
+  frame = swfdec_sprite_get_next_frame (movie->sprite, SWFDEC_MOVIE (movie)->frame);
+  /* tell all relevant movies that they won't survive this */
+  for (walk = SWFDEC_MOVIE (movie)->list; walk; walk = walk->next) {
+    SwfdecMovie *cur = walk->data;
+    if (frame < cur->content->sequence->start || 
+	frame >= cur->content->sequence->end)
+      swfdec_movie_tell_about_removal (cur);
+  }
+}
+
+static void
+swfdec_sprite_movie_goto (SwfdecMovie *mov, guint goto_frame)
 {
-  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (moviep);
-  SwfdecMovie *mov = moviep;
-  unsigned int goto_frame = GPOINTER_TO_UINT (data);
+  SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
+  SwfdecPlayer *player;
   GList *old, *walk;
   guint i, j, start;
 
+  g_assert (goto_frame < mov->n_frames);
+
   if (mov->will_be_removed)
     return;
-
   if (goto_frame == movie->current_frame)
     return;
 
+  player = SWFDEC_ROOT_MOVIE (mov->root)->player;
+  SWFDEC_LOG ("doing goto %u for %p %d", goto_frame, mov, 
+      SWFDEC_CHARACTER (SWFDEC_SPRITE_MOVIE (mov)->sprite)->id);
+  mov->frame = goto_frame;
+
   if (goto_frame < movie->current_frame) {
     start = 0;
     old = mov->list;
@@ -167,45 +206,6 @@ swfdec_sprite_movie_do_goto_frame (gpoin
   g_list_free (old);
 }
 
-static void
-swfdec_movie_tell_about_removal (SwfdecMovie *movie)
-{
-  GList *walk;
-  if (movie->will_be_removed)
-    return;
-  movie->will_be_removed = TRUE;
-  for (walk = movie->list; walk; walk = walk->next) {
-    swfdec_movie_tell_about_removal (walk->data);
-  }
-}
-
-static void
-swfdec_sprite_movie_goto (SwfdecMovie *mov, guint frame)
-{
-  SwfdecPlayer *player;
-  GList *walk;
-
-  g_assert (frame < mov->n_frames);
-
-  player = SWFDEC_ROOT_MOVIE (mov->root)->player;
-  SWFDEC_LOG ("queueing goto %u for %p %d", frame, mov, 
-      SWFDEC_CHARACTER (SWFDEC_SPRITE_MOVIE (mov)->sprite)->id);
-  
-  g_assert (frame <= G_MAXINT);
-
-  swfdec_player_add_action (player, mov,
-      swfdec_sprite_movie_do_goto_frame, GUINT_TO_POINTER (frame));
-
-  /* tell all relevant movies that they won't survive this */
-  for (walk = mov->list; walk; walk = walk->next) {
-    SwfdecMovie *cur = walk->data;
-    if (frame < cur->content->sequence->start || 
-	frame >= cur->content->sequence->end)
-      swfdec_movie_tell_about_removal (cur);
-  }
-  mov->frame = frame;
-}
-
 /*** MOVIE ***/
 
 G_DEFINE_TYPE (SwfdecSpriteMovie, swfdec_sprite_movie, SWFDEC_TYPE_MOVIE)
@@ -221,29 +221,19 @@ swfdec_sprite_movie_dispose (GObject *ob
 }
 
 static void
-swfdec_sprite_movie_queue_enter_frame (gpointer moviep, gpointer unused)
-{
-  SwfdecMovie *movie = moviep;
-
-  if (movie->will_be_removed)
-    return;
-  swfdec_movie_queue_script (movie, SWFDEC_EVENT_ENTER);
-}
-
-static void
 swfdec_sprite_movie_iterate (SwfdecMovie *mov)
 {
   SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
   unsigned int goto_frame;
 
-  if (mov->stopped) {
-    goto_frame = mov->frame;
-  } else {
+  if (mov->will_be_removed)
+    return;
+
+  swfdec_movie_queue_script (mov, SWFDEC_EVENT_ENTER);
+  if (!mov->stopped) {
     goto_frame = swfdec_sprite_get_next_frame (movie->sprite, mov->frame);
+    swfdec_sprite_movie_goto (mov, goto_frame);
   }
-  swfdec_player_add_action (SWFDEC_ROOT_MOVIE (mov->root)->player, 
-      mov, swfdec_sprite_movie_queue_enter_frame, NULL);
-  swfdec_sprite_movie_goto (mov, goto_frame);
 }
 
 static gboolean
@@ -315,7 +305,7 @@ swfdec_sprite_movie_init_movie (SwfdecMo
   SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
 
   mov->n_frames = movie->sprite->n_frames;
-  swfdec_sprite_movie_do_goto_frame (mov, GUINT_TO_POINTER (0));
+  swfdec_sprite_movie_goto (mov, 0);
   if (!swfdec_sprite_movie_iterate_end (mov)) {
     g_assert_not_reached ();
   }
diff --git a/libswfdec/swfdec_sprite_movie.h b/libswfdec/swfdec_sprite_movie.h
index 79a0db1..3be1725 100644
--- a/libswfdec/swfdec_sprite_movie.h
+++ b/libswfdec/swfdec_sprite_movie.h
@@ -60,6 +60,8 @@ struct _SwfdecSpriteMovieClass
 
 GType		swfdec_sprite_movie_get_type		(void);
 
+void		swfdec_sprite_movie_prepare		(SwfdecSpriteMovie *	movie);
+
 
 G_END_DECLS
 #endif
diff-tree d31d94e96ebbcbf4768d7e8801945d5d52a9abf9 (from 2160477ac3e50036bdd5030bd298dc1ca4f7a3f9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 15:23:53 2007 +0100

    net streams can signal eof now (if they were set to eof before)

diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 32651ad..48dd120 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -219,9 +219,8 @@ swfdec_net_stream_loader_target_parse (S
 	break;
       case SWFDEC_STATUS_ERROR:
       case SWFDEC_STATUS_NEEDBITS:
-	goto out;
       case SWFDEC_STATUS_EOF:
-	/* the flv decoder never emits this */
+	goto out;
       default:
 	g_assert_not_reached ();
 	return;
diff-tree 2160477ac3e50036bdd5030bd298dc1ca4f7a3f9 (from 21c8bd56636624a5937fc1ae693ca5233a57fa04)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 15:23:21 2007 +0100

    I noticed this g_print often enough now

diff --git a/libswfdec/swfdec_js_video.c b/libswfdec/swfdec_js_video.c
index fa427f8..946ebf7 100644
--- a/libswfdec/swfdec_js_video.c
+++ b/libswfdec/swfdec_js_video.c
@@ -33,7 +33,6 @@ swfdec_js_video_attach_video (JSContext 
   SwfdecNetStream *stream;
   SwfdecVideoMovie *video;
 
-  g_print ("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
   video = swfdec_scriptable_from_object (cx, obj, SWFDEC_TYPE_VIDEO_MOVIE);
   if (video == NULL)
     return JS_TRUE;
diff-tree 21c8bd56636624a5937fc1ae693ca5233a57fa04 (from 89993e6c8b33afd37db5691265da933b5b506fb9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 12:37:41 2007 +0100

    use the init and construct queue
    
    - add "onConstruct" event to event list
    - add swfdec_movie_execute_script to execute a script immidiately instead of queueing it
    - add 2 functions swfdec_movie_run_(construct|init) to run the constructors or
      initialization functions

diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c
index 06526fa..66d6aa7 100644
--- a/libswfdec/swfdec_event.c
+++ b/libswfdec/swfdec_event.c
@@ -60,7 +60,7 @@ static const char *event_names[] = {
   "onDragOver",
   "onDragOut",
   NULL,
-  NULL
+  "onConstruct"
 };
 
 const char *
@@ -226,7 +226,6 @@ swfdec_event_list_execute (SwfdecEventLi
     unsigned int condition, guint8 key)
 {
   unsigned int i;
-  const char *name;
 
   g_return_if_fail (list != NULL);
 
@@ -238,9 +237,6 @@ swfdec_event_list_execute (SwfdecEventLi
       swfdec_script_execute (event->script, scriptable);
     }
   }
-  name = swfdec_event_type_get_name (condition);
-  if (name)
-    swfdec_scriptable_execute (scriptable, name, 0, NULL);
 }
 
 gboolean
diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index 1504e3d..429a3dd 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1267,7 +1267,51 @@ swfdec_js_movie_create_jsobject	(SwfdecM
     return;
   }
   swfdec_js_movie_add_property (movie);
-  if (fun != JSVAL_NULL) {
+}
+
+/**
+ * swfdec_movie_run_init:
+ * @movie: a #SwfdecMovie
+ *
+ * Runs onClipEvent(initialize) on the given @movie.
+ */
+void
+swfdec_movie_run_init (SwfdecMovie *movie)
+{
+  SwfdecPlayer *player;
+
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+  g_return_if_fail (SWFDEC_SCRIPTABLE (movie)->jsobj != NULL);
+
+  player = SWFDEC_ROOT_MOVIE (movie->root)->player;
+  g_queue_remove (player->init_queue, movie);
+  swfdec_movie_execute_script (movie, SWFDEC_EVENT_INITIALIZE);
+}
+
+/**
+ * swfdec_movie_run_construct:
+ * @movie: a #SwfdecMovie
+ *
+ * Runs the constructors for @movie. This is (in the given order) 
+ * onClipEvent(construct), movie.onConstruct and the constructor registered
+ * via Object.registerClass.
+ **/
+void
+swfdec_movie_run_construct (SwfdecMovie *movie)
+{
+  SwfdecPlayer *player;
+  jsval fun;
+
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+  g_return_if_fail (SWFDEC_SCRIPTABLE (movie)->jsobj != NULL);
+
+  player = SWFDEC_ROOT_MOVIE (movie->root)->player;
+  g_queue_remove (player->construct_queue, movie);
+  swfdec_movie_execute_script (movie, SWFDEC_EVENT_CONSTRUCT);
+  /* FIXME: need a check if the constructor can be unregistered after construction */
+  if (SWFDEC_IS_SPRITE_MOVIE (movie) &&
+      (fun = swfdec_js_movie_lookup_class (SWFDEC_SPRITE_MOVIE (movie))) != JSVAL_NULL) {
+    SwfdecScriptable *script = SWFDEC_SCRIPTABLE (movie);
     SWFDEC_LOG ("Executing constructor for %s %p", G_OBJECT_TYPE_NAME (movie), movie);
     if (!js_InternalCall (script->jscx, script->jsobj, fun, 0, NULL, &fun)) {
       SWFDEC_ERROR ("constructor execution failed");
diff --git a/libswfdec/swfdec_js_video.c b/libswfdec/swfdec_js_video.c
index 946ebf7..fa427f8 100644
--- a/libswfdec/swfdec_js_video.c
+++ b/libswfdec/swfdec_js_video.c
@@ -33,6 +33,7 @@ swfdec_js_video_attach_video (JSContext 
   SwfdecNetStream *stream;
   SwfdecVideoMovie *video;
 
+  g_print ("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
   video = swfdec_scriptable_from_object (cx, obj, SWFDEC_TYPE_VIDEO_MOVIE);
   if (video == NULL)
     return JS_TRUE;
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 146fa2c..ab46a2f 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -332,20 +332,27 @@ swfdec_movie_remove (SwfdecMovie *movie)
     swfdec_movie_destroy (movie);
 }
 
-static void
-swfdec_movie_execute_script (gpointer moviep, gpointer data)
+void
+swfdec_movie_execute_script (SwfdecMovie *movie, SwfdecEventType condition)
 {
-  SwfdecMovie *movie = moviep;
-  guint condition = GPOINTER_TO_UINT (data);
+  const char *name;
+
+  g_return_if_fail (SWFDEC_IS_MOVIE (movie));
+  g_return_if_fail (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);
   }
+  name = swfdec_event_type_get_name (condition);
+  if (name != NULL)
+    swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (movie), name, 0, NULL);
+}
+
+static void
+swfdec_movie_do_execute_script (gpointer movie, gpointer condition)
+{
+  swfdec_movie_execute_script (movie, GPOINTER_TO_UINT (condition));
 }
 
 /**
@@ -377,7 +384,7 @@ swfdec_movie_queue_script (SwfdecMovie *
   }
 
   player = SWFDEC_ROOT_MOVIE (movie->root)->player;
-  swfdec_player_add_action (player, movie, swfdec_movie_execute_script, 
+  swfdec_player_add_action (player, movie, swfdec_movie_do_execute_script, 
       GUINT_TO_POINTER (condition));
   return TRUE;
 }
@@ -712,6 +719,11 @@ swfdec_movie_set_parent (SwfdecMovie *mo
   player->movies = g_list_prepend (player->movies, movie);
   /* we have to create the JSObject here to get actions queued before init_movie executes */
   swfdec_js_movie_create_jsobject (movie);
+  /* queue init and construct events for non-root movies */
+  if (movie != movie->root) {
+    g_queue_push_tail (player->init_queue, movie);
+    g_queue_push_tail (player->construct_queue, movie);
+  }
   if (klass->init_movie)
     klass->init_movie (movie);
   swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h
index 0351b54..2890f9c 100644
--- a/libswfdec/swfdec_movie.h
+++ b/libswfdec/swfdec_movie.h
@@ -185,6 +185,8 @@ void		swfdec_movie_render		(SwfdecMovie 
 						 gboolean		fill);
 void		swfdec_movie_goto		(SwfdecMovie *		movie,
 						 guint			frame);
+void		swfdec_movie_execute_script	(SwfdecMovie *		movie,
+						 SwfdecEventType	condition);
 gboolean      	swfdec_movie_queue_script	(SwfdecMovie *		movie,
   						 SwfdecEventType	condition);
 int		swfdec_movie_compare_depths	(gconstpointer		a,
@@ -192,5 +194,9 @@ int		swfdec_movie_compare_depths	(gconst
 SwfdecDepthClass
 		swfdec_depth_classify		(int			depth);
 
+/* in swfdec_js_movie.c */
+void		swfdec_movie_run_init		(SwfdecMovie *		movie);
+void		swfdec_movie_run_construct	(SwfdecMovie *		movie);
+
 G_END_DECLS
 #endif
diff-tree 89993e6c8b33afd37db5691265da933b5b506fb9 (from 67b44670242272bce0eb891db7ffbcbaa3d1b428)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 15 12:36:06 2007 +0100

    add an init_queue and a construct_queue for movies pending initialization or construction

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 8628b05..760fe43 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -252,7 +252,18 @@ static gboolean
 swfdec_player_do_action (SwfdecPlayer *player)
 {
   SwfdecPlayerAction *action;
+  SwfdecMovie *movie;
 
+  movie = g_queue_peek_head (player->init_queue);
+  if (movie) {
+    swfdec_movie_run_init (movie);
+    return TRUE;
+  }
+  movie = g_queue_peek_head (player->construct_queue);
+  if (movie) {
+    swfdec_movie_run_construct (movie);
+    return TRUE;
+  }
   do {
     action = swfdec_ring_buffer_pop (player->actions);
     if (action == NULL)
@@ -381,6 +392,10 @@ swfdec_player_dispose (GObject *object)
     swfdec_player_remove_timeout (player, &player->iterate_timeout);
   }
   g_assert (player->timeouts == NULL);
+  g_assert (g_queue_is_empty (player->init_queue));
+  g_assert (g_queue_is_empty (player->construct_queue));
+  g_queue_free (player->init_queue);
+  g_queue_free (player->construct_queue);
   swfdec_cache_unref (player->cache);
   if (player->loader) {
     g_object_unref (player->loader);
@@ -883,6 +898,8 @@ swfdec_player_init (SwfdecPlayer *player
   player->mouse_visible = TRUE;
   player->mouse_cursor = SWFDEC_MOUSE_CURSOR_NORMAL;
   player->iterate_timeout.callback = swfdec_player_iterate;
+  player->init_queue = g_queue_new ();
+  player->construct_queue = g_queue_new ();
 }
 
 void
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index d81b2cf..699a45a 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -86,6 +86,8 @@ struct _SwfdecPlayer
   /* iterating */
   GList *		movies;			/* list of all moveis that want to be iterated */
   SwfdecRingBuffer *	actions;		/* all actions we've queued up so far */
+  GQueue *		init_queue;		/* all movies that require an init event */
+  GQueue *		construct_queue;      	/* all movies that require an construct event */
 };
 
 struct _SwfdecPlayerClass


More information about the Swfdec mailing list