Benjamin Otte
2007-Nov-01 00:07 UTC
[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
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
Apparently Analagous Threads
- libswfdec/swfdec_load_object.c libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_resource.c libswfdec/swfdec_resource.h
- 10 commits - doc/swfdec-sections.txt libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_loader.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie_clip_loader.c libswfdec/swfdec_movie.h
- 18 commits - doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_event.c libswfdec/swfdec_event.h libswfdec/swfdec_flash_security.c
- 11 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_resource.c libswfdec/swfdec_resource_request.c
- 28 commits - configure.ac debian/changelog debian/control debian/copyright debian/.gitignore debian/libswfdec0.dirs debian/libswfdec0.files debian/libswfdec0.shlibs debian/libswfdec-dev.dirs debian/libswfdec-dev.files debian/rules debian/swf-player.dirs