[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