[Swfdec] 3 commits - libswfdec/Makefile.am libswfdec/swfdec_as_interpret.c libswfdec/swfdec_loader.c libswfdec/swfdec_loader_internal.h libswfdec/swfdec_load_object_as.c libswfdec/swfdec_load_object.c libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_resource.c libswfdec/swfdec_resource.h libswfdec/swfdec_resource_request.c libswfdec/swfdec_resource_request.h libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_sprite_movie.h libswfdec/swfdec_style_sheet.c

Benjamin Otte company at kemper.freedesktop.org
Wed Oct 31 17:07:28 PDT 2007


 libswfdec/Makefile.am               |    2 
 libswfdec/swfdec_as_interpret.c     |   37 ++-------
 libswfdec/swfdec_load_object.c      |   34 ++++++--
 libswfdec/swfdec_load_object_as.c   |    4 
 libswfdec/swfdec_loader.c           |    7 -
 libswfdec/swfdec_loader_internal.h  |    2 
 libswfdec/swfdec_net_stream.c       |   28 +++++-
 libswfdec/swfdec_player.c           |  147 ++++++++++++++----------------------
 libswfdec/swfdec_player_internal.h  |   19 ++--
 libswfdec/swfdec_resource.c         |   72 +++++++++++++++++
 libswfdec/swfdec_resource.h         |    5 +
 libswfdec/swfdec_resource_request.c |  125 ++++++++++++++++++++++++++++++
 libswfdec/swfdec_resource_request.h |   60 ++++++++++++++
 libswfdec/swfdec_sprite_movie.c     |   27 ------
 libswfdec/swfdec_sprite_movie.h     |    4 
 libswfdec/swfdec_style_sheet.c      |    2 
 16 files changed, 398 insertions(+), 177 deletions(-)

New commits:
commit 3fcf0a319414ae119e109211c391106cba07112e
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Nov 1 00:48:23 2007 +0100

    invoke mark() on the parent or we use all user-set variables
    
    This fixes stylesheet-load-7.swf
    And you owe me a drink in Istanbul for that one, Pekka ;)

diff --git a/libswfdec/swfdec_style_sheet.c b/libswfdec/swfdec_style_sheet.c
index 0f21fd9..ccdd03c 100644
--- a/libswfdec/swfdec_style_sheet.c
+++ b/libswfdec/swfdec_style_sheet.c
@@ -57,6 +57,8 @@ swfdec_style_sheet_mark (SwfdecAsObject *object)
   for (iter = style->listeners; iter != NULL; iter = iter->next) {
     swfdec_as_object_mark (iter->data);
   }
+
+  SWFDEC_AS_OBJECT_CLASS (swfdec_style_sheet_parent_class)->mark (object);
 }
 
 static void
commit f2f3f20ef2f78e40328ae2201f6357c8475aff56
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 31 22:22:19 2007 +0100

    that function was unused

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 09e83e4..c75ae73 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1775,30 +1775,6 @@ swfdec_player_get_movie_at_level (SwfdecPlayer *player, int level)
   return NULL;
 }
 
-void
-swfdec_player_remove_level (SwfdecPlayer *player, guint depth)
-{
-  GList *walk;
-  int real_depth;
-
-  real_depth = (int) depth - 16384;
-
-  for (walk = player->roots; walk; walk = walk->next) {
-    SwfdecMovie *movie = walk->data;
-
-    if (movie->depth < real_depth)
-      continue;
-
-    if (movie->depth == real_depth) {
-      SWFDEC_DEBUG ("remove existing movie _level%u", depth);
-      swfdec_movie_remove (movie);
-      return;
-    }
-    break;
-  }
-  SWFDEC_LOG ("no movie to remove at level %u", depth);
-}
-
 static gboolean
 is_ascii (const char *s)
 {
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index e0c480a..91f48f9 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -212,8 +212,6 @@ SwfdecSpriteMovie *
 						(SwfdecPlayer *		player,
 						 SwfdecResource *	resource,
 						 int			level);
-void		swfdec_player_remove_level	(SwfdecPlayer *		player,
-						 guint			depth);
 gboolean	swfdec_player_fscommand		(SwfdecPlayer *		player,
 						 const char *		command,
 						 const char *		value);
commit ae4a348edd7a162f0fef3f12436d0f82ddfb188f
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 31 22:21:17 2007 +0100

    rework init code once again
    
    This code should now be capable of doing the right thing wrt GetURL and
    delayed instantiation of movie clips with loadMovie.
    
    And yes, it's a lot of code again, but I had to change some APIs. Some...

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 0cf8b71..99a701b 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -96,6 +96,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
 	swfdec_rect.c \
 	swfdec_rectangle.c \
 	swfdec_resource.c \
+	swfdec_resource_request.c \
 	swfdec_ringbuffer.c \
 	swfdec_script.c \
 	swfdec_security.c \
@@ -219,6 +220,7 @@ noinst_HEADERS = \
 	swfdec_player_internal.h \
 	swfdec_rect.h \
 	swfdec_resource.h \
+	swfdec_resource_request.h \
 	swfdec_ringbuffer.h \
 	swfdec_script_internal.h \
 	swfdec_security.h \
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 143f78b..83634c6 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1151,16 +1151,8 @@ swfdec_action_get_url (SwfdecAsContext *cx, guint action, const guint8 *data, gu
     SWFDEC_ERROR ("GetURL without a SwfdecPlayer");
   } else if (swfdec_player_fscommand (SWFDEC_PLAYER (cx), url, target)) {
     /* nothing to do here */
-  } else {
-    SwfdecSecurity *sec = cx->frame->security;
-    SwfdecSpriteMovie *movie = swfdec_player_get_level (SWFDEC_PLAYER (cx), target, 
-	SWFDEC_IS_RESOURCE (sec) ? SWFDEC_RESOURCE (sec) : NULL);
-    if (movie) {
-      swfdec_sprite_movie_load (movie, url, SWFDEC_LOADER_REQUEST_DEFAULT, NULL);
-    } else {
-      swfdec_player_launch (SWFDEC_PLAYER (cx), SWFDEC_LOADER_REQUEST_DEFAULT, 
-	  url, target, NULL);
-    }
+  } else if (swfdec_player_get_level (SWFDEC_PLAYER (cx), target) >= 0) {
+    swfdec_resource_load (SWFDEC_PLAYER (cx), target, url, SWFDEC_LOADER_REQUEST_DEFAULT, NULL);
   }
   g_free (url);
   g_free (target);
@@ -1195,26 +1187,15 @@ swfdec_action_get_url2 (SwfdecAsContext *cx, guint action, const guint8 *data, g
     SWFDEC_ERROR ("GetURL2 action requires a SwfdecPlayer");
   } else if (swfdec_player_fscommand (SWFDEC_PLAYER (cx), url, target)) {
     /* nothing to do here */
-  } else if (internal || variables) {
-    SwfdecSecurity *sec = cx->frame->security;
-    SwfdecSpriteMovie *movie;
+  } else if (variables) {
+    SwfdecMovie *movie;
     
-    /* FIXME: This code looks wrong - figure out how levels are handled */
-    movie = swfdec_player_get_level (SWFDEC_PLAYER (cx), target, 
-	(SWFDEC_IS_RESOURCE (sec) && !variables) ? SWFDEC_RESOURCE (sec) : NULL);
-    if (movie == NULL) {
-      movie = (SwfdecSpriteMovie *) swfdec_player_get_movie_from_string (
-	SWFDEC_PLAYER (cx), target);
-      if (!SWFDEC_IS_SPRITE_MOVIE (movie))
-	movie = NULL;
-    }
-    if (movie == NULL) {
-      /* swfdec_player_get_movie_from_value() should have warned already */
-    } else if (variables) {
-      swfdec_movie_load_variables (SWFDEC_MOVIE (movie), url, method, NULL);
-    } else {
-      swfdec_sprite_movie_load (movie, url, method, NULL);
+    movie = swfdec_player_get_movie_from_string (SWFDEC_PLAYER (cx), target);
+    if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
+      swfdec_movie_load_variables (movie, url, method, NULL);
     }
+  } else if (internal) {
+    swfdec_resource_load (SWFDEC_PLAYER (cx), target, url, method, NULL);
   } else {
     /* load an external file */
     swfdec_player_launch (SWFDEC_PLAYER (cx), method, url, target, NULL);
diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index ebd6fdc..a50edd1 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -23,11 +23,13 @@
 
 #include <string.h>
 #include "swfdec_load_object.h"
+#include "swfdec_as_frame_internal.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_loader_internal.h"
 #include "swfdec_loadertarget.h"
 #include "swfdec_player_internal.h"
+#include "swfdec_resource_request.h"
 
 /*** SWFDEC_LOADER_TARGET ***/
 
@@ -185,24 +187,40 @@ swfdec_load_object_init (SwfdecLoadObject *load_object)
 {
 }
 
+static void
+swfdec_load_object_got_loader (SwfdecPlayer *player, SwfdecLoader *loader, gpointer obj)
+{
+  SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (obj);
+
+  if (loader == NULL) {
+    return;
+  }
+  load_object->loader = loader;
+
+  swfdec_loader_set_target (load_object->loader,
+      SWFDEC_LOADER_TARGET (load_object));
+  swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
+}
+
 static gboolean
 swfdec_load_object_load (SwfdecLoadObject *load_object, const char *url, 
     SwfdecLoaderRequest request, SwfdecBuffer *data)
 {
+  SwfdecPlayer *player;
+  SwfdecSecurity *sec;
   SwfdecAsValue val;
 
   g_return_val_if_fail (SWFDEC_IS_LOAD_OBJECT (load_object), FALSE);
   g_return_val_if_fail (url != NULL, FALSE);
 
+  player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context);
   swfdec_load_object_reset (load_object);
-  load_object->loader = swfdec_player_load (
-      SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context), url, request, data);
-  if (load_object->loader == NULL)
-    return FALSE;
-
-  swfdec_loader_set_target (load_object->loader,
-      SWFDEC_LOADER_TARGET (load_object));
-  swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
+  /* get the current security */
+  g_assert (SWFDEC_AS_CONTEXT (player)->frame);
+  sec = SWFDEC_AS_CONTEXT (player)->frame->security;
+  g_object_ref (load_object);
+  swfdec_player_request_resource (player, sec, url, request, data,
+      swfdec_load_object_got_loader, load_object, g_object_unref);
 
   SWFDEC_AS_VALUE_SET_INT (&val, 0);
   swfdec_as_object_set_variable_and_flags (load_object->target,
diff --git a/libswfdec/swfdec_load_object_as.c b/libswfdec/swfdec_load_object_as.c
index 045eb0d..c239ace 100644
--- a/libswfdec/swfdec_load_object_as.c
+++ b/libswfdec/swfdec_load_object_as.c
@@ -29,9 +29,9 @@
 #include "swfdec_loadertarget.h"
 #include "swfdec_player_internal.h"
 
-SWFDEC_AS_NATIVE (301, 0, swfdec_load_object_load)
+SWFDEC_AS_NATIVE (301, 0, swfdec_load_object_as_load)
 void
-swfdec_load_object_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc,
+swfdec_load_object_as_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
   const char *url;
diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index ca84656..255b943 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -240,22 +240,19 @@ swfdec_loader_perform_push (gpointer loaderp, gpointer unused)
 }
 
 SwfdecLoader *
-swfdec_loader_load (SwfdecLoader *loader, const char *url_string,
+swfdec_loader_load (SwfdecLoader *loader, const SwfdecURL *url,
     SwfdecLoaderRequest request, const char *data, gsize data_len)
 {
   SwfdecLoader *ret;
   SwfdecLoaderClass *klass;
-  SwfdecURL *url;
 
   g_return_val_if_fail (SWFDEC_IS_LOADER (loader), NULL);
-  g_return_val_if_fail (url_string != NULL, NULL);
+  g_return_val_if_fail (url != NULL, NULL);
   g_return_val_if_fail (data != NULL || data_len == 0, NULL);
 
   klass = SWFDEC_LOADER_GET_CLASS (loader);
   g_return_val_if_fail (klass->load != NULL, NULL);
-  url = swfdec_url_new_relative (loader->url, url_string);
   ret = g_object_new (G_OBJECT_CLASS_TYPE (klass), "url", url, NULL);
-  swfdec_url_free (url);
   klass->load (ret, loader, request, data, data_len);
   return ret;
 }
diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h
index 386f910..22b2421 100644
--- a/libswfdec/swfdec_loader_internal.h
+++ b/libswfdec/swfdec_loader_internal.h
@@ -35,7 +35,7 @@ typedef enum {
 } SwfdecLoaderState;
 
 SwfdecLoader *		swfdec_loader_load		(SwfdecLoader *		loader,
-							 const char *		url,
+							 const SwfdecURL *    	url,
 							 SwfdecLoaderRequest	request,
 							 const char *		data,
 							 gsize			data_len);
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index fa119ba..91f0974 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -24,11 +24,13 @@
 #include <math.h>
 #include "swfdec_net_stream.h"
 #include "swfdec_amf.h"
+#include "swfdec_as_frame_internal.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_audio_flv.h"
 #include "swfdec_debug.h"
 #include "swfdec_loader_internal.h"
 #include "swfdec_loadertarget.h"
+#include "swfdec_resource_request.h"
 
 /* NB: code and level must be rooted gc-strings */
 static void
@@ -482,21 +484,33 @@ swfdec_net_stream_new (SwfdecNetConnection *conn)
   return stream;
 }
 
+static void
+swfdec_net_stream_got_loader (SwfdecPlayer *player, SwfdecLoader *loader, gpointer streamp)
+{
+  SwfdecNetStream *stream = SWFDEC_NET_STREAM (streamp);
+
+  if (loader == NULL || SWFDEC_AS_OBJECT (stream)->context == NULL)
+    return;
+
+  swfdec_net_stream_set_loader (stream, loader);
+  g_object_unref (loader);
+}
+
 void
 swfdec_net_stream_set_url (SwfdecNetStream *stream, const char *url)
 {
-  SwfdecLoader *loader;
+  SwfdecAsContext *cx;
 
   g_return_if_fail (SWFDEC_IS_NET_STREAM (stream));
   g_return_if_fail (url != NULL);
 
   /* FIXME: use the connection once connections are implemented */
-  loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (stream)->context), url,
-      SWFDEC_LOADER_REQUEST_DEFAULT, NULL);
-  if (loader) {
-    swfdec_net_stream_set_loader (stream, loader);
-    g_object_unref (loader);
-  }
+  cx = SWFDEC_AS_OBJECT (stream)->context;
+  g_assert (cx->frame);
+  g_object_ref (stream);
+  swfdec_player_request_resource (SWFDEC_PLAYER (cx), cx->frame->security, url,
+      SWFDEC_LOADER_REQUEST_DEFAULT, NULL, swfdec_net_stream_got_loader, stream, 
+      g_object_unref);
 }
 
 void
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 439ceda..09e83e4 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -43,9 +43,10 @@
 #include "swfdec_loader_internal.h"
 #include "swfdec_marshal.h"
 #include "swfdec_movie.h"
+#include "swfdec_resource.h"
+#include "swfdec_resource_request.h"
 #include "swfdec_script_internal.h"
 #include "swfdec_sprite_movie.h"
-#include "swfdec_resource.h"
 #include "swfdec_utils.h"
 
 /*** gtk-doc ***/
@@ -836,6 +837,7 @@ swfdec_player_dispose (GObject *object)
   guint i;
 
   swfdec_player_stop_all_sounds (player);
+  swfdec_player_resource_request_finish (player);
   g_hash_table_destroy (player->registered_classes);
 
   while (player->roots)
@@ -1611,6 +1613,8 @@ swfdec_player_init (SwfdecPlayer *player)
   player->iterate_timeout.callback = swfdec_player_iterate;
   player->stage_width = -1;
   player->stage_height = -1;
+
+  swfdec_player_resource_request_init (player);
 }
 
 void
@@ -1690,42 +1694,75 @@ swfdec_player_invalidate (SwfdecPlayer *player, const SwfdecRect *rect)
 /**
  * swfdec_player_get_level:
  * @player: a #SwfdecPlayer
- * @name: name of the level to request
- * @create: resource to create the movie with if it doesn't exist
- *
- * This function is used to look up root movies in the given @player. The 
- * algorithm used is like this: First, check that @name actually references a
- * root level movie. If it does not, return %NULL. If the movie for the given 
- * level already exists, return it. If it does not, create it when @create was 
- * set to %TRUE and return the newly created movie. Otherwise return %NULL.
- *
- * Returns: the #SwfdecMovie referenced by the given @name or %NULL if no such
- *          movie exists. Note that if a new movie is created, it will not be
- *          fully initialized (yes, this function sucks).
+ * @name: a name that is supposed to refer to a level
+ *
+ * Checks if the given @name refers to a level, and if so, returns the level.
+ * An example for such a name is "_level5". These strings are used to refer to
+ * root movies inside the Flash player.
+ *
+ * Returns: the level referred to by @name or -1 if none
  **/
-SwfdecSpriteMovie *
-swfdec_player_get_level (SwfdecPlayer *player, const char *name, SwfdecResource *create)
+int
+swfdec_player_get_level (SwfdecPlayer *player, const char *name)
 {
-  SwfdecSpriteMovie *movie;
-  GList *walk;
-  const char *s;
   char *end;
-  int depth;
   gulong l;
 
-  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
-  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), -1);
+  g_return_val_if_fail (name != NULL, -1);
 
   /* check name starts with "_level" */
   if (swfdec_strncmp (SWFDEC_AS_CONTEXT (player)->version, name, "_level", 6) != 0)
-    return NULL;
+    return -1;
   name += 6;
   /* extract depth from rest string (or fail if it's not a depth) */
   errno = 0;
   l = strtoul (name, &end, 10);
   if (errno != 0 || *end != 0 || l > G_MAXINT)
+    return -1;
+  return l;
+}
+
+SwfdecSpriteMovie *
+swfdec_player_create_movie_at_level (SwfdecPlayer *player, SwfdecResource *resource,
+    int level)
+{
+  SwfdecMovie *movie;
+  const char *s;
+
+  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+  g_return_val_if_fail (level >= 0, NULL);
+  g_return_val_if_fail (swfdec_player_get_movie_at_level (player, level) == NULL, NULL);
+
+  /* create new root movie */
+  s = swfdec_as_context_give_string (SWFDEC_AS_CONTEXT (player), g_strdup_printf ("_level%d", level));
+  movie = swfdec_movie_new (player, level - 16384, NULL, resource, NULL, s);
+  if (movie == NULL)
     return NULL;
-  depth = l - 16384;
+  movie->name = SWFDEC_AS_STR_EMPTY;
+  return SWFDEC_SPRITE_MOVIE (movie);
+}
+
+/**
+ * swfdec_player_get_movie_at_level:
+ * @player: a #SwfdecPlayer
+ * @level: number of the level
+ *
+ * This function is used to look up root movies in the given @player. 
+ *
+ * Returns: the #SwfdecMovie located at the given level or %NULL if there is no
+ *          movie at that level.
+ **/
+SwfdecSpriteMovie *
+swfdec_player_get_movie_at_level (SwfdecPlayer *player, int level)
+{
+  GList *walk;
+  int depth;
+
+  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+  g_return_val_if_fail (level >= 0, NULL);
+
+  depth = level - 16384;
   /* find movie */
   for (walk = player->roots; walk; walk = walk->next) {
     SwfdecMovie *cur = walk->data;
@@ -1735,14 +1772,7 @@ swfdec_player_get_level (SwfdecPlayer *player, const char *name, SwfdecResource
       return SWFDEC_SPRITE_MOVIE (cur);
     break;
   }
-  /* bail if create isn't set*/
-  if (create == NULL)
-    return NULL;
-  /* create new root movie */
-  s = swfdec_as_context_give_string (SWFDEC_AS_CONTEXT (player), g_strdup_printf ("_level%lu", l));
-  movie = SWFDEC_SPRITE_MOVIE (swfdec_movie_new (player, depth, NULL, create, NULL, s));
-  SWFDEC_MOVIE (movie)->name = SWFDEC_AS_STR_EMPTY;
-  return movie;
+  return NULL;
 }
 
 void
@@ -1769,41 +1799,6 @@ swfdec_player_remove_level (SwfdecPlayer *player, guint depth)
   SWFDEC_LOG ("no movie to remove at level %u", depth);
 }
 
-SwfdecLoader *
-swfdec_player_load (SwfdecPlayer *player, const char *url, 
-    SwfdecLoaderRequest request, SwfdecBuffer *buffer)
-{
-  SwfdecAsContext *cx;
-  SwfdecSecurity *sec;
-  SwfdecURL *full;
-
-  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
-  g_return_val_if_fail (url != NULL, NULL);
-
-  g_assert (player->resource);
-  /* create absolute url first */
-  full = swfdec_url_new_relative (swfdec_loader_get_url (player->resource->loader), url);
-  /* figure out the right security object (FIXME: let the person loading it provide it?) */
-  cx = SWFDEC_AS_CONTEXT (player);
-  if (cx->frame) {
-    sec = cx->frame->security;
-  } else {
-    g_warning ("swfdec_player_load() should only be called from scripts");
-    sec = SWFDEC_SECURITY (player->resource);
-  }
-  if (!swfdec_security_allow_url (sec, full)) {
-    SWFDEC_ERROR ("not allowing access to %s", url);
-    return NULL;
-  }
-
-  if (buffer) {
-    return swfdec_loader_load (player->resource->loader, url, request, 
-	(const char *) buffer->data, buffer->length);
-  } else {
-    return swfdec_loader_load (player->resource->loader, url, request, NULL, 0);
-  }
-}
-
 static gboolean
 is_ascii (const char *s)
 {
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index cd1f1db..e0c480a 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -62,6 +62,7 @@ struct _SwfdecPlayer
   guint			height;			/* height of movie */
   GList *		roots;			/* all the root movies */
   GList *		load_objects;		/* all the load objects */
+  GSList *		resource_requests;	/* all external requested URIs - see swfdec_resource_request.[ch] */
   SwfdecCache *		cache;			/* player cache */
   gboolean		bgcolor_set;		/* TRUE if the background color has been set */
   SwfdecColor		bgcolor;		/* background color */
@@ -201,19 +202,21 @@ void		swfdec_player_stop_sounds	(SwfdecPlayer *		player,
 						 SwfdecAudioRemoveFunc	func,
 						 gpointer		data);
 void		swfdec_player_stop_all_sounds	(SwfdecPlayer *		player);
+gboolean	swfdec_player_get_level		(SwfdecPlayer *		player,
+						 const char *		name);
 SwfdecSpriteMovie *
-		swfdec_player_get_level		(SwfdecPlayer *		player,
-						 const char *		name,
-						 SwfdecResource *	resource);
+		swfdec_player_get_movie_at_level(SwfdecPlayer *		player,
+						 int			level);
+SwfdecSpriteMovie *
+		swfdec_player_create_movie_at_level 
+						(SwfdecPlayer *		player,
+						 SwfdecResource *	resource,
+						 int			level);
 void		swfdec_player_remove_level	(SwfdecPlayer *		player,
 						 guint			depth);
 gboolean	swfdec_player_fscommand		(SwfdecPlayer *		player,
 						 const char *		command,
 						 const char *		value);
-SwfdecLoader *	swfdec_player_load		(SwfdecPlayer *         player,
-						 const char *		url,
-						 SwfdecLoaderRequest	request,
-						 SwfdecBuffer *		buffer);
 void		swfdec_player_launch		(SwfdecPlayer *         player,
 						 SwfdecLoaderRequest	request,
 						 const char *		url,
diff --git a/libswfdec/swfdec_resource.c b/libswfdec/swfdec_resource.c
index 7847f48..d231111 100644
--- a/libswfdec/swfdec_resource.c
+++ b/libswfdec/swfdec_resource.c
@@ -25,7 +25,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include "swfdec_resource.h"
+#include "swfdec_as_frame_internal.h"
 #include "swfdec_as_internal.h"
+#include "swfdec_as_interpret.h"
 #include "swfdec_character.h"
 #include "swfdec_debug.h"
 #include "swfdec_decoder.h"
@@ -34,6 +36,7 @@
 #include "swfdec_loader_internal.h"
 #include "swfdec_loadertarget.h"
 #include "swfdec_player_internal.h"
+#include "swfdec_resource_request.h"
 #include "swfdec_script.h"
 #include "swfdec_sprite.h"
 #include "swfdec_swf_decoder.h"
@@ -302,3 +305,72 @@ swfdec_resource_add_export (SwfdecResource *instance, SwfdecCharacter *character
   g_hash_table_insert (instance->export_names, g_object_ref (character), g_strdup (name));
 }
 
+static void
+swfdec_resource_do_load (SwfdecPlayer *player, SwfdecLoader *loader, gpointer targetp)
+{
+  SwfdecSpriteMovie *movie;
+  SwfdecResource *resource;
+  SwfdecMovie *mov;
+  int level = -1;
+  char *target = targetp;
+
+  if (loader == NULL) {
+    /* *** Security Sandbox Violation *** */
+    return;
+  }
+
+  movie = (SwfdecSpriteMovie *) swfdec_action_lookup_object (SWFDEC_AS_CONTEXT (player),
+      player->roots->data, target, target + strlen (target));
+  resource = swfdec_resource_new (loader, NULL);
+  if (!SWFDEC_IS_SPRITE_MOVIE (movie)) {
+    level = swfdec_player_get_level (player, target);
+    if (level < 0)
+      goto fail;
+    movie = swfdec_player_get_movie_at_level (player, level);
+  }
+  if (movie == NULL) {
+    movie = swfdec_player_create_movie_at_level (player, resource, level);
+    mov = SWFDEC_MOVIE (movie);
+  } else {
+    mov = SWFDEC_MOVIE (movie);
+    swfdec_sprite_movie_unload (movie);
+    g_object_unref (mov->resource);
+    mov->resource = resource;
+    swfdec_resource_set_movie (mov->resource, movie);
+  }
+  g_object_unref (loader);
+  return;
+
+fail:
+  SWFDEC_WARNING ("%s does not reference a movie, not loading %s", target,
+      swfdec_url_get_url (swfdec_loader_get_url (loader)));
+  swfdec_loader_close (loader);
+  g_object_unref (loader);
+  return;
+}
+
+/* NB: must be called from a script */
+void
+swfdec_resource_load (SwfdecPlayer *player, const char *target, const char *url, 
+    SwfdecLoaderRequest request, SwfdecBuffer *buffer)
+{
+  SwfdecSpriteMovie *movie;
+  char *path;
+
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+  g_return_if_fail (target != NULL);
+  g_return_if_fail (url != NULL);
+
+  g_assert (SWFDEC_AS_CONTEXT (player)->frame != NULL);
+  movie = (SwfdecSpriteMovie *) swfdec_player_get_movie_from_string (player, target);
+  if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
+    path = swfdec_movie_get_path (SWFDEC_MOVIE (movie), TRUE);
+  } else if (swfdec_player_get_level (player, target) >= 0) {
+    path = g_strdup (target);
+  } else {
+    SWFDEC_WARNING ("%s does not reference a movie, not loading %s", target, url);
+    return;
+  }
+  swfdec_player_request_resource (player, SWFDEC_AS_CONTEXT (player)->frame->security, 
+      url, request, buffer, swfdec_resource_do_load, path, g_free);
+}
diff --git a/libswfdec/swfdec_resource.h b/libswfdec/swfdec_resource.h
index c87d205..331a102 100644
--- a/libswfdec/swfdec_resource.h
+++ b/libswfdec/swfdec_resource.h
@@ -71,5 +71,10 @@ gpointer	swfdec_resource_get_export		(SwfdecResource *	root,
 const char *	swfdec_resource_get_export_name    	(SwfdecResource *	root,
 							 SwfdecCharacter *	character);
 
+void		swfdec_resource_load			(SwfdecPlayer *		player,
+							 const char *		target,
+							 const char *		url,
+							 SwfdecLoaderRequest	request,
+							 SwfdecBuffer *		buffer);
 G_END_DECLS
 #endif
diff --git a/libswfdec/swfdec_resource_request.c b/libswfdec/swfdec_resource_request.c
new file mode 100644
index 0000000..32a5ed6
--- /dev/null
+++ b/libswfdec/swfdec_resource_request.c
@@ -0,0 +1,125 @@
+/* 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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_resource_request.h"
+#include "swfdec_debug.h"
+#include "swfdec_loader_internal.h"
+#include "swfdec_player_internal.h"
+#include "swfdec_resource.h"
+
+static void
+swfdec_resource_request_free (SwfdecResourceRequest *request)
+{
+  g_return_if_fail (request != NULL);
+
+  g_object_unref (request->security);
+  if (request->destroy)
+    request->destroy (request->data);
+  g_free (request->url);
+  if (request->buffer)
+    swfdec_buffer_unref (request->buffer);
+  g_slice_free (SwfdecResourceRequest, request);
+}
+
+static void
+swfdec_request_resource_perform_one (gpointer requestp, gpointer playerp)
+{
+  SwfdecPlayer *player = SWFDEC_PLAYER (playerp);
+  SwfdecResourceRequest *request = requestp;
+  SwfdecLoader *loader;
+  SwfdecURL *url;
+
+  g_assert (player->resource);
+  /* create absolute url first */
+  url = swfdec_url_new_relative (swfdec_loader_get_url (player->resource->loader), request->url);
+  if (!swfdec_security_allow_url (request->security, url)) {
+    /* FIXME: Need to load policy file from given URL */
+    SWFDEC_ERROR ("not allowing access to %s", swfdec_url_get_url (url));
+    loader = NULL;
+  } else {
+    if (request->buffer) {
+      loader = swfdec_loader_load (player->resource->loader, url, request->request, 
+	  (const char *) request->buffer->data, request->buffer->length);
+    } else {
+      loader = swfdec_loader_load (player->resource->loader, url, request->request, NULL, 0);
+    }
+  }
+  swfdec_url_free (url);
+  request->func (player, loader, request->data);
+  swfdec_resource_request_free (request);
+}
+
+static void
+swfdec_request_resource_perform (gpointer playerp, gpointer unused)
+{
+  SwfdecPlayer *player = SWFDEC_PLAYER (playerp);
+
+  g_slist_foreach (player->resource_requests, swfdec_request_resource_perform_one, player);
+  g_slist_free (player->resource_requests);
+  player->resource_requests = NULL;
+}
+
+void
+swfdec_player_request_resource (SwfdecPlayer *player, SwfdecSecurity *security,
+    const char *url, SwfdecLoaderRequest req, SwfdecBuffer *buffer, 
+    SwfdecResourceFunc func, gpointer data, GDestroyNotify destroy)
+{
+  SwfdecResourceRequest *request;
+
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+  g_return_if_fail (SWFDEC_IS_SECURITY (security));
+  g_return_if_fail (url != NULL);
+  g_return_if_fail (func != NULL);
+
+  request = g_slice_new0 (SwfdecResourceRequest);
+  request->security = g_object_ref (security);
+  request->url = g_strdup (url);
+  request->request = req;
+  if (buffer)
+    request->buffer = swfdec_buffer_ref (buffer);
+  request->func = func;
+  request->destroy = destroy;
+  request->data = data;
+
+  if (player->resource_requests == NULL) {
+    swfdec_player_add_external_action (player, player, swfdec_request_resource_perform, NULL);
+  }
+  player->resource_requests = g_slist_append (player->resource_requests, request);
+}
+
+void
+swfdec_player_resource_request_init (SwfdecPlayer *player)
+{
+  /* empty */
+}
+
+void
+swfdec_player_resource_request_finish (SwfdecPlayer *player)
+{
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
+  g_slist_foreach (player->resource_requests, (GFunc) swfdec_resource_request_free, NULL);
+  g_slist_free (player->resource_requests);
+  player->resource_requests = NULL;
+}
+
diff --git a/libswfdec/swfdec_resource_request.h b/libswfdec/swfdec_resource_request.h
new file mode 100644
index 0000000..b970a0a
--- /dev/null
+++ b/libswfdec/swfdec_resource_request.h
@@ -0,0 +1,60 @@
+/* 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_RESOURCE_REQUEST_H_
+#define _SWFDEC_RESOURCE_REQUEST_H_
+
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_security.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecResourceRequest SwfdecResourceRequest;
+typedef void (* SwfdecResourceFunc) (SwfdecPlayer *player, SwfdecLoader *loader, gpointer data);
+
+struct _SwfdecResourceRequest
+{
+  SwfdecSecurity *	security;     	/* security context hen loading */
+
+  char *		url;		/* URL we're gonna load */
+  SwfdecLoaderRequest	request;	/* how are we goona load this URL? */
+  SwfdecBuffer *	buffer;		/* data to pass to load request or NULL */
+
+  SwfdecResourceFunc	func;		/* function to call when we got a loader (or an error) */
+  GDestroyNotify	destroy;	/* function to call on player dispose */
+  gpointer		data;		/* function to pass to the above functions */
+};
+
+/* public api for swfdec */
+
+void		swfdec_player_request_resource		(SwfdecPlayer *		player,
+							 SwfdecSecurity *	security,
+							 const char *		url,
+							 SwfdecLoaderRequest	req,
+							 SwfdecBuffer *		buffer,
+							 SwfdecResourceFunc	func,
+							 gpointer		data,
+							 GDestroyNotify		destroy);
+
+/* private api for swfdec_player.c */
+void		swfdec_player_resource_request_init	(SwfdecPlayer *		player);
+void		swfdec_player_resource_request_finish	(SwfdecPlayer *		player);
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index e38a3e1..a78a306 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -721,7 +721,8 @@ swfdec_sprite_movie_clear (SwfdecAsContext *cx, SwfdecAsObject *object,
  * swfdec_sprite_movie_unload:
  * @movie: a #SwfdecMovie
  *
- * Unloads all contents from the given movie.
+ * Clears all contents from the given movie. This means deleting all
+ * variables and removing all children movie clips.
  **/
 void
 swfdec_sprite_movie_unload (SwfdecSpriteMovie *movie)
@@ -740,27 +741,3 @@ swfdec_sprite_movie_unload (SwfdecSpriteMovie *movie)
   movie->sprite = NULL;
 }
 
-void
-swfdec_sprite_movie_load (SwfdecSpriteMovie *movie, const char *url, SwfdecLoaderRequest request, 
-    SwfdecBuffer *data)
-{
-  SwfdecResource *resource;
-  SwfdecLoader *loader;
-
-  g_return_if_fail (SWFDEC_IS_SPRITE_MOVIE (movie));
-  g_return_if_fail (url != NULL);
-
-  swfdec_sprite_movie_unload (movie);
-
-  loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context),
-      url, request, data);
-  if (loader == NULL)
-    return;
-
-  resource = swfdec_resource_new (loader, NULL);
-  g_object_unref (SWFDEC_MOVIE (movie)->resource);
-  SWFDEC_MOVIE (movie)->resource = resource;
-  swfdec_resource_set_movie (resource, movie);
-  g_object_unref (loader);
-}
-
diff --git a/libswfdec/swfdec_sprite_movie.h b/libswfdec/swfdec_sprite_movie.h
index fa15e7b..3062bd1 100644
--- a/libswfdec/swfdec_sprite_movie.h
+++ b/libswfdec/swfdec_sprite_movie.h
@@ -68,10 +68,6 @@ void		swfdec_sprite_movie_goto		(SwfdecSpriteMovie *	movie,
 							 guint			goto_frame);
 
 void		swfdec_sprite_movie_unload		(SwfdecSpriteMovie *	movie);
-void		swfdec_sprite_movie_load		(SwfdecSpriteMovie *  	movie,
-							 const char *		url,
-					  		 SwfdecLoaderRequest	request,
-							 SwfdecBuffer *		data);
 
 
 G_END_DECLS


More information about the Swfdec mailing list