Benjamin Otte
2007-Mar-15 11:53 UTC
[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
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@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@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@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@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@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@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@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@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@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@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@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@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@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
Reasonably Related Threads
- Branch 'vivi' - 3 commits - player/Makefile.am player/swfdec_debug_movies.c player/swfdec_debug_movies.h vivified/core vivified/ui
- 5 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_keys.h libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_sprite_movie_as.c player/swfdebug.c player/swfdec_debug_movies.c player/swfdec_debug_movies.h test/trace
- 109 commits - configure.ac libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_buffer.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_codec_screen.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h
- 163 commits - autogen.sh configure.ac doc/swfdec-sections.txt libswfdec-gtk/swfdec_gtk_player.c libswfdec-gtk/swfdec_gtk_player.h libswfdec-gtk/swfdec_gtk_widget.c libswfdec-gtk/swfdec_source.c libswfdec/Makefile.am libswfdec/swfdec_as_array.c
- Branch 'interpreter' - 28 commits - configure.ac libswfdec/js libswfdec/swfdec_buffer.c libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c libswfdec/swfdec_js.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_player.c