Benjamin Otte
2007-Apr-04 10:15 UTC
[Swfdec] Branch 'as' - 17 commits - configure.ac doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt doc/swfdec.types libswfdec-gtk/Makefile.am libswfdec-gtk/swfdec-gtk.h libswfdec-gtk/swfdec_gtk_loader.c libswfdec-gtk/swfdec_gtk_loader.h libswfdec-gtk/swfdec_gtk_player.c libswfdec-gtk/swfdec_gtk_player.h libswfdec-gtk/swfdec_playback_alsa.c libswfdec-gtk/swfdec_source.c libswfdec/Makefile.am libswfdec/swfdec_amf.c libswfdec/swfdec_amf.h libswfdec/swfdec_as_array.c libswfdec/swfdec_as_array.h libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h libswfdec/swfdec_button.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_cached.c libswfdec/swfdec_connection.c libswfdec/swfdec_connection.h libswfdec/swfdec_debugger.c libswfdec/swfdec_edittext.c libswfdec/swfdec_edittext.h libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_event.c libswfdec/swfdec_event.h libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_font.c libswfdec/swfdec_graphic.c libswfdec/swfdec_graphic.h libswfdec/swfdec_js.c libswfdec/swfdec_js_movie.c libswfdec/swfdec_listener.c libswfdec/swfdec_listener.h libswfdec/swfdec_loader.c libswfdec/swfdec_loader.h libswfdec/swfdec_loader_internal.h libswfdec/swfdec_morphshape.c libswfdec/swfdec_movie.c libswfdec/swfdec_movie.h libswfdec/swfdec_net_stream.c libswfdec/swfdec_net_stream.h libswfdec/swfdec_player.c libswfdec/swfdec_player.h libswfdec/swfdec_player_internal.h libswfdec/swfdec_root_movie.c libswfdec/swfdec_script.c libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_video.c libswfdec/swfdec_video_movie.c libswfdec/swfdec_xml.c libswfdec/swfdec_xml.h player/swfdebug.c player/swfplay.c test/dump.c test/image test/parse.c test/sound test/swfdec-extract.c test/trace
configure.ac | 27 +++ doc/Makefile.am | 3 doc/swfdec-docs.sgml | 1 doc/swfdec-sections.txt | 18 ++ doc/swfdec.types | 2 libswfdec-gtk/Makefile.am | 6 libswfdec-gtk/swfdec-gtk.h | 1 libswfdec-gtk/swfdec_gtk_loader.c | 243 +++++++++++++++++++++++++++++++++++ libswfdec-gtk/swfdec_gtk_loader.h | 44 ++++++ libswfdec-gtk/swfdec_gtk_player.c | 23 +-- libswfdec-gtk/swfdec_gtk_player.h | 9 - libswfdec-gtk/swfdec_playback_alsa.c | 3 libswfdec-gtk/swfdec_source.c | 32 +++- libswfdec/Makefile.am | 35 ++--- libswfdec/swfdec_amf.c | 126 ++++++++---------- libswfdec/swfdec_amf.h | 16 +- libswfdec/swfdec_as_array.c | 104 ++++++++++++++ libswfdec/swfdec_as_array.h | 56 ++++++++ libswfdec/swfdec_as_context.c | 188 ++++++++++++++++++++++++++- libswfdec/swfdec_as_context.h | 13 + libswfdec/swfdec_as_object.c | 49 ++++++- libswfdec/swfdec_as_object.h | 11 + libswfdec/swfdec_as_types.c | 31 ++++ libswfdec/swfdec_as_types.h | 33 ++++ libswfdec/swfdec_button.c | 4 libswfdec/swfdec_button_movie.c | 4 libswfdec/swfdec_cached.c | 3 libswfdec/swfdec_connection.c | 61 +++----- libswfdec/swfdec_connection.h | 8 - libswfdec/swfdec_debugger.c | 55 +------ libswfdec/swfdec_edittext.c | 56 +++----- libswfdec/swfdec_edittext.h | 4 libswfdec/swfdec_edittext_movie.c | 65 +++------ libswfdec/swfdec_event.c | 85 +++++------- libswfdec/swfdec_event.h | 11 - libswfdec/swfdec_flv_decoder.c | 5 libswfdec/swfdec_font.c | 19 ++ libswfdec/swfdec_graphic.c | 3 libswfdec/swfdec_graphic.h | 5 libswfdec/swfdec_js.c | 2 libswfdec/swfdec_js_movie.c | 50 ------- libswfdec/swfdec_listener.c | 98 +++++--------- libswfdec/swfdec_listener.h | 9 - libswfdec/swfdec_loader.c | 46 ++---- libswfdec/swfdec_loader.h | 3 libswfdec/swfdec_loader_internal.h | 22 +++ libswfdec/swfdec_morphshape.c | 14 +- libswfdec/swfdec_movie.c | 146 +++++++++++++++++---- libswfdec/swfdec_movie.h | 10 - libswfdec/swfdec_net_stream.c | 90 ++++++------ libswfdec/swfdec_net_stream.h | 6 libswfdec/swfdec_player.c | 124 +++++++++-------- libswfdec/swfdec_player.h | 3 libswfdec/swfdec_player_internal.h | 19 +- libswfdec/swfdec_root_movie.c | 12 - libswfdec/swfdec_script.c | 10 - libswfdec/swfdec_sprite.c | 3 libswfdec/swfdec_sprite_movie.c | 4 libswfdec/swfdec_swf_decoder.c | 1 libswfdec/swfdec_video.c | 12 + libswfdec/swfdec_video_movie.c | 4 libswfdec/swfdec_xml.c | 53 ++----- libswfdec/swfdec_xml.h | 14 +- player/swfdebug.c | 8 - player/swfplay.c | 15 -- test/dump.c | 8 - test/image/image.c | 10 - test/parse.c | 10 - test/sound/sound.c | 10 - test/swfdec-extract.c | 10 - test/trace/trace.c | 9 - 71 files changed, 1515 insertions(+), 782 deletions(-) New commits: diff-tree df9459902a3d4cc821233ce7a973c1284cb4ffcf (from 31b77da7d447857b2a0769833c11a06fe870586a) Author: Benjamin Otte <otte@gnome.org> Date: Wed Apr 4 09:38:49 2007 +0200 unhook SpiderMonkey The current code does no ActionScript execution at all diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index be8455c..b46bcc0 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -1,6 +1,4 @@ -SUBDIRS = jpeg js - -DIST_SUBDIRS = jpeg js +SUBDIRS = jpeg CODECS @@ -13,9 +11,20 @@ endif lib_LTLIBRARIES = libswfdec-@SWFDEC_MAJORMINOR@.la -js_cflags = -I$(srcdir)/js/ -I./js -DXP_UNIX -DDEBUG +foofiles = \ + swfdec_js.c \ + swfdec_js_color.c \ + swfdec_js_connection.c \ + swfdec_js_global.c \ + swfdec_js_mouse.c \ + swfdec_js_movie.c \ + swfdec_js_net_stream.c \ + swfdec_js_sound.c \ + swfdec_js_video.c \ + swfdec_js_xml.c libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES = \ + swfdec_as_array.c \ swfdec_as_context.c \ swfdec_as_frame.c \ swfdec_as_function.c \ @@ -53,16 +62,6 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_graphic_movie.c \ swfdec_html_parser.c \ swfdec_image.c \ - swfdec_js.c \ - swfdec_js_color.c \ - swfdec_js_connection.c \ - swfdec_js_global.c \ - swfdec_js_mouse.c \ - swfdec_js_movie.c \ - swfdec_js_net_stream.c \ - swfdec_js_sound.c \ - swfdec_js_video.c \ - swfdec_js_xml.c \ swfdec_listener.c \ swfdec_loader.c \ swfdec_loadertarget.c \ @@ -78,7 +77,6 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES swfdec_root_movie.c \ swfdec_root_sprite.c \ swfdec_script.c \ - swfdec_scriptable.c \ swfdec_shape.c \ swfdec_sound.c \ swfdec_sprite.c \ @@ -92,7 +90,7 @@ libswfdec_@SWFDEC_MAJORMINOR@_la_SOURCES libswfdec_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ $(GLOBAL_CFLAGS) $(CAIRO_CFLAGS) $(GLIB_CFLAGS) $(PANGO_CFLAGS) \ - -I$(srcdir)/jpeg/ $(js_cflags) $(LIBOIL_CFLAGS) $(FFMPEG_CFLAGS) \ + -I$(srcdir)/jpeg/ $(LIBOIL_CFLAGS) $(FFMPEG_CFLAGS) \ -DG_LOG_DOMAIN=\"Swfdec\" libswfdec_@SWFDEC_MAJORMINOR@_la_LDFLAGS = \ -version-info $(SWFDEC_LIBVERSION) \ @@ -107,11 +105,12 @@ public_headers = \ swfdec_loader.h \ swfdec_player.h -libswfdec_@SWFDEC_MAJORMINOR@_la_LIBADD = jpeg/libjpeg.la js/libjs.la +libswfdec_@SWFDEC_MAJORMINOR@_la_LIBADD = jpeg/libjpeg.la libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINOR@/libswfdec libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = $(public_headers) swfdec_enums.h noinst_HEADERS = \ + swfdec_as_array.h \ swfdec_as_context.h \ swfdec_as_frame.h \ swfdec_as_function.h \ @@ -143,7 +142,6 @@ noinst_HEADERS = \ swfdec_graphic.h \ swfdec_graphic_movie.h \ swfdec_image.h \ - swfdec_js.h \ swfdec_listener.h \ swfdec_loader_internal.h \ swfdec_loadertarget.h \ @@ -159,7 +157,6 @@ noinst_HEADERS = \ swfdec_root_movie.h \ swfdec_root_sprite.h \ swfdec_script.h \ - swfdec_scriptable.h \ swfdec_shape.h \ swfdec_sound.h \ swfdec_sprite.h \ diff --git a/libswfdec/swfdec_amf.c b/libswfdec/swfdec_amf.c index e1ac8ba..9e47ae3 100644 --- a/libswfdec/swfdec_amf.c +++ b/libswfdec/swfdec_amf.c @@ -22,140 +22,137 @@ #endif #include "swfdec_amf.h" -#include "swfdec_bits.h" +#include "swfdec_as_array.h" #include "swfdec_debug.h" -#include "js/jsapi.h" -typedef gboolean (* SwfdecAmfParseFunc) (JSContext *cx, SwfdecBits *bits, jsval *val); +typedef gboolean (* SwfdecAmfParseFunc) (SwfdecAsContext *cx, SwfdecBits *bits, SwfdecAsValue *val); extern const SwfdecAmfParseFunc parse_funcs[SWFDEC_AMF_N_TYPES]; static gboolean -swfdec_amf_parse_boolean (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_boolean (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val) { - *val = swfdec_bits_get_u8 (bits) ? JSVAL_TRUE : JSVAL_FALSE; + SWFDEC_AS_VALUE_SET_BOOLEAN (val, swfdec_bits_get_u8 (bits) ? TRUE : FALSE); return TRUE; } static gboolean -swfdec_amf_parse_number (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_number (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val) { - double d = swfdec_bits_get_bdouble (bits); - - if (!JS_NewNumberValue (cx, d, val)) - return FALSE; + SWFDEC_AS_VALUE_SET_NUMBER (val, swfdec_bits_get_bdouble (bits)); return TRUE; } static gboolean -swfdec_amf_parse_string (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_string (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val) { guint len = swfdec_bits_get_bu16 (bits); char *s; - JSString *string; s = swfdec_bits_get_string_length (bits, len); if (s == NULL) return FALSE; - - string = JS_NewStringCopyZ (cx, s); - g_free (s); - if (!string) - return FALSE; - *val = STRING_TO_JSVAL (string); + SWFDEC_AS_VALUE_SET_STRING (val, swfdec_as_context_get_string (context, s)); return TRUE; } + static gboolean -swfdec_amf_parse_properties (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_properties (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsObject *object) { guint type; SwfdecAmfParseFunc func; - JSObject *object; - - g_assert (JSVAL_IS_OBJECT (*val)); - object = JSVAL_TO_OBJECT (*val); + /* need to root here due to GC */ + swfdec_as_object_root (object); while (swfdec_bits_left (bits)) { - jsval id, val; - if (!swfdec_amf_parse_string (cx, bits, &id)) + SwfdecAsValue id, val; + + if (!swfdec_amf_parse_string (context, bits, &id)) return FALSE; type = swfdec_bits_get_u8 (bits); if (type == SWFDEC_AMF_END_OBJECT) - return TRUE; + break; if (type >= SWFDEC_AMF_N_TYPES || (func = parse_funcs[type]) == NULL) { SWFDEC_ERROR ("no parse func for AMF type %u", type); - return FALSE; + goto error; } - if (!func (cx, bits, &val)) - return FALSE; - if (!JS_SetProperty (cx, object, JS_GetStringBytes (JSVAL_TO_STRING (id)), &val)) - return FALSE; + swfdec_as_object_set_variable (object, &id, &id); /* GC... */ + if (!func (context, bits, &val)) { + goto error; + } + swfdec_as_object_set_variable (object, &id, &val); /* GC... */ } /* no more bytes seems to end automatically */ + swfdec_as_object_unroot (object); return TRUE; + +error: + swfdec_as_object_unroot (object); + return FALSE; } static gboolean -swfdec_amf_parse_object (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_object (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val) { - JSObject *object; + SwfdecAsObject *object; - object = JS_NewObject (cx, NULL, NULL, NULL); + object = swfdec_as_object_new (context); if (object == NULL) return FALSE; - - *val = OBJECT_TO_JSVAL (object); - return swfdec_amf_parse_properties (cx, bits, val); + if (!swfdec_amf_parse_properties (context, bits, object)) + return FALSE; + SWFDEC_AS_VALUE_SET_OBJECT (val, object); + return TRUE; } static gboolean -swfdec_amf_parse_mixed_array (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_mixed_array (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val) { guint len; - JSObject *object; + SwfdecAsObject *array; len = swfdec_bits_get_bu32 (bits); - object = JS_NewArrayObject (cx, len, NULL); - if (object == NULL) + array = swfdec_as_array_new (context, len); + if (array == NULL) return FALSE; - - *val = OBJECT_TO_JSVAL (object); - return swfdec_amf_parse_properties (cx, bits, val); + if (!swfdec_amf_parse_properties (context, bits, array)) + return FALSE; + SWFDEC_AS_VALUE_SET_OBJECT (val, array); + return TRUE; } static gboolean -swfdec_amf_parse_array (JSContext *cx, SwfdecBits *bits, jsval *val) +swfdec_amf_parse_array (SwfdecAsContext *context, SwfdecBits *bits, SwfdecAsValue *val) { guint i, len; - JSObject *object; - jsval *vector; + SwfdecAsObject *array; guint type; SwfdecAmfParseFunc func; len = swfdec_bits_get_bu32 (bits); - vector = g_try_new (jsval, len); - if (vector == NULL) + array = swfdec_as_array_new (context, len); + if (array == NULL) return FALSE; + swfdec_as_object_root (array); for (i = 0; i < len; i++) { type = swfdec_bits_get_u8 (bits); + SwfdecAsValue val; if (type >= SWFDEC_AMF_N_TYPES || (func = parse_funcs[type]) == NULL) { SWFDEC_ERROR ("no parse func for AMF type %u", type); goto fail; } - if (!func (cx, bits, &vector[i])) + if (!func (context, bits, &val)) goto fail; + g_array_append_val (SWFDEC_AS_ARRAY (array)->values, val); } - object = JS_NewArrayObject (cx, len, vector); - if (object == NULL) - goto fail; - *val = OBJECT_TO_JSVAL (object); - g_free (vector); + swfdec_as_object_unroot (array); + SWFDEC_AS_VALUE_SET_OBJECT (val, array); return TRUE; fail: - g_free (vector); + swfdec_as_object_unroot (array); return FALSE; } @@ -183,13 +180,13 @@ const SwfdecAmfParseFunc parse_funcs[SWF }; gboolean -swfdec_amf_parse_one (JSContext *cx, SwfdecBits *bits, SwfdecAmfType expected_type, - jsval *rval) +swfdec_amf_parse_one (SwfdecAsContext *context, SwfdecBits *bits, + SwfdecAmfType expected_type, SwfdecAsValue *rval) { SwfdecAmfParseFunc func; guint type; - g_return_val_if_fail (cx != NULL, FALSE); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), 0); g_return_val_if_fail (bits != NULL, FALSE); g_return_val_if_fail (rval != NULL, FALSE); g_return_val_if_fail (expected_type < SWFDEC_AMF_N_TYPES, FALSE); @@ -205,23 +202,24 @@ swfdec_amf_parse_one (JSContext *cx, Swf SWFDEC_ERROR ("no parse func for AMF type %u", type); return FALSE; } - return func (cx, bits, rval); + return func (context, bits, rval); } +/* FIXME: parsed values aren't gc rooted... */ guint -swfdec_amf_parse (JSContext *cx, SwfdecBits *bits, guint n_items, ...) +swfdec_amf_parse (SwfdecAsContext *context, SwfdecBits *bits, guint n_items, ...) { va_list args; guint i; - g_return_val_if_fail (cx != NULL, 0); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), 0); g_return_val_if_fail (bits != NULL, 0); va_start (args, n_items); for (i = 0; i < n_items; i++) { SwfdecAmfType type = va_arg (args, SwfdecAmfType); - jsval *val = va_arg (args, jsval *); - if (!swfdec_amf_parse_one (cx, bits, type, val)) + SwfdecAsValue *val = va_arg (args, SwfdecAsValue *); + if (!swfdec_amf_parse_one (context, bits, type, val)) break; } va_end (args); diff --git a/libswfdec/swfdec_amf.h b/libswfdec/swfdec_amf.h index 564fbb5..0f9c67e 100644 --- a/libswfdec/swfdec_amf.h +++ b/libswfdec/swfdec_amf.h @@ -20,7 +20,7 @@ #ifndef __SWFDEC_AMF_H__ #define __SWFDEC_AMF_H__ -#include <libswfdec/js/jspubtd.h> +#include <libswfdec/swfdec_as_context.h> #include <libswfdec/swfdec_bits.h> typedef enum { @@ -46,13 +46,13 @@ typedef enum { SWFDEC_AMF_N_TYPES } SwfdecAmfType; -gboolean swfdec_amf_parse_one (JSContext * cx, - SwfdecBits * bits, - SwfdecAmfType expected_type, - jsval * rval); -guint swfdec_amf_parse (JSContext * cx, - SwfdecBits * bits, - guint n_items, +gboolean swfdec_amf_parse_one (SwfdecAsContext * context, + SwfdecBits * bits, + SwfdecAmfType expected_type, + SwfdecAsValue * rval); +guint swfdec_amf_parse (SwfdecAsContext * context, + SwfdecBits * bits, + guint n_items, ...); diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c new file mode 100644 index 0000000..b436e86 --- /dev/null +++ b/libswfdec/swfdec_as_array.c @@ -0,0 +1,104 @@ +/* SwfdecAs + * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "swfdec_as_array.h" +#include "swfdec_as_context.h" +#include "swfdec_as_stack.h" +#include "swfdec_debug.h" + +G_DEFINE_TYPE (SwfdecAsArray, swfdec_as_array, SWFDEC_TYPE_AS_OBJECT) + +static void +swfdec_as_array_dispose (GObject *object) +{ + SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); + + g_array_free (array->values, TRUE); + + G_OBJECT_CLASS (swfdec_as_array_parent_class)->dispose (object); +} + +static void +swfdec_as_array_mark (SwfdecAsObject *object) +{ + SwfdecAsArray *array = SWFDEC_AS_ARRAY (object); + guint i; + + for (i = 0; i < array->values->len; i++) { + swfdec_as_value_mark (&g_array_index (array->values, SwfdecAsValue, i)); + } + + SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->mark (object); +} + +static void +swfdec_as_array_class_init (SwfdecAsArrayClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); + + object_class->dispose = swfdec_as_array_dispose; + + asobject_class->mark = swfdec_as_array_mark; +} + +static void +swfdec_as_array_init (SwfdecAsArray *array) +{ + array->values = g_array_new (FALSE, TRUE, sizeof (SwfdecAsValue)); +} + +/** + * swfdec_as_array_new: + * @context: a #SwfdecAsContext + * @preallocated_items: number of items to preallocate + * + * Creates a new #SwfdecAsArray. @preallocated_items is a hint on how many + * space to reserve to avoid frequent reallocations later on. + * + * Returns: the new array or %NULL on OOM. + **/ +SwfdecAsObject * +swfdec_as_array_new (SwfdecAsContext *context, guint preallocated_items) +{ + guint size; + SwfdecAsObject *object; + + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + if (preallocated_items > 1024) { + SWFDEC_INFO ("%u items is a lot, better only preallocate 1024", preallocated_items); + preallocated_items = 1024; + } + + size = sizeof (SwfdecAsArray); + if (!swfdec_as_context_use_mem (context, size)) + return NULL; + object = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL); + swfdec_as_object_add (object, context, size); + if (preallocated_items) { + g_array_set_size (SWFDEC_AS_ARRAY (object)->values, preallocated_items); + g_array_set_size (SWFDEC_AS_ARRAY (object)->values, 0); + } + return object; +} + diff --git a/libswfdec/swfdec_as_array.h b/libswfdec/swfdec_as_array.h new file mode 100644 index 0000000..c4a2b82 --- /dev/null +++ b/libswfdec/swfdec_as_array.h @@ -0,0 +1,56 @@ +/* SwfdecAs + * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef _SWFDEC_AS_ARRAY_H_ +#define _SWFDEC_AS_ARRAY_H_ + +#include <libswfdec/swfdec_as_object.h> +#include <libswfdec/swfdec_as_types.h> +#include <libswfdec/swfdec_script.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecAsArrayClass SwfdecAsArrayClass; + +#define SWFDEC_TYPE_AS_ARRAY (swfdec_as_array_get_type()) +#define SWFDEC_IS_AS_ARRAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_ARRAY)) +#define SWFDEC_IS_AS_ARRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_ARRAY)) +#define SWFDEC_AS_ARRAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_ARRAY, SwfdecAsArray)) +#define SWFDEC_AS_ARRAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_ARRAY, SwfdecAsArrayClass)) +#define SWFDEC_AS_ARRAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_ARRAY, SwfdecAsArrayClass)) + +struct _SwfdecAsArray { + SwfdecAsObject object; + + GArray * values; /* the indexed values in the array */ +}; + +struct _SwfdecAsArrayClass { + SwfdecAsObjectClass object_class; +}; + +GType swfdec_as_array_get_type (void); + +SwfdecAsObject *swfdec_as_array_new (SwfdecAsContext * context, + guint preallocated_items); + + + +G_END_DECLS +#endif diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index 037e146..8fe289a 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -221,13 +221,23 @@ swfdec_as_context_mark_roots (gpointer k swfdec_as_object_mark (object); } +static void +swfdec_as_context_do_mark (SwfdecAsContext *context) +{ + g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL); +} + void swfdec_as_context_gc (SwfdecAsContext *context) { + SwfdecAsContextClass *klass; + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); SWFDEC_INFO ("invoking the garbage collector"); - g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL); + klass = SWFDEC_AS_CONTEXT_GET_CLASS (context); + g_assert (klass->mark); + klass->mark (context); swfdec_as_context_collect (context); } @@ -257,6 +267,8 @@ swfdec_as_context_class_init (SwfdecAsCo GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = swfdec_as_context_dispose; + + klass->mark = swfdec_as_context_do_mark; } static void @@ -451,3 +463,177 @@ swfdec_as_context_return (SwfdecAsContex swfdec_as_stack_push (context->frame->stack, &value); } } + +/*** EVAL ***/ + +char * +swfdec_as_slash_to_dot (const char *slash_str) +{ + const char *cur = slash_str; + GString *str = g_string_new (""); + + if (*cur == '/') { + g_string_append (str, "_root"); + } else { + goto start; + } + while (cur && *cur == '/') { + cur++; +start: + if (str->len > 0) + g_string_append_c (str, '.'); + if (cur[0] == '.' && cur[1] == '.') { + g_string_append (str, "_parent"); + cur += 2; + } else { + char *slash = strchr (cur, '/'); + if (slash) { + g_string_append_len (str, cur, slash - cur); + cur = slash; + } else { + g_string_append (str, cur); + cur = NULL; + } + } + /* cur should now point to the slash */ + } + if (cur) { + if (*cur != '\0') + goto fail; + } + SWFDEC_DEBUG ("parsed slash-notated string \"%s\" into dot notation \"%s\"", + slash_str, str->str); + return g_string_free (str, FALSE); + +fail: + SWFDEC_WARNING ("failed to parse slash-notated string \"%s\" into dot notation", slash_str); + g_string_free (str, TRUE); + return NULL; +} + +static void +swfdec_as_context_eval_get_property (SwfdecAsContext *cx, + SwfdecAsObject *obj, const char *name, SwfdecAsValue *ret) +{ + if (obj) { + swfdec_as_object_get (obj, name, ret); + } else { + g_assert_not_reached (); +#if 0 + if (cx->fp == NULL || cx->fp->scopeChain == NULL) + return JS_FALSE; + if (!js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop)) + return JS_FALSE; + if (!prop) + return JS_FALSE; + return OBJ_GET_PROPERTY (cx, obj, (jsid) prop->id, ret); +#endif + } +} + +static void +swfdec_as_context_eval_set_property (SwfdecAsContext *cx, + SwfdecAsObject *obj, const char *name, const SwfdecAsValue *ret) +{ + if (obj == NULL) { + g_assert_not_reached (); +#if 0 + JSObject *pobj; + JSProperty *prop; + if (cx->fp == NULL || cx->fp->varobj == NULL) + return JS_FALSE; + if (!js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop)) + return JS_FALSE; + if (pobj) + obj = pobj; + else + obj = cx->fp->varobj; +#endif + } + return swfdec_as_object_set (obj, name, ret); +} + +static void +swfdec_as_context_eval_internal (SwfdecAsContext *cx, SwfdecAsObject *obj, const char *str, + SwfdecAsValue *val, gboolean set) +{ + SwfdecAsValue cur; + char **varlist; + guint i; + + SWFDEC_LOG ("eval called with \"%s\" on %p", str, obj); + if (strchr (str, '/')) { + char *work = swfdec_as_slash_to_dot (str); + if (!work) { + SWFDEC_AS_VALUE_SET_UNDEFINED (val); + return; + } + varlist = g_strsplit (work, ".", -1); + g_free (work); + } else { + varlist = g_strsplit (str, ".", -1); + } + SWFDEC_AS_VALUE_SET_OBJECT (&cur, obj); /* FIXME: can be NULL here */ + for (i = 0; varlist[i] != NULL; i++) { + const char *dot = swfdec_as_context_get_string (cx, varlist[i]); + if (!SWFDEC_AS_VALUE_IS_OBJECT (&cur)) { + SWFDEC_AS_VALUE_SET_UNDEFINED (&cur); + break; + } + obj = SWFDEC_AS_VALUE_GET_OBJECT (&cur); + if (varlist[i+1] != NULL) { + swfdec_as_context_eval_get_property (cx, obj, dot, &cur); + } else { + if (set) { + swfdec_as_context_eval_set_property (cx, obj, dot, &cur); + } else { + swfdec_as_context_eval_get_property (cx, obj, dot, &cur); + } + goto finish; + } + } + if (obj == NULL && cx->frame) { + swfdec_as_object_get (SWFDEC_AS_OBJECT (cx->frame), SWFDEC_AS_STR_THIS, &cur); + } + +finish: + g_strfreev (varlist); + *val = cur; +} + +/** + * swfdec_as_context_eval: + * @context: a #SwfdecAsContext + * @obj: #SwfdecAsObject to use as source for evaluating or NULL for the + * current frame's scope + * @str: The string to evaluate + * @val: location for the return value + * + * This function works like the Actionscript eval function used on @obj. + * It handles both slash-style and dot-style notation. If an error occured + * during evaluation, the return value will be the undefined value. + **/ +void +swfdec_as_context_eval (SwfdecAsContext *cx, SwfdecAsObject *obj, const char *str, + SwfdecAsValue *val) +{ + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (cx)); + g_return_if_fail (obj == NULL || SWFDEC_IS_AS_OBJECT (obj)); + g_return_if_fail (str != NULL); + g_return_if_fail (val != NULL); + + swfdec_as_context_eval_internal (cx, obj, str, val, FALSE); +} + +void +swfdec_as_context_eval_set (SwfdecAsContext *cx, SwfdecAsObject *obj, const char *str, + const SwfdecAsValue *val) +{ + g_return_if_fail (SWFDEC_IS_AS_CONTEXT (cx)); + g_return_if_fail (obj == NULL || SWFDEC_IS_AS_OBJECT (obj)); + g_return_if_fail (str != NULL); + g_return_if_fail (val != NULL); + + swfdec_as_context_eval_internal (cx, obj, str, (SwfdecAsValue *) val, TRUE); +} + diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h index b3061f7..c1d12dc 100644 --- a/libswfdec/swfdec_as_context.h +++ b/libswfdec/swfdec_as_context.h @@ -60,6 +60,9 @@ struct _SwfdecAsContext { struct _SwfdecAsContextClass { GObjectClass object_class; + + /* mark all objects that should not be collected */ + void (* mark) (SwfdecAsContext * context); }; GType swfdec_as_context_get_type (void); @@ -82,8 +85,18 @@ void swfdec_as_value_mark (SwfdecAsVal void swfdec_as_string_mark (const char * string); void swfdec_as_context_gc (SwfdecAsContext * context); +void swfdec_as_context_run (SwfdecAsContext * context); void swfdec_as_context_return (SwfdecAsContext * context, SwfdecAsValue * retval); +void swfdec_as_context_eval (SwfdecAsContext * cx, + SwfdecAsObject * obj, + const char * str, + SwfdecAsValue * val); +void swfdec_as_context_eval_set (SwfdecAsContext * cx, + SwfdecAsObject * obj, + const char * str, + const SwfdecAsValue * val); + G_END_DECLS #endif diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index 34db07b..6f5ac61 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -23,6 +23,7 @@ #include "swfdec_as_object.h" #include "swfdec_as_context.h" +#include "swfdec_as_function.h" #include "swfdec_debug.h" @@ -39,7 +40,7 @@ swfdec_as_object_dispose (GObject *gobje { SwfdecAsObject *object = SWFDEC_AS_OBJECT (gobject); - g_assert (object->properties == NULL); + g_assert (!SWFDEC_AS_OBJECT_HAS_CONTEXT (object)); G_OBJECT_CLASS (swfdec_as_object_parent_class)->dispose (gobject); } @@ -80,7 +81,7 @@ swfdec_as_object_init (SwfdecAsObject *o * * Allocates a new Object. This does the same as the Actionscript code * "new Object()". - * <warn>This function may run the garbage collector.</warn> + * <warning>This function may run the garbage collector.</warning> * * Returns: the new object or NULL on out of memory. **/ @@ -115,7 +116,7 @@ swfdec_as_object_add (SwfdecAsObject *ob { g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context)); - g_return_if_fail (object->properties == NULL); + g_return_if_fail (!SWFDEC_AS_OBJECT_HAS_CONTEXT (object)); object->context = context; object->size = size; @@ -136,7 +137,7 @@ void swfdec_as_object_collect (SwfdecAsObject *object) { g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); - g_return_if_fail (object->properties != NULL); + g_return_if_fail (SWFDEC_AS_OBJECT_HAS_CONTEXT (object)); g_hash_table_foreach (object->properties, swfdec_as_object_free_property, object); g_hash_table_destroy (object->properties); @@ -248,3 +249,43 @@ swfdec_as_object_delete_variable (Swfdec } } +/** + * swfdec_as_object_run: + * @object: a #SwfdecAsObject + * @script: script to execute + * + * Executes the given @script with @object as this pointer. + **/ +void +swfdec_as_object_run (SwfdecAsObject *object, SwfdecScript *script) +{ + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); + g_return_if_fail (SWFDEC_AS_OBJECT_HAS_CONTEXT (object)); + g_return_if_fail (script != NULL); + + g_assert_not_reached (); + swfdec_as_context_run (object->context); +} + +void +swfdec_as_object_call (SwfdecAsObject *object, const char *name, guint argc, SwfdecAsValue *argv) +{ + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (argc == 0 || argv != NULL); +} + +gboolean +swfdec_as_object_has_function (SwfdecAsObject *object, const char *name) +{ + SwfdecAsValue val; + + g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + swfdec_as_object_get (object, name, &val); + if (!SWFDEC_AS_VALUE_IS_OBJECT (&val)) + return FALSE; + return SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (&val)); +} + diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h index 0accee4..6462784 100644 --- a/libswfdec/swfdec_as_object.h +++ b/libswfdec/swfdec_as_object.h @@ -22,6 +22,7 @@ #include <glib-object.h> #include <libswfdec/swfdec_as_types.h> +#include <libswfdec/swfdec_types.h> G_BEGIN_DECLS @@ -40,6 +41,8 @@ typedef struct _SwfdecAsObjectClass Swfd #define SWFDEC_AS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObjectClass)) #define SWFDEC_AS_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObjectClass)) +#define SWFDEC_AS_OBJECT_HAS_CONTEXT(obj) (SWFDEC_AS_OBJECT (obj)->properties != NULL) + struct _SwfdecAsObject { GObject object; @@ -89,6 +92,14 @@ void swfdec_as_object_delete_variable(S swfdec_as_object_get_variable ((object), &__variable, (value)); \ }G_STMT_END +void swfdec_as_object_run (SwfdecAsObject * object, + SwfdecScript * script); +gboolean swfdec_as_object_has_function (SwfdecAsObject * object, + const char * name); +void swfdec_as_object_call (SwfdecAsObject * object, + const char * name, + guint argc, + SwfdecAsValue * argv); G_END_DECLS #endif diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c index 2b84330..12f0d44 100644 --- a/libswfdec/swfdec_as_types.c +++ b/libswfdec/swfdec_as_types.c @@ -31,6 +31,37 @@ const char *swfdec_as_strings[] = { SWFDEC_AS_CONSTANT_STRING (""), SWFDEC_AS_CONSTANT_STRING ("__proto__"), SWFDEC_AS_CONSTANT_STRING ("this"), + SWFDEC_AS_CONSTANT_STRING ("code"), + SWFDEC_AS_CONSTANT_STRING ("level"), + SWFDEC_AS_CONSTANT_STRING ("description"), + SWFDEC_AS_CONSTANT_STRING ("status"), + SWFDEC_AS_CONSTANT_STRING ("success"), + SWFDEC_AS_CONSTANT_STRING ("NetConnection.Connect.Success"), + SWFDEC_AS_CONSTANT_STRING ("onLoad"), + SWFDEC_AS_CONSTANT_STRING ("onEnterFrame"), + SWFDEC_AS_CONSTANT_STRING ("onUnload"), + SWFDEC_AS_CONSTANT_STRING ("onMouseMove"), + SWFDEC_AS_CONSTANT_STRING ("onMouseDown"), + SWFDEC_AS_CONSTANT_STRING ("onMouseUp"), + SWFDEC_AS_CONSTANT_STRING ("onKeyUp"), + SWFDEC_AS_CONSTANT_STRING ("onKeyDown"), + SWFDEC_AS_CONSTANT_STRING ("onData"), + SWFDEC_AS_CONSTANT_STRING ("onPress"), + SWFDEC_AS_CONSTANT_STRING ("onRelease"), + SWFDEC_AS_CONSTANT_STRING ("onReleaseOutside"), + SWFDEC_AS_CONSTANT_STRING ("onRollOver"), + SWFDEC_AS_CONSTANT_STRING ("onRollOut"), + SWFDEC_AS_CONSTANT_STRING ("onDragOver"), + SWFDEC_AS_CONSTANT_STRING ("onDragOut"), + SWFDEC_AS_CONSTANT_STRING ("onConstruct"), + SWFDEC_AS_CONSTANT_STRING ("onStatus"), + SWFDEC_AS_CONSTANT_STRING ("error"), + SWFDEC_AS_CONSTANT_STRING ("NetStream.Buffer.Empty"), + SWFDEC_AS_CONSTANT_STRING ("NetStream.Buffer.Full"), + SWFDEC_AS_CONSTANT_STRING ("NetStream.Buffer.Flush"), + SWFDEC_AS_CONSTANT_STRING ("NetStream.Play.Start"), + SWFDEC_AS_CONSTANT_STRING ("NetStream.Play.Stop"), + SWFDEC_AS_CONSTANT_STRING ("NetStream.Play.StreamNotFound"), /* add more here */ NULL }; diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h index 9a293a4..92a7355 100644 --- a/libswfdec/swfdec_as_types.h +++ b/libswfdec/swfdec_as_types.h @@ -34,12 +34,14 @@ G_BEGIN_DECLS #define SWFDEC_TYPE_AS_ASOBJECT (6) typedef guint8 SwfdecAsType; +typedef struct _SwfdecAsArray SwfdecAsArray; typedef struct _SwfdecAsContext SwfdecAsContext; typedef struct _SwfdecAsFrame SwfdecAsFrame; typedef struct _SwfdecAsObject SwfdecAsObject; typedef struct _SwfdecAsStack SwfdecAsStack; typedef struct _SwfdecAsValue SwfdecAsValue; +/* IMPORTANT: a SwfdecAsValue memset to 0 is a valid undefined value */ struct _SwfdecAsValue { SwfdecAsType type; union { @@ -92,6 +94,37 @@ extern const char *swfdec_as_strings[]; #define SWFDEC_AS_STR_EMPTY (swfdec_as_strings[0] + 1) #define SWFDEC_AS_STR_PROTO (swfdec_as_strings[1] + 1) #define SWFDEC_AS_STR_THIS (swfdec_as_strings[2] + 1) +#define SWFDEC_AS_STR_CODE (swfdec_as_strings[3] + 1) +#define SWFDEC_AS_STR_LEVEL (swfdec_as_strings[4] + 1) +#define SWFDEC_AS_STR_DESCRIPTION (swfdec_as_strings[5] + 1) +#define SWFDEC_AS_STR_STATUS (swfdec_as_strings[6] + 1) +#define SWFDEC_AS_STR_SUCCESS (swfdec_as_strings[7] + 1) +#define SWFDEC_AS_STR_NET_CONNECTION_CONNECT_SUCCESS (swfdec_as_strings[8] + 1) +#define SWFDEC_AS_STR_ON_LOAD (swfdec_as_strings[9] + 1) +#define SWFDEC_AS_STR_ON_ENTER_FRAME (swfdec_as_strings[10] + 1) +#define SWFDEC_AS_STR_ON_UNLOAD (swfdec_as_strings[11] + 1) +#define SWFDEC_AS_STR_ON_MOUSE_MOVE (swfdec_as_strings[12] + 1) +#define SWFDEC_AS_STR_ON_MOUSE_DOWN (swfdec_as_strings[13] + 1) +#define SWFDEC_AS_STR_ON_MOUSE_UP (swfdec_as_strings[14] + 1) +#define SWFDEC_AS_STR_ON_KEY_UP (swfdec_as_strings[15] + 1) +#define SWFDEC_AS_STR_ON_KEY_DOWN (swfdec_as_strings[16] + 1) +#define SWFDEC_AS_STR_ON_DATA (swfdec_as_strings[17] + 1) +#define SWFDEC_AS_STR_ON_PRESS (swfdec_as_strings[18] + 1) +#define SWFDEC_AS_STR_ON_RELEASE (swfdec_as_strings[19] + 1) +#define SWFDEC_AS_STR_ON_RELEASE_OUTSIDE (swfdec_as_strings[20] + 1) +#define SWFDEC_AS_STR_ON_ROLL_OVER (swfdec_as_strings[21] + 1) +#define SWFDEC_AS_STR_ON_ROLL_OUT (swfdec_as_strings[22] + 1) +#define SWFDEC_AS_STR_ON_DRAG_OVER (swfdec_as_strings[23] + 1) +#define SWFDEC_AS_STR_ON_DRAG_OUT (swfdec_as_strings[24] + 1) +#define SWFDEC_AS_STR_ON_CONSTRUCT (swfdec_as_strings[25] + 1) +#define SWFDEC_AS_STR_ON_STATUS (swfdec_as_strings[26] + 1) +#define SWFDEC_AS_STR_ERROR (swfdec_as_strings[27] + 1) +#define SWFDEC_AS_STR_NETSTREAM_BUFFER_EMPTY (swfdec_as_strings[28] + 1) +#define SWFDEC_AS_STR_NETSTREAM_BUFFER_FULL (swfdec_as_strings[29] + 1) +#define SWFDEC_AS_STR_NETSTREAM_BUFFER_FLUSH (swfdec_as_strings[30] + 1) +#define SWFDEC_AS_STR_NETSTREAM_PLAY_START (swfdec_as_strings[31] + 1) +#define SWFDEC_AS_STR_NETSTREAM_PLAY_STOP (swfdec_as_strings[32] + 1) +#define SWFDEC_AS_STR_NETSTREAM_PLAY_STREAMNOTFOUND (swfdec_as_strings[33] + 1) /* all existing actions */ typedef enum { diff --git a/libswfdec/swfdec_button.c b/libswfdec/swfdec_button.c index 13eed56..d537952 100644 --- a/libswfdec/swfdec_button.c +++ b/libswfdec/swfdec_button.c @@ -23,7 +23,6 @@ #include "config.h" #endif #include <string.h> -#include <js/jsapi.h> #include "swfdec_button.h" #include "swfdec_button_movie.h" #include "swfdec_sound.h" @@ -60,11 +59,12 @@ swfdec_button_dispose (GObject *object) } static SwfdecMovie * -swfdec_button_create_movie (SwfdecGraphic *graphic) +swfdec_button_create_movie (SwfdecGraphic *graphic, gsize *size) { SwfdecButtonMovie *movie = g_object_new (SWFDEC_TYPE_BUTTON_MOVIE, NULL); movie->button = SWFDEC_BUTTON (graphic); + *size = sizeof (SwfdecButtonMovie); return SWFDEC_MOVIE (movie); } diff --git a/libswfdec/swfdec_button_movie.c b/libswfdec/swfdec_button_movie.c index 3c7b0b4..15267b6 100644 --- a/libswfdec/swfdec_button_movie.c +++ b/libswfdec/swfdec_button_movie.c @@ -107,9 +107,9 @@ swfdec_button_movie_execute (SwfdecButto } if (movie->button->events) swfdec_event_list_execute (movie->button->events, - SWFDEC_SCRIPTABLE (SWFDEC_MOVIE (movie)->parent), condition, 0); + SWFDEC_AS_OBJECT (SWFDEC_MOVIE (movie)->parent), condition, 0); name = swfdec_button_condition_get_name (condition); - swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (movie), name, 0, NULL); + swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), name, 0, NULL); } #define CONTENT_IN_FRAME(content, frame) \ diff --git a/libswfdec/swfdec_connection.c b/libswfdec/swfdec_connection.c index 464affb..d55c916 100644 --- a/libswfdec/swfdec_connection.c +++ b/libswfdec/swfdec_connection.c @@ -23,13 +23,13 @@ #include <string.h> #include "swfdec_connection.h" +#include "swfdec_as_context.h" +#include "swfdec_as_object.h" #include "swfdec_debug.h" -#include "js/jsapi.h" -#include "js/jsinterp.h" /*** SwfdecConnection ***/ -G_DEFINE_TYPE (SwfdecConnection, swfdec_connection, SWFDEC_TYPE_SCRIPTABLE) +G_DEFINE_TYPE (SwfdecConnection, swfdec_connection, SWFDEC_TYPE_AS_OBJECT) static void swfdec_connection_dispose (GObject *object) @@ -42,16 +42,12 @@ swfdec_connection_dispose (GObject *obje G_OBJECT_CLASS (swfdec_connection_parent_class)->dispose (object); } -extern const JSClass connection_class; static void swfdec_connection_class_init (SwfdecConnectionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfdecScriptableClass *scriptable_class = SWFDEC_SCRIPTABLE_CLASS (klass); object_class->dispose = swfdec_connection_dispose; - - scriptable_class->jsclass = &connection_class; } static void @@ -63,46 +59,37 @@ static void swfdec_connection_onstatus (SwfdecConnection *conn, const char *code, const char *level, const char *description) { - JSContext *cx = SWFDEC_SCRIPTABLE (conn)->jscx; - JSObject *obj = SWFDEC_SCRIPTABLE (conn)->jsobj; - JSObject *info; - jsval val, fun; - JSString *string; + SwfdecAsValue value; + SwfdecAsObject *info; - if (!JS_GetProperty (cx, obj, "onStatus", &fun)) - return; - if (fun == JSVAL_VOID) - return; - info = JS_NewObject (cx, NULL, NULL, NULL); - if (info == NULL || - (string = JS_NewStringCopyZ (cx, code)) == NULL || - (val = STRING_TO_JSVAL (string)) == 0 || - !JS_SetProperty (cx, info, "code", &val) || - (string = JS_NewStringCopyZ (cx, level)) == NULL || - (val = STRING_TO_JSVAL (string)) == 0 || - !JS_SetProperty (cx, info, "level", &val)) + info = swfdec_as_object_new (SWFDEC_AS_OBJECT (conn)->context); + if (info == NULL) return; + swfdec_as_object_root (info); + SWFDEC_AS_VALUE_SET_STRING (&value, code); + swfdec_as_object_set (info, SWFDEC_AS_STR_CODE, &value); + SWFDEC_AS_VALUE_SET_STRING (&value, level); + swfdec_as_object_set (info, SWFDEC_AS_STR_LEVEL, &value); if (description) { - if ((string = JS_NewStringCopyZ (cx, level)) == NULL || - (val = STRING_TO_JSVAL (string)) == 0 || - !JS_SetProperty (cx, info, "description", &val)) - return; + SWFDEC_AS_VALUE_SET_STRING (&value, description); + swfdec_as_object_set (info, SWFDEC_AS_STR_DESCRIPTION, &value); } - val = OBJECT_TO_JSVAL (info); - js_InternalCall (cx, obj, fun, 1, &val, &fun); + SWFDEC_AS_VALUE_SET_OBJECT (&value, info); + swfdec_as_object_unroot (info); + swfdec_as_object_call (SWFDEC_AS_OBJECT (conn), SWFDEC_AS_STR_STATUS, 1, &value); } SwfdecConnection * -swfdec_connection_new (JSContext *cx) +swfdec_connection_new (SwfdecAsContext *context) { SwfdecConnection *conn; - SwfdecScriptable *script; - g_return_val_if_fail (cx != NULL, NULL); + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + if (!swfdec_as_context_use_mem (context, sizeof (SwfdecConnection))) + return NULL; conn = g_object_new (SWFDEC_TYPE_CONNECTION, NULL); - script = SWFDEC_SCRIPTABLE (conn); - script->jscx = cx; + swfdec_as_object_add (SWFDEC_AS_OBJECT (conn), context, sizeof (SwfdecConnection)); return conn; } @@ -117,7 +104,7 @@ swfdec_connection_connect (SwfdecConnect if (url) { SWFDEC_ERROR ("FIXME: using NetConnection with non-null URLs is not implemented"); } - swfdec_connection_onstatus (conn, "NetConnection.Connect.Success", - "status", NULL); + swfdec_connection_onstatus (conn, SWFDEC_AS_STR_NET_CONNECTION_CONNECT_SUCCESS, + SWFDEC_AS_STR_SUCCESS, NULL); } diff --git a/libswfdec/swfdec_connection.h b/libswfdec/swfdec_connection.h index 7219a89..d093c30 100644 --- a/libswfdec/swfdec_connection.h +++ b/libswfdec/swfdec_connection.h @@ -20,7 +20,7 @@ #ifndef _SWFDEC_CONNECTION_H_ #define _SWFDEC_CONNECTION_H_ -#include <libswfdec/swfdec_scriptable.h> +#include <libswfdec/swfdec_as_object.h> G_BEGIN_DECLS @@ -36,18 +36,18 @@ typedef struct _SwfdecConnectionClass Sw #define SWFDEC_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_CONNECTION, SwfdecConnectionClass)) struct _SwfdecConnection { - SwfdecScriptable scriptable; + SwfdecAsObject object; char * url; /* url for this connection or NULL for none */ }; struct _SwfdecConnectionClass { - SwfdecScriptableClass scriptable_class; + SwfdecAsObjectClass object_class; }; GType swfdec_connection_get_type (void); -SwfdecConnection * swfdec_connection_new (JSContext * cx); +SwfdecConnection * swfdec_connection_new (SwfdecAsContext * context); void swfdec_connection_connect (SwfdecConnection * conn, const char * url); diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c index 5e3cebc..52fb38c 100644 --- a/libswfdec/swfdec_debugger.c +++ b/libswfdec/swfdec_debugger.c @@ -25,11 +25,8 @@ #include "swfdec_debugger.h" #include "swfdec_debug.h" #include "swfdec_decoder.h" -#include "swfdec_js.h" #include "swfdec_movie.h" #include "swfdec_player_internal.h" -#include "js/jsdbgapi.h" -#include "js/jsinterp.h" /* for frame->swf */ /*** SwfdecDebuggerScript ***/ @@ -112,7 +109,7 @@ swfdec_debugger_print_push (ScriptParser break; default: SWFDEC_ERROR ("Push: type %u not implemented", type); - return JS_FALSE; + return NULL; } } return g_string_free (string, FALSE); @@ -321,6 +318,7 @@ typedef struct { guint line; } Breakpoint; +#if 0 static void swfdec_debugger_do_breakpoint (SwfdecDebugger *debugger, guint id) { @@ -345,22 +343,7 @@ swfdec_debugger_do_breakpoint (SwfdecDeb g_object_freeze_notify (G_OBJECT (debugger)); } - -static JSTrapStatus -swfdec_debugger_interrupt_cb (JSContext *cx, JSScript *script, - jsbytecode *pc, jsval *rval, void *debugger) -{ - SwfdecDebuggerScript *dscript; - guint line; - if (!swfdec_debugger_get_current (debugger, &dscript, &line)) - return JSTRAP_CONTINUE; - if (dscript->commands[line].breakpoint) { - swfdec_debugger_do_breakpoint (debugger, dscript->commands[line].breakpoint); - } else if (SWFDEC_DEBUGGER (debugger)->stepping) { - swfdec_debugger_do_breakpoint (debugger, 0); - } - return JSTRAP_CONTINUE; -} +#endif static void swfdec_debugger_update_interrupting (SwfdecDebugger *debugger) @@ -377,10 +360,9 @@ swfdec_debugger_update_interrupting (Swf } } if (should_interrupt) { - JS_SetInterrupt (JS_GetRuntime (SWFDEC_PLAYER (debugger)->jscx), - swfdec_debugger_interrupt_cb, debugger); + g_assert_not_reached (); } else { - JS_ClearInterrupt (JS_GetRuntime (SWFDEC_PLAYER (debugger)->jscx), NULL, NULL); + g_assert_not_reached (); } } @@ -444,8 +426,8 @@ swfdec_debugger_unset_breakpoint (Swfdec } static gboolean -swfdec_debugger_get_from_js (SwfdecDebugger *debugger, SwfdecScript *script, - jsbytecode *pc, SwfdecDebuggerScript **script_out, guint *line_out) +swfdec_debugger_get_from_as (SwfdecDebugger *debugger, SwfdecScript *script, + guint8 *pc, SwfdecDebuggerScript **script_out, guint *line_out) { guint line; SwfdecDebuggerScript *dscript = swfdec_debugger_get_script (debugger, script); @@ -460,7 +442,7 @@ swfdec_debugger_get_from_js (SwfdecDebug *line_out = line; return TRUE; } - if (pc < (jsbytecode *) dscript->commands[line].code) + if (pc < (guint8 *) dscript->commands[line].code) return FALSE; } return FALSE; @@ -470,18 +452,8 @@ gboolean swfdec_debugger_get_current (SwfdecDebugger *debugger, SwfdecDebuggerScript **dscript, guint *line) { - JSStackFrame *frame = NULL; - JSContext *cx; - jsbytecode *pc; - - cx = SWFDEC_PLAYER (debugger)->jscx; - JS_FrameIterator (cx, &frame); - if (frame == NULL) - return FALSE; - if (frame->swf == NULL) - return FALSE; - pc = JS_GetFramePC (cx, frame); - return swfdec_debugger_get_from_js (debugger, frame->swf, pc, dscript, line); + /* totally bogus code just to avoid gcc warning */ + return swfdec_debugger_get_from_as (debugger, NULL, NULL, dscript, line); } gboolean @@ -542,7 +514,6 @@ swfdec_debugger_run (SwfdecDebugger *deb { SwfdecPlayer *player; GList *walk; - jsval rval; const char *ret; g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), NULL); @@ -552,11 +523,7 @@ swfdec_debugger_run (SwfdecDebugger *deb g_object_freeze_notify (G_OBJECT (debugger)); - if (swfdec_js_run (player, command, &rval)) { - ret = swfdec_js_to_string (player->jscx, rval); - } else { - ret = NULL; - } + SWFDEC_ERROR ("ooops"); for (walk = player->roots; walk; walk = walk->next) { diff --git a/libswfdec/swfdec_edittext.c b/libswfdec/swfdec_edittext.c index 151feb2..11245d7 100644 --- a/libswfdec/swfdec_edittext.c +++ b/libswfdec/swfdec_edittext.c @@ -1,15 +1,32 @@ +/* Swfdec + * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <pango/pangocairo.h> #include <string.h> -#include <js/jsapi.h> #include "swfdec_edittext.h" #include "swfdec_debug.h" #include "swfdec_edittext_movie.h" #include "swfdec_font.h" -#include "swfdec_js.h" #include "swfdec_player_internal.h" #include "swfdec_swf_decoder.h" @@ -22,7 +39,7 @@ swfdec_edit_text_mouse_in (SwfdecGraphic } static SwfdecMovie * -swfdec_edit_text_create_movie (SwfdecGraphic *graphic) +swfdec_edit_text_create_movie (SwfdecGraphic *graphic, gsize *size) { SwfdecEditText *text = SWFDEC_EDIT_TEXT (graphic); SwfdecEditTextMovie *ret = g_object_new (SWFDEC_TYPE_EDIT_TEXT_MOVIE, NULL); @@ -30,6 +47,7 @@ swfdec_edit_text_create_movie (SwfdecGra ret->text = text; if (text->text) swfdec_edit_text_movie_set_text (ret, text->text); + *size = sizeof (SwfdecEditTextMovie); return SWFDEC_MOVIE (ret); } @@ -40,10 +58,9 @@ swfdec_edit_text_dispose (GObject *objec SwfdecEditText *text = SWFDEC_EDIT_TEXT (object); g_free (text->text); + text->text = NULL; g_free (text->variable); text->variable = NULL; - g_free (text->variable_prefix); - text->variable_prefix = NULL; G_OBJECT_CLASS (swfdec_edit_text_parent_class)->dispose (object); } @@ -65,34 +82,6 @@ swfdec_edit_text_init (SwfdecEditText * text->max_length = G_MAXUINT; } -static void -swfdec_edit_text_parse_variable (SwfdecEditText *text) -{ - char *s; - - if (text->variable && text->variable[0] == '\0') { - g_free (text->variable); - text->variable = NULL; - return; - } - /* FIXME: check the variable for valid identifiers */ - if (strchr (text->variable, '/')) { - char *ret = swfdec_js_slash_to_dot (text->variable); - g_free (text->variable); - text->variable = ret; - } - if (!text->variable) - return; - s = strrchr (text->variable, '.'); - if (s) { - guint len = s - text->variable; - text->variable_prefix = g_strndup (text->variable, len); - text->variable_name = s + 1; - } else { - text->variable_name = text->variable; - } -} - int tag_func_define_edit_text (SwfdecSwfDecoder * s) { @@ -178,7 +167,6 @@ tag_func_define_edit_text (SwfdecSwfDeco text->spacing = swfdec_bits_get_s16 (b); } text->variable = swfdec_bits_get_string (b); - swfdec_edit_text_parse_variable (text); if (has_text) text->text = swfdec_bits_get_string (b); diff --git a/libswfdec/swfdec_edittext.h b/libswfdec/swfdec_edittext.h index d6051ec..0bf5c27 100644 --- a/libswfdec/swfdec_edittext.h +++ b/libswfdec/swfdec_edittext.h @@ -1,5 +1,5 @@ /* Swfdec - * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> + * Copyright (C) 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -67,8 +67,6 @@ struct _SwfdecEditText /* variable info */ char * variable; /* full name of the variable in dot notation */ - char * variable_prefix;/* prefix of the variable (or NULL) */ - char * variable_name; /* name of the variable without dots */ gboolean readonly; }; diff --git a/libswfdec/swfdec_edittext_movie.c b/libswfdec/swfdec_edittext_movie.c index 421f6bc..1cef508 100644 --- a/libswfdec/swfdec_edittext_movie.c +++ b/libswfdec/swfdec_edittext_movie.c @@ -22,8 +22,8 @@ #endif #include "swfdec_edittext_movie.h" +#include "swfdec_as_context.h" #include "swfdec_debug.h" -#include "swfdec_js.h" #include "swfdec_player_internal.h" #include "swfdec_root_movie.h" @@ -68,26 +68,21 @@ static void swfdec_edit_text_movie_iterate (SwfdecMovie *movie) { SwfdecEditTextMovie *text = SWFDEC_EDIT_TEXT_MOVIE (movie); - SwfdecScriptable *parent; - JSObject *jsobj; - jsval val; + SwfdecAsObject *parent; const char *s; + SwfdecAsValue val = { 0, }; if (text->text->variable == NULL) return; - parent = SWFDEC_SCRIPTABLE (movie->parent); - jsobj = swfdec_scriptable_get_object (parent); - if (jsobj == NULL) - return; - val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable); - if (JSVAL_IS_VOID (val)) + parent = SWFDEC_AS_OBJECT (movie->parent); + swfdec_as_context_eval (parent->context, parent, text->text->variable, &val); + if (SWFDEC_AS_VALUE_IS_UNDEFINED (&val)) return; - s = swfdec_js_to_string (parent->jscx, val); - if (!s && !text->str) - return; - if (s && text->str && g_str_equal (s, text->str)) + s = swfdec_as_value_to_string (parent->context, &val); + g_assert (s); + if (text->str && g_str_equal (s, text->str)) return; swfdec_edit_text_movie_set_text (text, s); @@ -97,44 +92,30 @@ static void swfdec_edit_text_movie_init_movie (SwfdecMovie *movie) { SwfdecEditTextMovie *text = SWFDEC_EDIT_TEXT_MOVIE (movie); - SwfdecScriptable *parent; - JSObject *jsobj; - JSString *string; - jsval val; + SwfdecAsObject *parent; + SwfdecAsValue val = { 0, }; + const char *s; if (text->text->variable == NULL) return; - parent = SWFDEC_SCRIPTABLE (movie->parent); - jsobj = swfdec_scriptable_get_object (parent); - if (jsobj == NULL) - return; - if (text->text->variable_prefix) { - val = swfdec_js_eval (parent->jscx, jsobj, text->text->variable_prefix); - if (!JSVAL_IS_OBJECT (val)) - return; - jsobj = JSVAL_TO_OBJECT (val); - } - if (!JS_GetProperty (parent->jscx, jsobj, text->text->variable_name, &val)) - return; - if (!JSVAL_IS_VOID (val)) { - const char *s = swfdec_js_to_string (parent->jscx, val); - if (!s && !text->str) - return; - if (s && text->str && g_str_equal (s, text->str)) + parent = SWFDEC_AS_OBJECT (movie->parent); + swfdec_as_context_eval (parent->context, parent, text->text->variable, &val); + if (!SWFDEC_AS_VALUE_IS_UNDEFINED (&val)) { + s = swfdec_as_value_to_string (parent->context, &val); + g_assert (s); + if (text->str && g_str_equal (s, text->str)) return; swfdec_edit_text_movie_set_text (text, s); return; } - SWFDEC_LOG ("setting variable %s (%s) to \"%s\"", text->text->variable_name, - text->text->variable, text->str ? text->str : ""); - string = JS_NewStringCopyZ (parent->jscx, text->str ? text->str : ""); - if (string == NULL) - return; - val = STRING_TO_JSVAL (string); - JS_SetProperty (parent->jscx, jsobj, text->text->variable_name, &val); + SWFDEC_LOG ("setting variable %s to \"%s\"", text->text->variable, + text->str ? text->str : ""); + s = text->str ? swfdec_as_context_get_string (parent->context, text->str) : SWFDEC_AS_STR_EMPTY; + SWFDEC_AS_VALUE_SET_STRING (&val, s); + swfdec_as_context_eval_set (parent->context, parent, text->text->variable, &val); } static void diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c index af41b9e..ab48140 100644 --- a/libswfdec/swfdec_event.c +++ b/libswfdec/swfdec_event.c @@ -20,10 +20,9 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <js/jsapi.h> #include "swfdec_event.h" +#include "swfdec_as_object.h" #include "swfdec_debug.h" -#include "swfdec_js.h" #include "swfdec_player_internal.h" #include "swfdec_script.h" @@ -41,70 +40,57 @@ struct _SwfdecEventList { GArray * events; }; -static const char *event_names[] = { - "onLoad", - "onEnterFrame", - "onUnload", - "onMouseMove", - "onMouseDown", - "onMouseUp", - "onKeyUp", - "onKeyDown", - "onData", - NULL, - "onPress", - "onRelease", - "onReleaseOutside", - "onRollOver", - "onRollOut", - "onDragOver", - "onDragOut", - NULL, - "onConstruct" -}; - +/** + * swfdec_event_type_get_name: + * @type: a #SwfdecEventType + * + * Gets the name for the event as a refcounted string or %NULL if the + * given clip event has no associated event. + * + * Returns: The name of the event or %NULL if none. + **/ const char * swfdec_event_type_get_name (SwfdecEventType type) { switch (type) { case SWFDEC_EVENT_LOAD: - return event_names[0]; + return SWFDEC_AS_STR_ON_LOAD; case SWFDEC_EVENT_ENTER: - return event_names[1]; + return SWFDEC_AS_STR_ON_ENTER_FRAME; case SWFDEC_EVENT_UNLOAD: - return event_names[2]; + return SWFDEC_AS_STR_ON_UNLOAD; case SWFDEC_EVENT_MOUSE_MOVE: - return event_names[3]; + return SWFDEC_AS_STR_ON_MOUSE_MOVE; case SWFDEC_EVENT_MOUSE_DOWN: - return event_names[4]; + return SWFDEC_AS_STR_ON_MOUSE_DOWN; case SWFDEC_EVENT_MOUSE_UP: - return event_names[5]; + return SWFDEC_AS_STR_ON_MOUSE_UP; case SWFDEC_EVENT_KEY_UP: - return event_names[6]; + return SWFDEC_AS_STR_ON_KEY_UP; case SWFDEC_EVENT_KEY_DOWN: - return event_names[7]; + return SWFDEC_AS_STR_ON_KEY_DOWN; case SWFDEC_EVENT_DATA: - return event_names[8]; + return SWFDEC_AS_STR_ON_DATA; case SWFDEC_EVENT_INITIALIZE: - return event_names[9]; + return NULL; case SWFDEC_EVENT_PRESS: - return event_names[10]; + return SWFDEC_AS_STR_ON_PRESS; case SWFDEC_EVENT_RELEASE: - return event_names[11]; + return SWFDEC_AS_STR_ON_RELEASE; case SWFDEC_EVENT_RELEASE_OUTSIDE: - return event_names[12]; + return SWFDEC_AS_STR_ON_RELEASE_OUTSIDE; case SWFDEC_EVENT_ROLL_OVER: - return event_names[13]; + return SWFDEC_AS_STR_ON_ROLL_OVER; case SWFDEC_EVENT_ROLL_OUT: - return event_names[14]; + return SWFDEC_AS_STR_ON_ROLL_OUT; case SWFDEC_EVENT_DRAG_OVER: - return event_names[15]; + return SWFDEC_AS_STR_ON_DRAG_OVER; case SWFDEC_EVENT_DRAG_OUT: - return event_names[16]; + return SWFDEC_AS_STR_ON_DRAG_OUT; case SWFDEC_EVENT_KEY_PRESS: - return event_names[17]; + return NULL; case SWFDEC_EVENT_CONSTRUCT: - return event_names[18]; + return SWFDEC_AS_STR_ON_CONSTRUCT; default: g_assert_not_reached (); return NULL; @@ -222,32 +208,33 @@ swfdec_event_list_parse (SwfdecEventList } void -swfdec_event_list_execute (SwfdecEventList *list, SwfdecScriptable *scriptable, +swfdec_event_list_execute (SwfdecEventList *list, SwfdecAsObject *object, guint condition, guint8 key) { guint i; g_return_if_fail (list != NULL); + g_return_if_fail (SWFDEC_IS_AS_OBJECT (object)); for (i = 0; i < list->events->len; i++) { SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i); if ((event->conditions & condition) && event->key == key) { - SWFDEC_LOG ("executing script for event %u on scriptable %p", condition, scriptable); - swfdec_script_execute (event->script, scriptable); + SWFDEC_LOG ("executing script for event %u on scriptable %p", condition, object); + swfdec_as_object_run (object, event->script); } } } gboolean -swfdec_event_list_has_conditions (SwfdecEventList *list, SwfdecScriptable *scriptable, +swfdec_event_list_has_conditions (SwfdecEventList *list, SwfdecAsObject *object, guint condition, guint8 key) { guint i; const char *name; g_return_val_if_fail (list != NULL, FALSE); - g_return_val_if_fail (SWFDEC_IS_SCRIPTABLE (scriptable), FALSE); + g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), FALSE); for (i = 0; i < list->events->len; i++) { SwfdecEvent *event = &g_array_index (list->events, SwfdecEvent, i); @@ -257,7 +244,7 @@ swfdec_event_list_has_conditions (Swfdec } name = swfdec_event_type_get_name (condition); if (name) - return swfdec_scriptable_can_execute (scriptable, name); + return swfdec_as_object_has_function (object, name); return FALSE; } diff --git a/libswfdec/swfdec_event.h b/libswfdec/swfdec_event.h index 604e74b..6c5be7f 100644 --- a/libswfdec/swfdec_event.h +++ b/libswfdec/swfdec_event.h @@ -18,6 +18,7 @@ */ #include <libswfdec/swfdec_bits.h> +#include <libswfdec/swfdec_as_types.h> #include <libswfdec/swfdec_player.h> #include <libswfdec/swfdec_types.h> @@ -57,16 +58,16 @@ void swfdec_event_list_free (SwfdecEv void swfdec_event_list_parse (SwfdecEventList * list, SwfdecBits * bits, int version, - guint conditions, + guint conditions, guint8 key, const char * description); void swfdec_event_list_execute (SwfdecEventList * list, - SwfdecScriptable * scriptable, - guint condition, + SwfdecAsObject * object, + guint condition, guint8 key); gboolean swfdec_event_list_has_conditions(SwfdecEventList * list, - SwfdecScriptable * scriptable, - guint conditions, + SwfdecAsObject * object, + guint conditions, guint8 key); diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c index 807447e..fe35ed2 100644 --- a/libswfdec/swfdec_flv_decoder.c +++ b/libswfdec/swfdec_flv_decoder.c @@ -614,6 +614,7 @@ swfdec_flv_decoder_get_data (SwfdecFlvDe #include "swfdec_sprite.h" #include "swfdec_video_movie.h" +#if 0 static void notify_initialized (SwfdecPlayer *player, GParamSpec *pspec, SwfdecVideoMovie *movie) { @@ -623,6 +624,7 @@ notify_initialized (SwfdecPlayer *player swfdec_movie_queue_update (SWFDEC_MOVIE (movie), SWFDEC_MOVIE_INVALID_MATRIX); swfdec_movie_invalidate (SWFDEC_MOVIE (movie)); } +#endif gboolean swfdec_flv_decoder_is_eof (SwfdecFlvDecoder *flv) @@ -643,6 +645,8 @@ swfdec_flv_decoder_eof (SwfdecFlvDecoder SwfdecMovie * swfdec_flv_decoder_add_movie (SwfdecFlvDecoder *flv, SwfdecMovie *parent) { + g_assert_not_reached (); +#if 0 SwfdecContent *content = swfdec_content_new (0); SwfdecMovie *movie; SwfdecVideo *video; @@ -670,5 +674,6 @@ swfdec_flv_decoder_add_movie (SwfdecFlvD g_object_unref (stream); return movie; +#endif } diff --git a/libswfdec/swfdec_graphic.c b/libswfdec/swfdec_graphic.c index a0df25d..bc7f46c 100644 --- a/libswfdec/swfdec_graphic.c +++ b/libswfdec/swfdec_graphic.c @@ -30,12 +30,13 @@ G_DEFINE_ABSTRACT_TYPE (SwfdecGraphic, swfdec_graphic, SWFDEC_TYPE_CHARACTER) static SwfdecMovie * -swfdec_graphic_create_movie (SwfdecGraphic *graphic) +swfdec_graphic_create_movie (SwfdecGraphic *graphic, gsize *size) { SwfdecGraphicMovie *movie = g_object_new (SWFDEC_TYPE_GRAPHIC_MOVIE, NULL); movie->graphic = graphic; g_object_ref (graphic); + *size = sizeof (SwfdecGraphicMovie); return SWFDEC_MOVIE (movie); } diff --git a/libswfdec/swfdec_graphic.h b/libswfdec/swfdec_graphic.h index 1fded88..daa1066 100644 --- a/libswfdec/swfdec_graphic.h +++ b/libswfdec/swfdec_graphic.h @@ -1,7 +1,7 @@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,7 +51,8 @@ struct _SwfdecGraphicClass SwfdecCharacterClass character_class; /* when creating a movie for this graphic, calls this function */ - SwfdecMovie * (*create_movie) (SwfdecGraphic * graphic); + SwfdecMovie * (*create_movie) (SwfdecGraphic * graphic, + gsize * size); /* optional vfuncs */ void (* render) (SwfdecGraphic * graphic, cairo_t * cr, diff --git a/libswfdec/swfdec_js.c b/libswfdec/swfdec_js.c index 5ec2303..a3c8119 100644 --- a/libswfdec/swfdec_js.c +++ b/libswfdec/swfdec_js.c @@ -103,8 +103,6 @@ swfdec_js_init_player (SwfdecPlayer *pla swfdec_js_add_xml (player); swfdec_js_add_connection (player); swfdec_js_add_net_stream (player); - player->mouse_listener = swfdec_listener_new (player); - player->key_listener = swfdec_listener_new (player); } typedef struct _SwfdecJSInterval SwfdecJSInterval; diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c index 3f6333c..9f58d56 100644 --- a/libswfdec/swfdec_js_movie.c +++ b/libswfdec/swfdec_js_movie.c @@ -1427,56 +1427,6 @@ swfdec_js_movie_create_jsobject (SwfdecM swfdec_js_movie_add_property (movie); } -/** - * swfdec_movie_run_init: - * @movie: a #SwfdecMovie - * - * Runs onClipEvent(initialize) on the given @movie. - */ -void -swfdec_movie_run_init (SwfdecMovie *movie) -{ - SwfdecPlayer *player; - - g_return_if_fail (SWFDEC_IS_MOVIE (movie)); - g_return_if_fail (SWFDEC_SCRIPTABLE (movie)->jsobj != NULL); - - player = SWFDEC_ROOT_MOVIE (movie->root)->player; - g_queue_remove (player->init_queue, movie); - swfdec_movie_execute_script (movie, SWFDEC_EVENT_INITIALIZE); -} - -/** - * swfdec_movie_run_construct: - * @movie: a #SwfdecMovie - * - * Runs the constructors for @movie. This is (in the given order) - * onClipEvent(construct), movie.onConstruct and the constructor registered - * via Object.registerClass. - **/ -void -swfdec_movie_run_construct (SwfdecMovie *movie) -{ - SwfdecPlayer *player; - jsval fun; - - g_return_if_fail (SWFDEC_IS_MOVIE (movie)); - g_return_if_fail (SWFDEC_SCRIPTABLE (movie)->jsobj != NULL); - - player = SWFDEC_ROOT_MOVIE (movie->root)->player; - g_queue_remove (player->construct_queue, movie); - swfdec_movie_execute_script (movie, SWFDEC_EVENT_CONSTRUCT); - /* FIXME: need a check if the constructor can be unregistered after construction */ - if (SWFDEC_IS_SPRITE_MOVIE (movie) && - (fun = swfdec_js_movie_lookup_class (SWFDEC_SPRITE_MOVIE (movie))) != JSVAL_NULL) { - SwfdecScriptable *script = SWFDEC_SCRIPTABLE (movie); - SWFDEC_LOG ("Executing constructor for %s %p", G_OBJECT_TYPE_NAME (movie), movie); - if (!js_InternalCall (script->jscx, script->jsobj, fun, 0, NULL, &fun)) { - SWFDEC_ERROR ("constructor execution failed"); - } - } -} - void swfdec_js_movie_remove_jsobject (SwfdecMovie *movie) { diff --git a/libswfdec/swfdec_listener.c b/libswfdec/swfdec_listener.c index 85ea67d..b4495e7 100644 --- a/libswfdec/swfdec_listener.c +++ b/libswfdec/swfdec_listener.c @@ -21,31 +21,32 @@ #include "config.h" #endif #include "swfdec_listener.h" -#include "js/jsapi.h" -#include "js/jsfun.h" -#include "js/jsinterp.h" +#include "swfdec_as_context.h" +#include "swfdec_as_object.h" #include "swfdec_debug.h" -#include "swfdec_player_internal.h" typedef struct { - JSObject * object; /* the object we care about or NULL if empty */ - gboolean blocked :1; /* TRUE if may not be removed */ - gboolean removed :1; /* TRUE if was removed but is blocked */ + SwfdecAsObject * object; /* the object we care about or NULL if empty */ + const char * blocked_by; /* string of event we're about to execute */ + gboolean removed; /* TRUE if was removed but is blocked */ } SwfdecListenerEntry; struct _SwfdecListener { - SwfdecPlayer * player; + SwfdecAsContext * context; /* we can't use GArray here because it reallocated below us, which JS_AddRoot doesn't like */ SwfdecListenerEntry * entries; /* all allocated entries */ guint n_entries; /* number of allocated entries */ }; SwfdecListener * -swfdec_listener_new (SwfdecPlayer *player) +swfdec_listener_new (SwfdecAsContext *context) { - SwfdecListener *listener = g_new0 (SwfdecListener, 1); + SwfdecListener *listener; + + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); - listener->player = player; + listener = g_new0 (SwfdecListener, 1); + listener->context = context; listener->entries = NULL; listener->n_entries = 0; @@ -55,27 +56,19 @@ swfdec_listener_new (SwfdecPlayer *playe void swfdec_listener_free (SwfdecListener *listener) { - guint i; - JSContext *cx; - g_return_if_fail (listener != NULL); - cx = listener->player->jscx; - for (i = 0; i < listener->n_entries; i++) { - JS_RemoveRoot (cx, &listener->entries[i].object); - } g_free (listener->entries); - swfdec_player_remove_all_actions (listener->player, listener); g_free (listener); } gboolean -swfdec_listener_add (SwfdecListener *listener, JSObject *obj) +swfdec_listener_add (SwfdecListener *listener, SwfdecAsObject *obj) { guint found, i; g_return_val_if_fail (listener != NULL, FALSE); - g_return_val_if_fail (obj != NULL, FALSE); + g_return_val_if_fail (SWFDEC_AS_OBJECT (obj), FALSE); found = listener->n_entries; for (i = 0; i < listener->n_entries; i++) { @@ -87,24 +80,11 @@ swfdec_listener_add (SwfdecListener *lis if (found >= listener->n_entries) { gpointer mem; guint new_len = listener->n_entries + 16; - JSContext *cx = listener->player->jscx; - for (i = 0; i < listener->n_entries; i++) { - JS_RemoveRoot (cx, &listener->entries[i].object); - } mem = g_try_realloc (listener->entries, sizeof (SwfdecListenerEntry) * new_len); if (mem == NULL) return FALSE; listener->entries = mem; - for (i = listener->n_entries; i < new_len; i++) { - listener->entries[i].object = NULL; - listener->entries[i].blocked = 0; - listener->entries[i].removed = 0; - if (!JS_AddRoot (cx, &listener->entries[i].object)) { - listener->n_entries = i; - return FALSE; - } - } listener->n_entries = new_len; } g_assert (listener->entries[found].object == NULL); @@ -113,7 +93,7 @@ swfdec_listener_add (SwfdecListener *lis } void -swfdec_listener_remove (SwfdecListener *listener, JSObject *obj) +swfdec_listener_remove (SwfdecListener *listener, SwfdecAsObject *obj) { guint i; @@ -122,7 +102,7 @@ swfdec_listener_remove (SwfdecListener * for (i = 0; i < listener->n_entries; i++) { if (listener->entries[i].object == obj) { - if (listener->entries[i].blocked) { + if (listener->entries[i].blocked_by) { listener->entries[i].removed = TRUE; } else { listener->entries[i].object = NULL; @@ -132,53 +112,47 @@ swfdec_listener_remove (SwfdecListener * } } -static void -swfdec_listener_do_execute (gpointer listenerp, gpointer event_name) +void +swfdec_listener_execute (SwfdecListener *listener, const char *event_name) { guint i; - SwfdecListener *listener = listenerp; - JSContext *cx = listener->player->jscx; + + g_return_if_fail (listener != NULL); + g_return_if_fail (event_name != NULL); for (i = 0; i < listener->n_entries; i++) { - if (listener->entries[i].blocked) { - jsval fun; - JSObject *obj = listener->entries[i].object; + g_assert (listener->entries[i].blocked_by == NULL); /* ensure this happens only once */ + if (listener->entries[i].object) { + listener->entries[i].blocked_by = event_name; + } + } + for (i = 0; i < listener->n_entries; i++) { + if (listener->entries[i].blocked_by) { + SwfdecAsObject *obj = listener->entries[i].object; + const char *event = listener->entries[i].blocked_by; if (listener->entries[i].removed) { listener->entries[i].object = NULL; listener->entries[i].removed = FALSE; } - listener->entries[i].blocked = FALSE; - if (!JS_GetProperty (cx, obj, event_name, &fun)) - continue; - if (!JSVAL_IS_OBJECT (fun) || fun == JSVAL_NULL || - JS_GetClass (JSVAL_TO_OBJECT (fun)) != &js_FunctionClass) { - SWFDEC_INFO ("object has no handler for %s event", (char *) event_name); - continue; - } - js_InternalCall (cx, obj, fun, 0, NULL, &fun); + listener->entries[i].blocked_by = NULL; + swfdec_as_object_call (obj, event, 0, NULL); } } - g_free (event_name); } void -swfdec_listener_execute (SwfdecListener *listener, const char *event_name) +swfdec_listener_mark (SwfdecListener *listener) { - gboolean found = FALSE; guint i; g_return_if_fail (listener != NULL); - g_return_if_fail (event_name != NULL); for (i = 0; i < listener->n_entries; i++) { - g_assert (!listener->entries[i].blocked); /* ensure this happens only once */ if (listener->entries[i].object) { - listener->entries[i].blocked = TRUE; - found = TRUE; + swfdec_as_object_mark (listener->entries[i].object); + if (listener->entries[i].blocked_by) + swfdec_as_string_mark (listener->entries[i].blocked_by); } } - if (found) - swfdec_player_add_action (listener->player, listener, - swfdec_listener_do_execute, g_strdup (event_name)); } diff --git a/libswfdec/swfdec_listener.h b/libswfdec/swfdec_listener.h index de4694d..f0a0791 100644 --- a/libswfdec/swfdec_listener.h +++ b/libswfdec/swfdec_listener.h @@ -18,8 +18,8 @@ */ #include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_as_types.h> #include <libswfdec/swfdec_types.h> -#include <libswfdec/js/jspubtd.h> #ifndef _SWFDEC_LISTENER_H_ #define _SWFDEC_LISTENER_H_ @@ -27,14 +27,15 @@ G_BEGIN_DECLS -SwfdecListener * swfdec_listener_new (SwfdecPlayer * player); +SwfdecListener * swfdec_listener_new (SwfdecAsContext * context); void swfdec_listener_free (SwfdecListener * listener); gboolean swfdec_listener_add (SwfdecListener * listener, - JSObject * obj); + SwfdecAsObject * obj); void swfdec_listener_remove (SwfdecListener * listener, - JSObject * obj); + SwfdecAsObject * obj); void swfdec_listener_execute (SwfdecListener * listener, const char * event); +void swfdec_listener_mark (SwfdecListener * listener); G_END_DECLS diff --git a/libswfdec/swfdec_morphshape.c b/libswfdec/swfdec_morphshape.c index 623e790..7d28130 100644 --- a/libswfdec/swfdec_morphshape.c +++ b/libswfdec/swfdec_morphshape.c @@ -31,7 +31,7 @@ G_DEFINE_TYPE (SwfdecMorphShape, swfdec_morph_shape, SWFDEC_TYPE_SHAPE) static SwfdecMovie * -swfdec_graphic_create_movie (SwfdecGraphic *graphic) +swfdec_graphic_create_movie (SwfdecGraphic *graphic, gsize *size) { guint i; SwfdecMorphShape *morph = SWFDEC_MORPH_SHAPE (graphic); @@ -40,10 +40,12 @@ swfdec_graphic_create_movie (SwfdecGraph movie->morph = morph; g_object_ref (morph); + *size = sizeof (SwfdecMorphMovie) + sizeof (cairo_path_t) * morph->end_vecs->len; movie->paths = g_new0 (cairo_path_t, morph->end_vecs->len); for (i = 0; i < morph->end_vecs->len; i++) { movie->paths[i].num_data = g_array_index (morph->end_vecs, SwfdecShapeVec, i).path.num_data; movie->paths[i].data = g_new (cairo_path_data_t, movie->paths[i].num_data); + *size += sizeof (cairo_path_data_t) * movie->paths[i].num_data; } return SWFDEC_MOVIE (movie); diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c index 3317fb2..3b6a726 100644 --- a/libswfdec/swfdec_movie.c +++ b/libswfdec/swfdec_movie.c @@ -23,14 +23,13 @@ #include <string.h> #include <math.h> -#include <js/jsapi.h> - #include "swfdec_movie.h" +#include "swfdec_as_context.h" #include "swfdec_debug.h" #include "swfdec_debugger.h" #include "swfdec_event.h" #include "swfdec_graphic.h" -#include "swfdec_js.h" +#include "swfdec_loader_internal.h" #include "swfdec_player_internal.h" #include "swfdec_root_movie.h" #include "swfdec_sprite.h" @@ -39,7 +38,7 @@ static const SwfdecContent default_content = SWFDEC_CONTENT_DEFAULT; -G_DEFINE_ABSTRACT_TYPE (SwfdecMovie, swfdec_movie, SWFDEC_TYPE_SCRIPTABLE) +G_DEFINE_ABSTRACT_TYPE (SwfdecMovie, swfdec_movie, SWFDEC_TYPE_AS_OBJECT) static void swfdec_movie_init (SwfdecMovie * movie) @@ -324,7 +323,7 @@ swfdec_movie_destroy (SwfdecMovie *movie swfdec_movie_set_content (movie, NULL); if (klass->finish_movie) klass->finish_movie (movie); - swfdec_js_movie_remove_jsobject (movie); + //swfdec_js_movie_remove_jsobject (movie); player->movies = g_list_remove (player->movies, movie); g_object_unref (movie); } @@ -348,6 +347,55 @@ swfdec_movie_remove (SwfdecMovie *movie) swfdec_movie_destroy (movie); } +/** + * swfdec_movie_run_init: + * @movie: a #SwfdecMovie + * + * Runs onClipEvent(initialize) on the given @movie. + */ +void +swfdec_movie_run_init (SwfdecMovie *movie) +{ + SwfdecPlayer *player; + + g_return_if_fail (SWFDEC_IS_MOVIE (movie)); + + player = SWFDEC_ROOT_MOVIE (movie->root)->player; + g_queue_remove (player->init_queue, movie); + swfdec_movie_execute_script (movie, SWFDEC_EVENT_INITIALIZE); +} + +/** + * swfdec_movie_run_construct: + * @movie: a #SwfdecMovie + * + * Runs the constructors for @movie. This is (in the given order) + * onClipEvent(construct), movie.onConstruct and the constructor registered + * via Object.registerClass. + **/ +void +swfdec_movie_run_construct (SwfdecMovie *movie) +{ + SwfdecPlayer *player; + + g_return_if_fail (SWFDEC_IS_MOVIE (movie)); + + player = SWFDEC_ROOT_MOVIE (movie->root)->player; + g_queue_remove (player->construct_queue, movie); + swfdec_movie_execute_script (movie, SWFDEC_EVENT_CONSTRUCT); +#if 0 + /* FIXME: need a check if the constructor can be unregistered after construction */ + if (SWFDEC_IS_SPRITE_MOVIE (movie) && + (fun = swfdec_js_movie_lookup_class (SWFDEC_SPRITE_MOVIE (movie))) != JSVAL_NULL) { + SwfdecScriptable *script = SWFDEC_SCRIPTABLE (movie); + SWFDEC_LOG ("Executing constructor for %s %p", G_OBJECT_TYPE_NAME (movie), movie); + if (!js_InternalCall (script->jscx, script->jsobj, fun, 0, NULL, &fun)) { + SWFDEC_ERROR ("constructor execution failed"); + } + } +#endif +} + void swfdec_movie_execute_script (SwfdecMovie *movie, SwfdecEventType condition) { @@ -358,11 +406,11 @@ swfdec_movie_execute_script (SwfdecMovie if (movie->content->events) { swfdec_event_list_execute (movie->content->events, - SWFDEC_SCRIPTABLE (movie), condition, 0); + SWFDEC_AS_OBJECT (movie), condition, 0); } name = swfdec_event_type_get_name (condition); if (name != NULL) - swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (movie), name, 0, NULL); + swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), name, 0, NULL); } static void @@ -390,12 +438,12 @@ swfdec_movie_queue_script (SwfdecMovie * if (movie->content->events) { if (!swfdec_event_list_has_conditions (movie->content->events, - SWFDEC_SCRIPTABLE (movie), condition, 0)) + SWFDEC_AS_OBJECT (movie), condition, 0)) return FALSE; } else { const char *name = swfdec_event_type_get_name (condition); if (name == NULL || - !swfdec_scriptable_can_execute (SWFDEC_SCRIPTABLE (movie), name)) + !swfdec_as_object_has_function (SWFDEC_AS_OBJECT (movie), name)) return FALSE; } @@ -405,6 +453,52 @@ swfdec_movie_queue_script (SwfdecMovie * return TRUE; } +/** + * swfdec_movie_set_variables: + * @script: a #SwfdecMovie + * @variables: variables to set on @movie in application-x-www-form-urlencoded + * format + * + * Verifies @variables to be encoded correctly and sets them as string + * properties on the given @movie. + **/ +void +swfdec_movie_set_variables (SwfdecMovie *movie, const char *variables) +{ + SwfdecAsObject *as; + + g_return_if_fail (SWFDEC_IS_MOVIE (movie)); + g_return_if_fail (variables != NULL); + + as = SWFDEC_AS_OBJECT (movie); + SWFDEC_DEBUG ("setting variables on %p: %s", movie, variables); + while (TRUE) { + char *name, *value; + const char *asname; + SwfdecAsValue val; + + if (!swfdec_urldecode_one (variables, &name, &value, &variables)) { + SWFDEC_WARNING ("variables invalid at \"%s\"", variables); + break; + } + if (*variables != '\0' && *variables != '&') { + SWFDEC_WARNING ("variables not delimited with & at \"%s\"", variables); + g_free (name); + g_free (value); + break; + } + asname = swfdec_as_context_get_string (as->context, name); + g_free (name); + SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (as->context, value)); + g_free (value); + swfdec_as_object_set (as, asname, &val); + SWFDEC_LOG ("Set variable \"%s\" to \"%s\"", name, value); + if (*variables == '\0') + break; + variables++; + } +} + /* NB: coordinates are in movie's coordiante system. Use swfdec_movie_get_mouse * if you have global coordinates */ static gboolean @@ -672,25 +766,13 @@ swfdec_movie_iterate_end (SwfdecMovie *m g_list_find (movie->parent->list, movie) != NULL; } -static JSObject * -swfdec_movie_create_js_object (SwfdecScriptable *script) -{ - /* we create the objects manually and ensure persistence */ - g_assert_not_reached (); -} - -extern const JSClass movieclip_class; static void swfdec_movie_class_init (SwfdecMovieClass * movie_class) { GObjectClass *object_class = G_OBJECT_CLASS (movie_class); - SwfdecScriptableClass *script_class = SWFDEC_SCRIPTABLE_CLASS (movie_class); object_class->dispose = swfdec_movie_dispose; - script_class->jsclass = &movieclip_class; - script_class->create_js_object = swfdec_movie_create_js_object; - movie_class->iterate_end = swfdec_movie_iterate_end; } @@ -740,7 +822,7 @@ swfdec_movie_set_parent (SwfdecMovie *mo */ player->movies = g_list_prepend (player->movies, movie); /* we have to create the JSObject here to get actions queued before init_movie executes */ - swfdec_js_movie_create_jsobject (movie); + //swfdec_js_movie_create_jsobject (movie); /* queue init and construct events for non-root movies */ if (movie != movie->root) { g_queue_push_tail (player->init_queue, movie); @@ -781,6 +863,8 @@ swfdec_movie_new (SwfdecMovie *parent, c { SwfdecGraphicClass *klass; SwfdecMovie *ret; + SwfdecAsObject *object; + gsize size; g_return_val_if_fail (SWFDEC_IS_MOVIE (parent), NULL); g_return_val_if_fail (SWFDEC_IS_GRAPHIC (content->graphic), NULL); @@ -789,9 +873,15 @@ swfdec_movie_new (SwfdecMovie *parent, c SWFDEC_DEBUG ("new movie for parent %p", parent); klass = SWFDEC_GRAPHIC_GET_CLASS (content->graphic); g_return_val_if_fail (klass->create_movie != NULL, NULL); - ret = klass->create_movie (content->graphic); + ret = klass->create_movie (content->graphic, &size); + object = SWFDEC_AS_OBJECT (parent); + if (swfdec_as_context_use_mem (object->context, size)) { + swfdec_as_object_add (SWFDEC_AS_OBJECT (ret), object->context, size); + g_object_ref (ret); + } else { + SWFDEC_AS_OBJECT (ret)->context = object->context; + } ret->parent = parent; - SWFDEC_SCRIPTABLE (ret)->jscx = SWFDEC_SCRIPTABLE (parent)->jscx; g_object_ref (parent); ret->root = parent->root; swfdec_movie_initialize (ret, content); @@ -811,7 +901,13 @@ swfdec_movie_new_for_player (SwfdecPlaye ret = g_object_new (SWFDEC_TYPE_ROOT_MOVIE, NULL); g_object_weak_ref (G_OBJECT (ret), (GWeakNotify) swfdec_content_free, content); SWFDEC_ROOT_MOVIE (ret)->player = player; - SWFDEC_SCRIPTABLE (ret)->jscx = player->jscx; + if (swfdec_as_context_use_mem (SWFDEC_AS_CONTEXT (player), sizeof (SwfdecRootMovie))) { + swfdec_as_object_add (SWFDEC_AS_OBJECT (ret), + SWFDEC_AS_CONTEXT (player), sizeof (SwfdecRootMovie)); + g_object_ref (ret); + } else { + SWFDEC_AS_OBJECT (ret)->context = SWFDEC_AS_CONTEXT (player); + } ret->root = ret; swfdec_movie_initialize (ret, content); ret->has_name = FALSE; diff --git a/libswfdec/swfdec_movie.h b/libswfdec/swfdec_movie.h index f1db624..299c793 100644 --- a/libswfdec/swfdec_movie.h +++ b/libswfdec/swfdec_movie.h @@ -21,11 +21,11 @@ #define _SWFDEC_MOVIE_H_ #include <glib-object.h> +#include <libswfdec/swfdec_as_object.h> #include <libswfdec/swfdec_color.h> #include <libswfdec/swfdec.h> -#include <libswfdec/swfdec_rect.h> #include <libswfdec/swfdec_event.h> -#include <libswfdec/swfdec_scriptable.h> +#include <libswfdec/swfdec_rect.h> #include <libswfdec/swfdec_types.h> G_BEGIN_DECLS @@ -75,7 +75,7 @@ typedef enum { } SwfdecMovieState; struct _SwfdecMovie { - SwfdecScriptable scriptable; + SwfdecAsObject object; char * name; /* name used in to_string */ gboolean has_name; /* TRUE if name wasn't given automagically */ @@ -115,7 +115,7 @@ struct _SwfdecMovie { }; struct _SwfdecMovieClass { - SwfdecScriptableClass scriptable_class; + SwfdecAsObjectClass object_class; /* general vfuncs */ void (* init_movie) (SwfdecMovie * movie); @@ -189,6 +189,8 @@ void swfdec_movie_execute_script (Swfde SwfdecEventType condition); gboolean swfdec_movie_queue_script (SwfdecMovie * movie, SwfdecEventType condition); +void swfdec_movie_set_variables (SwfdecMovie * movie, + const char * variables); int swfdec_movie_compare_depths (gconstpointer a, gconstpointer b); SwfdecDepthClass diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c index b0bcd4d..04d89a3 100644 --- a/libswfdec/swfdec_net_stream.c +++ b/libswfdec/swfdec_net_stream.c @@ -28,36 +28,25 @@ #include "swfdec_debug.h" #include "swfdec_loader_internal.h" #include "swfdec_loadertarget.h" -#include "js/jsapi.h" +/* NB: code and level must be rooted gc-strings */ static void swfdec_net_stream_onstatus (SwfdecNetStream *stream, const char *code, const char *level) { - jsval val; - JSString *string; - JSObject *object; - JSContext *cx; + SwfdecAsValue val; + SwfdecAsObject *object; - SWFDEC_INFO ("emitting onStatus for %s %s", level, code); - cx = stream->player->jscx; - object = JS_NewObject (cx, NULL, NULL, NULL); + object = swfdec_as_object_new (SWFDEC_AS_OBJECT (stream)->context); if (!object) return; - string = JS_NewStringCopyZ (cx, code); - if (!string) - return; - val = STRING_TO_JSVAL (string); - if (!JS_SetProperty (cx, object, "code", &val)) - return; - string = JS_NewStringCopyZ (cx, level); - if (!string) - return; - val = STRING_TO_JSVAL (string); - if (!JS_SetProperty (cx, object, "level", &val)) - return; + SWFDEC_INFO ("emitting onStatus for %s %s", level, code); + SWFDEC_AS_VALUE_SET_STRING (&val, code); + swfdec_as_object_set (object, SWFDEC_AS_STR_CODE, &val); + SWFDEC_AS_VALUE_SET_STRING (&val, level); + swfdec_as_object_set (object, SWFDEC_AS_STR_LEVEL, &val); - val = OBJECT_TO_JSVAL (object); - swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (stream), "onStatus", 1, &val); + SWFDEC_AS_VALUE_SET_OBJECT (&val, object); + swfdec_as_object_call (SWFDEC_AS_OBJECT (stream), SWFDEC_AS_STR_ON_STATUS, 1, &val); } static void swfdec_net_stream_update_playing (SwfdecNetStream *stream); @@ -116,16 +105,17 @@ swfdec_net_stream_video_goto (SwfdecNetS } if (stream->next_time <= stream->current_time) { if (swfdec_flv_decoder_is_eof (stream->flvdecoder)) { - swfdec_net_stream_onstatus (stream, "NetStream.Play.Stop", "status"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_PLAY_STOP, SWFDEC_AS_STR_STATUS); } else { stream->buffering = TRUE; - swfdec_net_stream_onstatus (stream, "NetStream.Buffer.Empty", "status"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_BUFFER_EMPTY, + SWFDEC_AS_STR_STATUS); } swfdec_net_stream_update_playing (stream); } if (process_events) { while (process_events_from <= stream->current_time) { - jsval name, value; + SwfdecAsValue name, value; SwfdecBits bits; SwfdecBuffer *event = swfdec_flv_decoder_get_data (stream->flvdecoder, process_events_from, &process_events_from); if (!event) @@ -133,12 +123,12 @@ swfdec_net_stream_video_goto (SwfdecNetS SWFDEC_LOG ("processing event from timestamp %u", process_events_from); process_events_from++; /* increase so we get the next event next time */ swfdec_bits_init (&bits, event); - if (swfdec_amf_parse (SWFDEC_SCRIPTABLE (stream)->jscx, &bits, 2, + if (swfdec_amf_parse (SWFDEC_AS_OBJECT (stream)->context, &bits, 2, SWFDEC_AMF_STRING, &name, SWFDEC_AMF_MIXED_ARRAY, &value) != 2) { SWFDEC_ERROR ("could not parse data tag"); } else { - swfdec_scriptable_execute (SWFDEC_SCRIPTABLE (stream), - JS_GetStringBytes (JSVAL_TO_STRING (name)), 1, &value); + swfdec_as_object_call (SWFDEC_AS_OBJECT (stream), + SWFDEC_AS_VALUE_GET_STRING (&name), 1, &value); } } } @@ -221,7 +211,8 @@ swfdec_net_stream_loader_target_parse (S if (loader->error) { if (stream->flvdecoder == NULL) - swfdec_net_stream_onstatus (stream, "NetStream.Play.StreamNotFound", "error"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_PLAY_STREAMNOTFOUND, + SWFDEC_AS_STR_ERROR); return; } if (!loader->eof && swfdec_buffer_queue_get_depth (loader->queue) == 0) { @@ -233,7 +224,8 @@ swfdec_net_stream_loader_target_parse (S stream->flvdecoder = g_object_new (SWFDEC_TYPE_FLV_DECODER, NULL); SWFDEC_DECODER (stream->flvdecoder)->player = stream->player; SWFDEC_DECODER (stream->flvdecoder)->queue = loader->queue; - swfdec_net_stream_onstatus (stream, "NetStream.Play.Start", "status"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_PLAY_START, + SWFDEC_AS_STR_STATUS); swfdec_loader_set_data_type (loader, SWFDEC_LOADER_DATA_FLV); } klass = SWFDEC_DECODER_GET_CLASS (stream->flvdecoder); @@ -267,12 +259,14 @@ out: guint first, last; swfdec_flv_decoder_eof (stream->flvdecoder); recheck = TRUE; - swfdec_net_stream_onstatus (stream, "NetStream.Buffer.Flush", "status"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_BUFFER_FLUSH, + SWFDEC_AS_STR_STATUS); swfdec_net_stream_video_goto (stream, stream->current_time); stream->buffering = FALSE; if (swfdec_flv_decoder_get_video_info (stream->flvdecoder, &first, &last) && stream->current_time + stream->buffer_time <= last) { - swfdec_net_stream_onstatus (stream, "NetStream.Buffer.Full", "status"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_BUFFER_FULL, + SWFDEC_AS_STR_STATUS); } } if (recheck) { @@ -283,7 +277,8 @@ out: if (current + stream->buffer_time <= last) { swfdec_net_stream_video_goto (stream, current); stream->buffering = FALSE; - swfdec_net_stream_onstatus (stream, "NetStream.Buffer.Full", "status"); + swfdec_net_stream_onstatus (stream, SWFDEC_AS_STR_NETSTREAM_BUFFER_FULL, + SWFDEC_AS_STR_STATUS); } } else { SWFDEC_ERROR ("no video stream, how do we update buffering?"); @@ -323,7 +318,7 @@ swfdec_net_stream_input_disconnect (Swfd /*** SWFDEC_NET_STREAM ***/ -G_DEFINE_TYPE_WITH_CODE (SwfdecNetStream, swfdec_net_stream, SWFDEC_TYPE_SCRIPTABLE, +G_DEFINE_TYPE_WITH_CODE (SwfdecNetStream, swfdec_net_stream, SWFDEC_TYPE_AS_OBJECT, G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_net_stream_loader_target_init)) static void @@ -346,16 +341,25 @@ swfdec_net_stream_dispose (GObject *obje G_OBJECT_CLASS (swfdec_net_stream_parent_class)->dispose (object); } -extern const JSClass net_stream_class; +static void +swfdec_net_stream_mark (SwfdecAsObject *object) +{ + SwfdecNetStream *stream = SWFDEC_NET_STREAM (object); + + swfdec_as_object_mark (SWFDEC_AS_OBJECT (stream->conn)); + + SWFDEC_AS_OBJECT_CLASS (swfdec_net_stream_parent_class)->mark (object); +} + static void swfdec_net_stream_class_init (SwfdecNetStreamClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfdecScriptableClass *scriptable_class = SWFDEC_SCRIPTABLE_CLASS (klass); + SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); object_class->dispose = swfdec_net_stream_dispose; - scriptable_class->jsclass = &net_stream_class; + asobject_class->mark = swfdec_net_stream_mark; } static void @@ -370,16 +374,17 @@ swfdec_net_stream_init (SwfdecNetStream SwfdecNetStream * swfdec_net_stream_new (SwfdecPlayer *player, SwfdecConnection *conn) { + SwfdecAsContext *context; SwfdecNetStream *stream; - g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); g_return_val_if_fail (SWFDEC_IS_CONNECTION (conn), NULL); + context = SWFDEC_AS_OBJECT (conn)->context; + if (!swfdec_as_context_use_mem (context, sizeof (SwfdecNetStream))) + return NULL; stream = g_object_new (SWFDEC_TYPE_NET_STREAM, NULL); - stream->player = player; + swfdec_as_object_add (SWFDEC_AS_OBJECT (stream), context, sizeof (SwfdecNetStream)); stream->conn = conn; - SWFDEC_SCRIPTABLE (stream)->jscx = player->jscx; - g_object_ref (conn); return stream; } diff --git a/libswfdec/swfdec_net_stream.h b/libswfdec/swfdec_net_stream.h index 7973b5f..8f95d97 100644 --- a/libswfdec/swfdec_net_stream.h +++ b/libswfdec/swfdec_net_stream.h @@ -21,10 +21,10 @@ #define _SWFDEC_NET_STREAM_H_ #include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_as_object.h> #include <libswfdec/swfdec_connection.h> #include <libswfdec/swfdec_flv_decoder.h> #include <libswfdec/swfdec_player_internal.h> -#include <libswfdec/swfdec_scriptable.h> #include <libswfdec/swfdec_video_movie.h> G_BEGIN_DECLS @@ -41,7 +41,7 @@ typedef struct _SwfdecNetStreamClass Swf struct _SwfdecNetStream { - SwfdecScriptable scriptable; + SwfdecAsObject object; SwfdecPlayer * player; /* the player we play in */ SwfdecConnection * conn; /* connection used for opening streams */ @@ -71,7 +71,7 @@ struct _SwfdecNetStream struct _SwfdecNetStreamClass { - SwfdecScriptableClass scriptable_class; + SwfdecAsObjectClass object_class; }; GType swfdec_net_stream_get_type (void); diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c index 6e03f55..28a1547 100644 --- a/libswfdec/swfdec_player.c +++ b/libswfdec/swfdec_player.c @@ -32,7 +32,6 @@ #include "swfdec_debug.h" #include "swfdec_enums.h" #include "swfdec_event.h" -#include "swfdec_js.h" #include "swfdec_listener.h" #include "swfdec_loader_internal.h" #include "swfdec_marshal.h" @@ -309,7 +308,7 @@ enum { PROP_BACKGROUND_COLOR }; -G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, G_TYPE_OBJECT) +G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, SWFDEC_TYPE_AS_CONTEXT) void swfdec_player_remove_movie (SwfdecPlayer *player, SwfdecMovie *movie) @@ -365,31 +364,20 @@ swfdec_player_set_property (GObject *obj } } -static gboolean -free_registered_class (gpointer key, gpointer value, gpointer playerp) -{ - SwfdecPlayer *player = playerp; - - g_free (key); - JS_RemoveRoot (player->jscx, value); - g_free (value); - return TRUE; -} - static void swfdec_player_dispose (GObject *object) { SwfdecPlayer *player = SWFDEC_PLAYER (object); swfdec_player_stop_all_sounds (player); - /* this must happen before we finish the JS player, we have roots in there */ - g_hash_table_foreach_steal (player->registered_classes, free_registered_class, player); g_hash_table_destroy (player->registered_classes); while (player->roots) swfdec_movie_destroy (player->roots->data); - swfdec_js_finish_player (player); + swfdec_listener_free (player->mouse_listener); + swfdec_listener_free (player->key_listener); + //swfdec_js_finish_player (player); swfdec_player_remove_all_actions (player, player); /* HACK to allow non-removable actions */ g_assert (swfdec_ring_buffer_pop (player->actions) == NULL); @@ -542,7 +530,7 @@ swfdec_player_do_mouse_move (SwfdecPlaye for (walk = player->movies; walk; walk = walk->next) { swfdec_movie_queue_script (walk->data, SWFDEC_EVENT_MOUSE_MOVE); } - swfdec_listener_execute (player->mouse_listener, "onMouseMove"); + swfdec_listener_execute (player->mouse_listener, SWFDEC_AS_STR_ON_MOUSE_MOVE); swfdec_player_update_mouse_position (player); } @@ -555,10 +543,10 @@ swfdec_player_do_mouse_button (SwfdecPla if (player->mouse_button) { event = SWFDEC_EVENT_MOUSE_DOWN; - event_name = "onMouseDown"; + event_name = SWFDEC_AS_STR_ON_MOUSE_DOWN; } else { event = SWFDEC_EVENT_MOUSE_UP; - event_name = "onMouseUp"; + event_name = SWFDEC_AS_STR_ON_MOUSE_UP; } for (walk = player->movies; walk; walk = walk->next) { swfdec_movie_queue_script (walk->data, event); @@ -773,9 +761,29 @@ swfdec_accumulate_or (GSignalInvocationH } static void +swfdec_player_mark_string_object (gpointer key, gpointer value, gpointer data) +{ + swfdec_as_string_mark (key); + swfdec_as_object_mark (value); +} + +static void +swfdec_player_mark (SwfdecAsContext *context) +{ + SwfdecPlayer *player = SWFDEC_PLAYER (context); + + g_hash_table_foreach (player->registered_classes, swfdec_player_mark_string_object, NULL); + swfdec_listener_mark (player->mouse_listener); + swfdec_listener_mark (player->key_listener); + + SWFDEC_AS_CONTEXT_CLASS (swfdec_player_parent_class)->mark (context); +} + +static void swfdec_player_class_init (SwfdecPlayerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfdecAsContextClass *context_class = SWFDEC_AS_CONTEXT_CLASS (klass); object_class->get_property = swfdec_player_get_property; object_class->set_property = swfdec_player_set_property; @@ -891,6 +899,8 @@ swfdec_player_class_init (SwfdecPlayerCl G_SIGNAL_RUN_LAST, 0, NULL, NULL, swfdec_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + context_class->mark = swfdec_player_mark; + klass->advance = swfdec_player_do_advance; klass->handle_mouse = swfdec_player_do_handle_mouse; } @@ -898,9 +908,11 @@ swfdec_player_class_init (SwfdecPlayerCl static void swfdec_player_init (SwfdecPlayer *player) { - swfdec_js_init_player (player); - player->registered_classes = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + //swfdec_js_init_player (player); + player->mouse_listener = swfdec_listener_new (SWFDEC_AS_CONTEXT (player)); + player->key_listener = swfdec_listener_new (SWFDEC_AS_CONTEXT (player)); + player->registered_classes = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, NULL); player->actions = swfdec_ring_buffer_new_for_type (SwfdecPlayerAction, 16); player->cache = swfdec_cache_new (50 * 1024 * 1024); /* 100 MB */ @@ -960,7 +972,7 @@ swfdec_player_add_level_from_loader (Swf root->player = player; root->loader = loader; if (variables) - swfdec_scriptable_set_variables (SWFDEC_SCRIPTABLE (movie), variables); + swfdec_movie_set_variables (movie, variables); swfdec_loader_set_target (root->loader, SWFDEC_LOADER_TARGET (root)); return root; } @@ -1042,42 +1054,41 @@ swfdec_player_initialize (SwfdecPlayer * g_object_notify (G_OBJECT (player), "initialized"); } -jsval +/** + * swfdec_player_get_export_class: + * @player: a #SwfdecPlayer + * @name: garbage-collected string naming the export + * + * Looks up the constructor for characters that are exported using @name. + * + * Returns: a #SwfdecAsObject naming the constructor or %NULL if none + **/ +SwfdecAsObject * swfdec_player_get_export_class (SwfdecPlayer *player, const char *name) { - jsval *val = g_hash_table_lookup (player->registered_classes, name); - - if (val) - return *val; - else - return JSVAL_NULL; + return g_hash_table_lookup (player->registered_classes, name); } +/** + * swfdec_player_set_export_class: + * @player: a #SwfdecPlayer + * @name: garbage-collected string naming the export + * @object: object to use as constructor or %NULL for none + * + * Sets the constructor to be used for instances created using the object + * exported with @name. + **/ void -swfdec_player_set_export_class (SwfdecPlayer *player, const char *name, jsval val) +swfdec_player_set_export_class (SwfdecPlayer *player, const char *name, SwfdecAsObject *object) { - jsval *insert; - g_return_if_fail (SWFDEC_IS_PLAYER (player)); g_return_if_fail (name != NULL); - g_return_if_fail (JSVAL_IS_OBJECT (val)); + g_return_if_fail (object == NULL || SWFDEC_IS_AS_OBJECT (object)); - insert = g_hash_table_lookup (player->registered_classes, name); - if (insert) { - JS_RemoveRoot (player->jscx, insert); - g_free (insert); + if (object) + g_hash_table_insert (player->registered_classes, (gpointer) name, object); + else g_hash_table_remove (player->registered_classes, name); - } - - if (val != JSVAL_NULL) { - insert = g_new (jsval, 1); - *insert = val; - if (!JS_AddRoot (player->jscx, insert)) { - g_free (insert); - return; - } - g_hash_table_insert (player->registered_classes, g_strdup (name), insert); - } } /** PUBLIC API ***/ @@ -1207,7 +1218,6 @@ swfdec_init (void) swfdec_debug_set_level (level); } } - swfdec_js_init (0); } /** diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h index f4de1a1..7dcf8dc 100644 --- a/libswfdec/swfdec_player_internal.h +++ b/libswfdec/swfdec_player_internal.h @@ -20,11 +20,10 @@ #ifndef _SWFDEC_PLAYER_INTERNAL_H_ #define _SWFDEC_PLAYER_INTERNAL_H_ -#include <glib-object.h> #include <libswfdec/swfdec_player.h> +#include <libswfdec/swfdec_as_context.h> #include <libswfdec/swfdec_rect.h> #include <libswfdec/swfdec_ringbuffer.h> -#include <libswfdec/js/jspubtd.h> G_BEGIN_DECLS @@ -39,7 +38,7 @@ struct _SwfdecTimeout { struct _SwfdecPlayer { - GObject object; + SwfdecAsContext context; /* global properties */ guint rate; /* divide by 256 to get iterations per second */ @@ -51,12 +50,10 @@ struct _SwfdecPlayer SwfdecColor bgcolor; /* background color */ SwfdecLoader * loader; /* initial loader */ - /* javascript */ - JSContext * jscx; /* global Javascript context */ - JSObject * jsobj; /* the global object */ - guint interval_id; /* id returned from setInterval call */ + /* ActionScript */ + guint interval_id; /* id returned from setInterval call */ GList * intervals; /* all currently running intervals */ - GHashTable * registered_classes; /* name => jsval* to constructor */ + GHashTable * registered_classes; /* name => SwfdecAsObject constructor */ SwfdecListener * mouse_listener; /* emitting mouse events */ SwfdecListener * key_listener; /* emitting keyboard events */ @@ -92,7 +89,7 @@ struct _SwfdecPlayer struct _SwfdecPlayerClass { - GObjectClass object_class; + SwfdecAsContextClass context_class; void (* advance) (SwfdecPlayer * player, guint msecs, @@ -117,11 +114,11 @@ void swfdec_player_lock (SwfdecPlayer void swfdec_player_unlock (SwfdecPlayer * player); void swfdec_player_perform_actions (SwfdecPlayer * player); -jsval swfdec_player_get_export_class (SwfdecPlayer * player, +SwfdecAsObject *swfdec_player_get_export_class (SwfdecPlayer * player, const char * name); void swfdec_player_set_export_class (SwfdecPlayer * player, const char * name, - jsval val); + SwfdecAsObject * object); void swfdec_player_invalidate (SwfdecPlayer * player, const SwfdecRect * rect); diff --git a/libswfdec/swfdec_root_movie.c b/libswfdec/swfdec_root_movie.c index 36282d7..8b22055 100644 --- a/libswfdec/swfdec_root_movie.c +++ b/libswfdec/swfdec_root_movie.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> #include "swfdec_root_movie.h" +#include "swfdec_as_object.h" #include "swfdec_character.h" #include "swfdec_debug.h" #include "swfdec_decoder.h" @@ -35,7 +36,6 @@ #include "swfdec_root_sprite.h" #include "swfdec_script.h" #include "swfdec_swf_decoder.h" -#include "js/jsapi.h" static void swfdec_root_movie_loader_target_init (SwfdecLoaderTargetInterface *iface); @@ -79,14 +79,6 @@ swfdec_root_movie_loader_target_set_deco static gboolean swfdec_root_movie_loader_target_do_init (SwfdecLoaderTarget *target) { - SwfdecRootMovie *movie = SWFDEC_ROOT_MOVIE (target); - - if (movie->player->roots->next == 0) { - /* if we're the only child */ - /* FIXME: check case sensitivity wrt embedding movies of different version */ - JS_SetContextCaseSensitive (movie->player->jscx, - SWFDEC_SWF_DECODER (movie->decoder)->version > 6); - } return TRUE; } @@ -243,7 +235,7 @@ swfdec_root_movie_perform_root_actions ( SwfdecSpriteAction *action = &g_array_index (array, SwfdecSpriteAction, i); switch (action->type) { case SWFDEC_ROOT_ACTION_INIT_SCRIPT: - swfdec_script_execute (action->data, SWFDEC_SCRIPTABLE (root)); + swfdec_as_object_run (SWFDEC_AS_OBJECT (root), action->data); break; case SWFDEC_ROOT_ACTION_EXPORT: { diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 60b107a..a537953 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -25,13 +25,11 @@ #include "swfdec_as_context.h" #include "swfdec_debug.h" #include "swfdec_debugger.h" -#include "swfdec_scriptable.h" #include <errno.h> #include <math.h> #include <string.h> #include "swfdec_decoder.h" -#include "swfdec_js.h" #include "swfdec_movie.h" #include "swfdec_player_internal.h" #include "swfdec_root_movie.h" diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c index 1c6a43f..04e7ff4 100644 --- a/libswfdec/swfdec_sprite.c +++ b/libswfdec/swfdec_sprite.c @@ -477,11 +477,12 @@ swfdec_spriteseg_remove_object_2 (Swfdec } static SwfdecMovie * -swfdec_sprite_create_movie (SwfdecGraphic *graphic) +swfdec_sprite_create_movie (SwfdecGraphic *graphic, gsize *size) { SwfdecSpriteMovie *ret = g_object_new (SWFDEC_TYPE_SPRITE_MOVIE, NULL); ret->sprite = SWFDEC_SPRITE (graphic); + *size = sizeof (SwfdecSpriteMovie); return SWFDEC_MOVIE (ret); } diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c index a114315..d4210f5 100644 --- a/libswfdec/swfdec_sprite_movie.c +++ b/libswfdec/swfdec_sprite_movie.c @@ -22,10 +22,10 @@ #endif #include "swfdec_sprite_movie.h" +#include "swfdec_as_object.h" #include "swfdec_audio_event.h" #include "swfdec_audio_stream.h" #include "swfdec_debug.h" -#include "swfdec_js.h" #include "swfdec_player_internal.h" #include "swfdec_ringbuffer.h" #include "swfdec_root_movie.h" @@ -66,7 +66,7 @@ swfdec_sprite_movie_remove_child (Swfdec static void swfdec_sprite_movie_run_script (gpointer movie, gpointer data) { - swfdec_script_execute (data, SWFDEC_SCRIPTABLE (movie)); + swfdec_as_object_run (movie, data); } static void diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c index 97f6965..bfe89db 100644 --- a/libswfdec/swfdec_swf_decoder.c +++ b/libswfdec/swfdec_swf_decoder.c @@ -34,7 +34,6 @@ #include "swfdec_bits.h" #include "swfdec_cached.h" #include "swfdec_debug.h" -#include "swfdec_js.h" #include "swfdec_player_internal.h" #include "swfdec_root_sprite.h" diff --git a/libswfdec/swfdec_video.c b/libswfdec/swfdec_video.c index a044606..86911e0 100644 --- a/libswfdec/swfdec_video.c +++ b/libswfdec/swfdec_video.c @@ -146,7 +146,7 @@ swfdec_video_input_new (SwfdecVideo *vid G_DEFINE_TYPE (SwfdecVideo, swfdec_video, SWFDEC_TYPE_GRAPHIC) static SwfdecMovie * -swfdec_video_create_movie (SwfdecGraphic *graphic) +swfdec_video_create_movie (SwfdecGraphic *graphic, gsize *size) { SwfdecVideo *video = SWFDEC_VIDEO (graphic); SwfdecVideoMovie *movie = g_object_new (SWFDEC_TYPE_VIDEO_MOVIE, NULL); @@ -156,6 +156,7 @@ swfdec_video_create_movie (SwfdecGraphic g_object_ref (graphic); if (input) swfdec_video_movie_set_input (movie, input); + *size = sizeof (SwfdecVideoMovie); return SWFDEC_MOVIE (movie); } diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c index cf74a92..ff1769f 100644 --- a/libswfdec/swfdec_video_movie.c +++ b/libswfdec/swfdec_video_movie.c @@ -94,18 +94,14 @@ swfdec_video_movie_iterate_end (SwfdecMo return TRUE; } -extern const JSClass video_class; static void swfdec_video_movie_class_init (SwfdecVideoMovieClass * g_class) { GObjectClass *object_class = G_OBJECT_CLASS (g_class); - SwfdecScriptableClass *scriptable_class = SWFDEC_SCRIPTABLE_CLASS (g_class); SwfdecMovieClass *movie_class = SWFDEC_MOVIE_CLASS (g_class); object_class->dispose = swfdec_video_movie_dispose; - scriptable_class->jsclass = &video_class; - movie_class->update_extents = swfdec_video_movie_update_extents; movie_class->render = swfdec_video_movie_render; movie_class->iterate_end = swfdec_video_movie_iterate_end; diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c index 366bf60..c931c6b 100644 --- a/libswfdec/swfdec_xml.c +++ b/libswfdec/swfdec_xml.c @@ -27,42 +27,27 @@ #include "swfdec_loader_internal.h" #include "swfdec_loadertarget.h" #include "swfdec_player_internal.h" -#include "js/jsapi.h" -#include "js/jsinterp.h" /*** SWFDEC_LOADER_TARGET ***/ static SwfdecPlayer * swfdec_xml_loader_target_get_player (SwfdecLoaderTarget *target) { - SwfdecXml *xml = SWFDEC_XML (target); - - return xml->player; + return SWFDEC_PLAYER (SWFDEC_AS_OBJECT (target)->context); } static void swfdec_xml_ondata (SwfdecXml *xml) { - JSContext *cx = SWFDEC_SCRIPTABLE (xml)->jscx; - JSObject *obj = SWFDEC_SCRIPTABLE (xml)->jsobj; - jsval val, fun; - JSString *string; + SwfdecAsValue val; - if (!JS_GetProperty (cx, obj, "onData", &fun)) - return; - if (fun == JSVAL_VOID) - return; if (xml->text) { - string = JS_NewStringCopyZ (cx, xml->text); - if (string == NULL) { - SWFDEC_ERROR ("Could not convert text to JS string"); - return; - } - val = STRING_TO_JSVAL (string); + SWFDEC_AS_VALUE_SET_STRING (&val, + swfdec_as_context_get_string (SWFDEC_AS_OBJECT (xml)->context, xml->text)); } else { - val = JSVAL_VOID; + SWFDEC_AS_VALUE_SET_UNDEFINED (&val); } - js_InternalCall (cx, obj, fun, 1, &val, &fun); + swfdec_as_object_call (SWFDEC_AS_OBJECT (xml), SWFDEC_AS_STR_ON_DATA, 1, &val); } static void @@ -119,7 +104,7 @@ swfdec_xml_loader_target_init (SwfdecLoa /*** SWFDEC_XML ***/ -G_DEFINE_TYPE_WITH_CODE (SwfdecXml, swfdec_xml, SWFDEC_TYPE_SCRIPTABLE, +G_DEFINE_TYPE_WITH_CODE (SwfdecXml, swfdec_xml, SWFDEC_TYPE_AS_OBJECT, G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_xml_loader_target_init)) static void @@ -143,16 +128,12 @@ swfdec_xml_dispose (GObject *object) G_OBJECT_CLASS (swfdec_xml_parent_class)->dispose (object); } -extern const JSClass xml_class; static void swfdec_xml_class_init (SwfdecXmlClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfdecScriptableClass *scriptable_class = SWFDEC_SCRIPTABLE_CLASS (klass); object_class->dispose = swfdec_xml_dispose; - - scriptable_class->jsclass = &xml_class; } static void @@ -160,19 +141,17 @@ swfdec_xml_init (SwfdecXml *xml) { } -SwfdecXml * -swfdec_xml_new (SwfdecPlayer *player) +SwfdecAsObject * +swfdec_xml_new (SwfdecAsContext *context) { - SwfdecXml *xml; - SwfdecScriptable *script; - - g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL); + SwfdecAsObject *xml; - xml= g_object_new (SWFDEC_TYPE_XML, NULL); - xml->player = player; + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); - script = SWFDEC_SCRIPTABLE (xml); - script->jscx = player->jscx; + if (!swfdec_as_context_use_mem (context, sizeof (SwfdecXml))) + return NULL; + xml = g_object_new (SWFDEC_TYPE_XML, NULL); + swfdec_as_object_add (xml, context, sizeof (SwfdecXml)); return xml; } @@ -184,7 +163,7 @@ swfdec_xml_load (SwfdecXml *xml, const c g_return_if_fail (url != NULL); swfdec_xml_reset (xml); - xml->loader = swfdec_player_load (xml->player, url); + xml->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (xml)->context), url); swfdec_loader_set_target (xml->loader, SWFDEC_LOADER_TARGET (xml)); swfdec_loader_queue_parse (xml->loader); } diff --git a/libswfdec/swfdec_xml.h b/libswfdec/swfdec_xml.h index b2b3ea8..77b355a 100644 --- a/libswfdec/swfdec_xml.h +++ b/libswfdec/swfdec_xml.h @@ -20,7 +20,8 @@ #ifndef _SWFDEC_XML_H_ #define _SWFDEC_XML_H_ -#include <libswfdec/swfdec_scriptable.h> +#include <libswfdec/swfdec.h> +#include <libswfdec/swfdec_as_object.h> G_BEGIN_DECLS @@ -36,23 +37,22 @@ typedef struct _SwfdecXmlClass SwfdecXml #define SWFDEC_XML_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_XML, SwfdecXmlClass)) struct _SwfdecXml { - SwfdecScriptable scriptable; + SwfdecAsObject object; char * text; /* string that this XML displays */ - SwfdecPlayer * player; /* player we're playing in */ SwfdecLoader * loader; /* loader when loading or NULL */ }; struct _SwfdecXmlClass { - SwfdecScriptableClass scriptable_class; + SwfdecAsObjectClass object_class; }; GType swfdec_xml_get_type (void); -SwfdecXml * swfdec_xml_new (SwfdecPlayer * player); +SwfdecAsObject *swfdec_xml_new (SwfdecAsContext * context); -void swfdec_xml_load (SwfdecXml * xml, - const char * url); +void swfdec_xml_load (SwfdecXml * xml, + const char * url); G_END_DECLS diff-tree 31b77da7d447857b2a0769833c11a06fe870586a (from parents) Merge: e9bda1999fcb67c54febb83a8bc1be75e62c60be 7495e883f55098c1b6cb22873cb6ac2bd99052e7 Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 10:33:42 2007 +0200 Merge branch 'master' into as diff-tree 7495e883f55098c1b6cb22873cb6ac2bd99052e7 (from 35b8ff9083919b168d2090d4ccf72aa5cec99538) Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 10:06:59 2007 +0200 get rid of the constant pool in swfdec_script_interpret, since we allocate it there diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 21c1fff..d8ce1ad 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -3022,6 +3022,10 @@ no_catch: /* Reset sp before freeing stack slots, because our caller may GC soon. */ fp->sp = fp->spbase; fp->spbase = NULL; + if (fp->constant_pool) { + swfdec_constant_pool_free (fp->constant_pool); + fp->constant_pool = NULL; + } js_FreeRawStack(cx, mark); cx->interpLevel--; swfdec_script_unref (script); @@ -3123,8 +3127,6 @@ swfdec_script_execute (SwfdecScript *scr ok = swfdec_script_interpret (script, cx, &frame.rval); js_FreeRawStack (cx, mark); - if (frame.constant_pool) - swfdec_constant_pool_free (frame.constant_pool); cx->fp = oldfp; if (oldfp) { diff-tree 35b8ff9083919b168d2090d4ccf72aa5cec99538 (from 23af06e2fcd39f80bd13b10ee02d57eb7b0e9aee) Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Thu Mar 22 19:58:07 2007 +0000 Free the glyph array along with the font. ==24359== 580 (260 direct, 320 indirect) bytes in 3 blocks are definitely lost in loss record 70 of 101 ==24359== at 0x4021620: malloc (vg_replace_malloc.c:149) ==24359== by 0x4E7BCB5: g_malloc (gmem.c:131) ==24359== by 0x4E8B887: g_slice_alloc (gslice.c:777) ==24359== by 0x4E56E38: g_array_sized_new (garray.c:94) ==24359== by 0x4E56F56: g_array_new (garray.c:86) ==24359== by 0x4044B2D: swfdec_font_init (swfdec_font.c:61) ==24359== by 0x4E35838: g_type_create_instance (gtype.c:1569) ==24359== by 0x4E1C901: g_object_constructor (gobject.c:1041) ==24359== by 0x4E1AC0A: g_object_newv (gobject.c:937) ==24359== by 0x4E1B74E: g_object_new_valist (gobject.c:981) ==24359== by 0x4E1B8FF: g_object_new (gobject.c:795) ==24359== by 0x406CE47: swfdec_swf_decoder_create_character (swfdec_swf_decoder.c:385) Slightly misleading as the leak resolution wasn't high enough to distinguish between g_slice_allocs. diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c index 6794e0f..1b032d8 100644 --- a/libswfdec/swfdec_font.c +++ b/libswfdec/swfdec_font.c @@ -37,14 +37,23 @@ swfdec_font_dispose (GObject *object) SwfdecFont * font = SWFDEC_FONT (object); guint i; - for (i = 0; i < font->glyphs->len; i++) { - g_object_unref (g_array_index (font->glyphs, SwfdecFontEntry, i).shape); + if (font->glyphs) { + for (i = 0; i < font->glyphs->len; i++) { + g_object_unref (g_array_index (font->glyphs, SwfdecFontEntry, i).shape); + } + g_array_free (font->glyphs, TRUE); + font->glyphs = NULL; } - if (font->desc) + if (font->desc) { pango_font_description_free (font->desc); - g_free (font->name); + font->desc = NULL; + } + if (font->name) { + g_free (font->name); + font->name = NULL; + } - G_OBJECT_CLASS (swfdec_font_parent_class)->dispose (G_OBJECT (font)); + G_OBJECT_CLASS (swfdec_font_parent_class)->dispose (object); } static void diff-tree 23af06e2fcd39f80bd13b10ee02d57eb7b0e9aee (from 9068d5785dee8a9575cbf88e8b8813a0a69d9d89) Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Tue Apr 3 09:44:35 2007 +0200 Unref the cached value when disposing the SwfdecCached. diff --git a/libswfdec/swfdec_cached.c b/libswfdec/swfdec_cached.c index aa6a694..b7216e6 100644 --- a/libswfdec/swfdec_cached.c +++ b/libswfdec/swfdec_cached.c @@ -32,7 +32,7 @@ swfdec_cached_dispose (GObject *object) { SwfdecCached * cached = SWFDEC_CACHED (object); - swfdec_cached_unload (cached); + swfdec_cached_set_cache (cached, NULL); G_OBJECT_CLASS (swfdec_cached_parent_class)->dispose (object); } @@ -54,7 +54,6 @@ void swfdec_cached_set_cache (SwfdecCached *cached, SwfdecCache *cache) { g_return_if_fail (SWFDEC_IS_CACHED (cached)); - g_return_if_fail (cache != NULL); if (cached->cache) { if (cached->handle.unload) diff-tree 9068d5785dee8a9575cbf88e8b8813a0a69d9d89 (from 079bedb48b51463f22ccd91ddf24a8a5a1f18618) Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Thu Mar 22 19:35:11 2007 +0000 Free the path data when disposing the morph shape. ==18759== 2,048 bytes in 2 blocks are definitely lost in loss record 83 of 101 ==18759== at 0x402171B: realloc (vg_replace_malloc.c:306) ==18759== by 0x4E7BB7A: g_realloc (gmem.c:168) ==18759== by 0x40664FA: swfdec_path_ensure_size (swfdec_shape.c:72) ==18759== by 0x4066B48: swfdec_path_append (swfdec_shape.c:128) ==18759== by 0x4066C29: swfdec_shape_accumulate_one_polygon (swfdec_shape.c:472) ==18759== by 0x4067159: swfdec_shape_accumulate_one_fill (swfdec_shape.c:529) ==18759== by 0x4067583: swfdec_shape_initialize_from_sub_paths (swfdec_shape.c:580) ==18759== by 0x40680B9: tag_define_morph_shape (swfdec_shape.c:995) ==18759== by 0x406D5C2: swfdec_swf_decoder_parse (swfdec_swf_decoder.c:298) ==18759== by 0x40507DE: swfdec_loader_target_parse_default (swfdec_loadertarget.c:109) ==18759== by 0x4050ADA: swfdec_loader_target_parse (swfdec_loadertarget.c:160) ==18759== by 0x404E858: swfdec_loader_parse (swfdec_loader.c:409) diff --git a/libswfdec/swfdec_morphshape.c b/libswfdec/swfdec_morphshape.c index 06e8a9d..623e790 100644 --- a/libswfdec/swfdec_morphshape.c +++ b/libswfdec/swfdec_morphshape.c @@ -52,9 +52,15 @@ swfdec_graphic_create_movie (SwfdecGraph static void swfdec_morph_shape_dispose (GObject *object) { - SwfdecMorphShape *shape = SWFDEC_MORPH_SHAPE (object); + SwfdecMorphShape *morph = SWFDEC_MORPH_SHAPE (object); + guint i; - g_array_free (shape->end_vecs, TRUE); + if (morph->end_vecs != NULL) { + for (i = 0; i < morph->end_vecs->len; i++) + g_free (g_array_index (morph->end_vecs, SwfdecShapeVec, i).path.data); + g_array_free (morph->end_vecs, TRUE); + morph->end_vecs = NULL; + } G_OBJECT_CLASS (swfdec_morph_shape_parent_class)->dispose (object); } diff-tree 079bedb48b51463f22ccd91ddf24a8a5a1f18618 (from 0598ab8797606c967fb2087d9cfffd4be175e432) Author: Chris Wilson <chris@chris-wilson.co.uk> Date: Tue Apr 3 09:38:33 2007 +0200 Fix minor leak of function_name. diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c index 0aff14c..21c1fff 100644 --- a/libswfdec/swfdec_script.c +++ b/libswfdec/swfdec_script.c @@ -1680,7 +1680,7 @@ swfdec_action_define_function (JSContext gboolean v2 = (action == 0x8e); swfdec_bits_init_data (&bits, data, len); - function_name = swfdec_bits_get_string (&bits); + function_name = swfdec_bits_skip_string (&bits); if (function_name == NULL) { SWFDEC_ERROR ("could not parse function name"); return JS_FALSE; diff-tree 0598ab8797606c967fb2087d9cfffd4be175e432 (from 06570fb5489008d491213428b25be15716f6e448) Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 09:16:30 2007 +0200 fix a leak which caused whole videos to be leaked You notice 5MB per leak at some point... diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c index 681e401..b0bcd4d 100644 --- a/libswfdec/swfdec_net_stream.c +++ b/libswfdec/swfdec_net_stream.c @@ -395,6 +395,7 @@ swfdec_net_stream_set_url (SwfdecNetStre /* FIXME: use the connection once connections are implemented */ loader = swfdec_player_load (stream->player, url); swfdec_net_stream_set_loader (stream, loader); + g_object_unref (loader); } void diff-tree 06570fb5489008d491213428b25be15716f6e448 (from c9974a9671427543b289eb19eb556d4b890aa8c1) Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 09:03:14 2007 +0200 fix a memleak diff --git a/libswfdec/swfdec_video.c b/libswfdec/swfdec_video.c index f163ffd..a044606 100644 --- a/libswfdec/swfdec_video.c +++ b/libswfdec/swfdec_video.c @@ -119,16 +119,19 @@ swfdec_video_input_disconnect (SwfdecVid static SwfdecVideoMovieInput * swfdec_video_input_new (SwfdecVideo *video) { - SwfdecVideoInput *input = g_new0 (SwfdecVideoInput, 1); - + SwfdecVideoInput *input; + if (video->n_frames == 0) return NULL; if (video->codec == NULL) return NULL; + input = g_new0 (SwfdecVideoInput, 1); if (video->codec) input->decoder = swfdec_video_codec_init (video->codec); - if (input->decoder == NULL) + if (input->decoder == NULL) { + g_free (input); return NULL; + } input->input.connect = swfdec_video_input_connect; input->input.iterate = swfdec_video_input_iterate; input->input.disconnect = swfdec_video_input_disconnect; diff-tree c9974a9671427543b289eb19eb556d4b890aa8c1 (from 2bd12763b607d0729b0c97b7900599220d4f479c) Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 09:01:47 2007 +0200 include the file name in error messages diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c index 643fb3e..4b1e57f 100644 --- a/libswfdec-gtk/swfdec_gtk_loader.c +++ b/libswfdec-gtk/swfdec_gtk_loader.c @@ -105,7 +105,10 @@ swfdec_gtk_loader_read_cb (GnomeVFSAsync gtk->handle = NULL; return; } else if (result != GNOME_VFS_OK) { - swfdec_loader_error (loader, gnome_vfs_result_to_string (result)); + char *err = g_strdup_printf ("%s: %s", loader->url, + gnome_vfs_result_to_string (result)); + swfdec_loader_error (loader, err); + g_free (err); swfdec_buffer_unref (gtk->current_buffer); gtk->current_buffer = NULL; gnome_vfs_async_cancel (gtk->handle); @@ -141,7 +144,10 @@ swfdec_gtk_loader_open_cb (GnomeVFSAsync SwfdecLoader *loader = loaderp; if (result != GNOME_VFS_OK) { - swfdec_loader_error (loader, gnome_vfs_result_to_string (result)); + char *err = g_strdup_printf ("%s: %s", loader->url, + gnome_vfs_result_to_string (result)); + swfdec_loader_error (loader, err); + g_free (err); gnome_vfs_async_cancel (gtk->handle); gtk->handle = NULL; return; diff-tree 2bd12763b607d0729b0c97b7900599220d4f479c (from b3030fd82079172d16451d6c265077cc21a60802) Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 09:01:23 2007 +0200 Do not ref the player anymore Using a refcount was a good idea when SwfdecSource was seperate. Now it's used from the player itself, so it'll get into a refcount loop. We use weak references instead, so it's theoretically possible to use the source outside of a player. It'll remove itself when the player goes away. diff --git a/libswfdec-gtk/swfdec_source.c b/libswfdec-gtk/swfdec_source.c index f001de3..10d0f0e 100644 --- a/libswfdec-gtk/swfdec_source.c +++ b/libswfdec-gtk/swfdec_source.c @@ -34,7 +34,7 @@ my_time_val_difference (const GTimeVal * typedef struct _SwfdecIterateSource SwfdecIterateSource; struct _SwfdecIterateSource { GSource source; - SwfdecPlayer * player; + SwfdecPlayer * player; /* player we manage or NULL if player was deleted */ double speed; /* inverse playback speed (so 0.5 means double speed) */ gulong notify; /* set for iterate notifications */ GTimeVal last; /* last time */ @@ -47,6 +47,7 @@ swfdec_iterate_get_msecs_to_next_event ( GTimeVal now; glong diff; + g_assert (source->player); diff = swfdec_player_get_next_event (source->player); if (diff == 0) return G_MAXLONG; @@ -62,7 +63,13 @@ swfdec_iterate_get_msecs_to_next_event ( static gboolean swfdec_iterate_prepare (GSource *source, gint *timeout) { - glong diff = swfdec_iterate_get_msecs_to_next_event (source); + glong diff; + + diff = swfdec_iterate_get_msecs_to_next_event (source); + if (((SwfdecIterateSource *) source)->player == NULL) { + *timeout = 0; + return TRUE; + } if (diff == G_MAXLONG) { *timeout = -1; @@ -79,8 +86,11 @@ swfdec_iterate_prepare (GSource *source, static gboolean swfdec_iterate_check (GSource *source) { - glong diff = swfdec_iterate_get_msecs_to_next_event (source); - + glong diff; + + if (((SwfdecIterateSource *) source)->player == NULL) + return 0; + diff = swfdec_iterate_get_msecs_to_next_event (source); return diff < 0; } @@ -88,8 +98,11 @@ static gboolean swfdec_iterate_dispatch (GSource *source_, GSourceFunc callback, gpointer user_data) { SwfdecIterateSource *source = (SwfdecIterateSource *) source_; - glong diff = swfdec_iterate_get_msecs_to_next_event (source_); - + glong diff; + + if (source->player == NULL) + return FALSE; + diff = swfdec_iterate_get_msecs_to_next_event (source_); if (diff > 0) return TRUE; diff = swfdec_player_get_next_event (source->player) - diff; @@ -105,7 +118,9 @@ swfdec_iterate_finalize (GSource *source if (source->notify) { g_signal_handler_disconnect (source->player, source->notify); } - g_object_unref (source->player); + if (source->player) { + g_object_remove_weak_pointer (G_OBJECT (source->player), (gpointer *) &source->player); + } } GSourceFuncs swfdec_iterate_funcs = { @@ -132,7 +147,8 @@ swfdec_iterate_source_new (SwfdecPlayer source = (SwfdecIterateSource *) g_source_new (&swfdec_iterate_funcs, sizeof (SwfdecIterateSource)); - source->player = g_object_ref (player); + source->player = player; + g_object_add_weak_pointer (G_OBJECT (source->player), (gpointer *) &source->player); source->speed = 1.0 / speed; source->notify = g_signal_connect (player, "advance", G_CALLBACK (swfdec_iterate_source_advance_cb), source); diff-tree b3030fd82079172d16451d6c265077cc21a60802 (from ea7b64b68489721b867fef1edf55c809de2e2b8a) Author: Benjamin Otte <otte@gnome.org> Date: Tue Apr 3 09:00:34 2007 +0200 Do not ref the player anymore Using a refcount was a good idea when SwfdecPlayback was seperate. Now it's used from the player itself, so it'll get into a refcount loop. diff --git a/libswfdec-gtk/swfdec_playback_alsa.c b/libswfdec-gtk/swfdec_playback_alsa.c index b6a2f1a..ee4da3e 100644 --- a/libswfdec-gtk/swfdec_playback_alsa.c +++ b/libswfdec-gtk/swfdec_playback_alsa.c @@ -318,7 +318,7 @@ swfdec_playback_open (SwfdecPlayer *play g_return_val_if_fail (context != NULL, NULL); sound = g_new0 (SwfdecPlayback, 1); - sound->player = g_object_ref (player); + sound->player = player; g_signal_connect (player, "advance", G_CALLBACK (advance_before), sound); g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), sound); g_signal_connect (player, "audio-removed", G_CALLBACK (audio_removed), sound); @@ -346,7 +346,6 @@ swfdec_playback_close (SwfdecPlayback *s REMOVE_HANDLER (sound->player, advance_before, sound); REMOVE_HANDLER (sound->player, audio_added, sound); REMOVE_HANDLER (sound->player, audio_removed, sound); - g_object_unref (sound->player); g_main_context_unref (sound->context); g_free (sound); } diff-tree ea7b64b68489721b867fef1edf55c809de2e2b8a (from cba7ba2518e522d3f695d41a7f4c8dc4d1d19da8) Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 2 17:38:29 2007 +0200 this debugging message is not that important diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c index 99363f9..681e401 100644 --- a/libswfdec/swfdec_net_stream.c +++ b/libswfdec/swfdec_net_stream.c @@ -225,7 +225,7 @@ swfdec_net_stream_loader_target_parse (S return; } if (!loader->eof && swfdec_buffer_queue_get_depth (loader->queue) == 0) { - SWFDEC_WARNING ("nothing to parse?!"); + SWFDEC_INFO ("nothing to do"); return; } if (stream->flvdecoder == NULL) { diff-tree cba7ba2518e522d3f695d41a7f4c8dc4d1d19da8 (from 7d592c21a8605361c3e63aca138f3e359cdbab50) Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 2 13:28:39 2007 +0200 update docs diff --git a/configure.ac b/configure.ac index 3550a5c..fdf2a31 100644 --- a/configure.ac +++ b/configure.ac @@ -226,13 +226,13 @@ AM_CONDITIONAL(HAVE_GNOMEVFS, [test "x$H AC_SUBST(GLOBAL_CFLAGS) AC_SUBST(GLOBAL_CFLAGS) -SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS" -SWFDEC_LIBS="\$(top_builddir)/libswfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS -lz" +SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS $CAIRO_CFLAGS" +SWFDEC_LIBS="\$(top_builddir)/libswfdec/libswfdec-$SWFDEC_MAJORMINOR.la $GLIB_LIBS $CAIRO_LIBS -lz" AC_SUBST(SWFDEC_LIBS) AC_SUBST(SWFDEC_CFLAGS) -SWFDEC_GTK_CFLAGS="$SWFDEC_CFLAGS" -SWFDEC_GTK_LIBS="\$(top_builddir)/libswfdec-gtk/libswfdec-gtk-$SWFDEC_MAJORMINOR.la $SWFDEC_LIBS" +SWFDEC_GTK_CFLAGS="$SWFDEC_CFLAGS $GTK_CFLAGS" +SWFDEC_GTK_LIBS="\$(top_builddir)/libswfdec-gtk/libswfdec-gtk-$SWFDEC_MAJORMINOR.la $SWFDEC_LIBS $GTK_LIBS" AC_SUBST(SWFDEC_GTK_LIBS) AC_SUBST(SWFDEC_GTK_CFLAGS) diff --git a/doc/Makefile.am b/doc/Makefile.am index 0b037de..4855ce8 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -109,6 +109,7 @@ IGNORE_HFILES= \ swfdec_xml.h EXTRA_HFILES = \ + ../libswfdec-gtk/swfdec_gtk_loader.h \ ../libswfdec-gtk/swfdec_gtk_player.h \ ../libswfdec-gtk/swfdec_gtk_widget.h @@ -131,7 +132,7 @@ expand_content_files # e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) # e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) INCLUDES=$(SWFDEC_GTK_CFLAGS) $(CAIRO_CFLAGS) -GTKDOC_LIBS=$(SWFDEC_GTK_LIBS) +GTKDOC_LIBS=$(SWFDEC_GTK_LIBS) # This includes the standard gtk-doc make rules, copied by gtkdocize. include $(top_srcdir)/gtk-doc.make diff --git a/doc/swfdec-docs.sgml b/doc/swfdec-docs.sgml index e5b1d71..aa1c339 100644 --- a/doc/swfdec-docs.sgml +++ b/doc/swfdec-docs.sgml @@ -10,6 +10,7 @@ <title>Swfdec Gtk library</title> <xi:include href="xml/SwfdecGtkPlayer.xml"/> <xi:include href="xml/SwfdecGtkWidget.xml"/> + <xi:include href="xml/SwfdecGtkLoader.xml"/> </chapter> <chapter> <title>Swfdec library</title> diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt index 3d270af..e0454c7 100644 --- a/doc/swfdec-sections.txt +++ b/doc/swfdec-sections.txt @@ -118,7 +118,7 @@ swfdec_mouse_cursor_get_type <TITLE>SwfdecGtkPlayer</TITLE> SwfdecGtkPlayer swfdec_gtk_player_new -swfdec_gtk_player_new_from_file +swfdec_gtk_player_new_from_uri swfdec_gtk_player_get_playing swfdec_gtk_player_set_playing swfdec_gtk_player_get_speed @@ -162,3 +162,19 @@ SWFDEC_IS_GTK_WIDGET SWFDEC_IS_GTK_WIDGET_CLASS SWFDEC_TYPE_GTK_WIDGET </SECTION> + +<SECTION> +<FILE>SwfdecGtkLoader</FILE> +<TITLE>SwfdecGtkLoader</TITLE> +SwfdecGtkLoader +swfdec_gtk_loader_new +<SUBSECTION Standard> +swfdec_gtk_loader_get_type +SwfdecGtkLoaderClass +SWFDEC_GTK_LOADER +SWFDEC_GTK_LOADER_CLASS +SWFDEC_GTK_LOADER_GET_CLASS +SWFDEC_IS_GTK_LOADER +SWFDEC_IS_GTK_LOADER_CLASS +SWFDEC_TYPE_GTK_LOADER +</SECTION> diff --git a/doc/swfdec.types b/doc/swfdec.types index dbd39e4..9b70671 100644 --- a/doc/swfdec.types +++ b/doc/swfdec.types @@ -1,8 +1,10 @@ #include <libswfdec/swfdec.h> +#include <libswfdec-gtk/swfdec-gtk.h> swfdec_player_get_type swfdec_audio_get_type swfdec_loader_get_type +swfdec_gtk_loader_get_type swfdec_gtk_player_get_type swfdec_gtk_widget_get_type diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c index 9267e86..643fb3e 100644 --- a/libswfdec-gtk/swfdec_gtk_loader.c +++ b/libswfdec-gtk/swfdec_gtk_loader.c @@ -23,6 +23,28 @@ #include "swfdec_gtk_loader.h" +/*** GTK-DOC ***/ + +/** + * SECTION:SwfdecGtkLoader + * @title: SwfdecGtkLoader + * @short_description: advanced loader able to load network ressources + * @see_also: #SwfdecLoader + * + * #SwfdecGtkLoader is a #SwfdecLoader that is intended as an easy way to be + * access ressources that are not stored in files, such as http. It can + * however be compiled with varying support for different protocols, so don't + * rely on support for a particular protocol being available. If you need this, + * code your own SwfdecLoader subclass. + */ + +/** + * SwfdecGtkLoader: + * + * This is the object used to represent a loader. Since it may use varying + * backends, it is completely private. + */ + #ifndef HAVE_GNOMEVFS #include <libswfdec/swfdec_loader_internal.h> diff-tree 7d592c21a8605361c3e63aca138f3e359cdbab50 (from parents) Merge: a7488cbdfbdc0e33215e8e401c4199c143fa88d6 f516f0186bef8f00810f200034d63776bfab9271 Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 2 12:41:14 2007 +0200 Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec diff-tree a7488cbdfbdc0e33215e8e401c4199c143fa88d6 (from a6d61c0101f96f031463545c96383b3ebfeafe63) Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 2 12:36:58 2007 +0200 Add a loader that loads other stuff than files (in particular http) It's currently using gnome-vfs but gnome-vfs somehow doesn't like to give me the file size. So I'll most likely switch to something else soon. diff --git a/configure.ac b/configure.ac index 65be1fc..aef0a9a 100644 --- a/configure.ac +++ b/configure.ac @@ -204,6 +204,25 @@ else fi AM_CONDITIONAL(HAVE_FFMPEG, [test "x$HAVE_FFMPEG" = xyes]) +AC_ARG_ENABLE(gnome-vfs, + AS_HELP_STRING([--enable-gnome-vfs], + [enable gnome-vfs support for swfdec-gtk (default=yes)])], + enable_gnomevfs=$enableval, + enable_gnomevfs="yes") + +if test "$enable_gnomevfs" = "yes"; then + PKG_CHECK_MODULES(GNOMEVFS, gnome-vfs-2.0 >= 2.14.0, HAVE_GNOMEVFS=yes, HAVE_GNOMEVFS=no) + if test "x$HAVE_GNOMEVFS" = xyes; then + AC_DEFINE(HAVE_GNOMEVFS, 1, [Define if gnome-vfs is enabled]) + else + AC_MSG_ERROR([Couldn't find gnome-vfs-2.0.]) + fi +else + AC_MSG_WARN([*** gnome-vfs support was not enabled. ***]) +fi +AM_CONDITIONAL(HAVE_GNOMEVFS, [test "x$HAVE_GNOMEVFS" = xyes]) + +AC_SUBST(GLOBAL_CFLAGS) AC_SUBST(GLOBAL_CFLAGS) SWFDEC_CFLAGS="-I\$(top_srcdir) $GLIB_CFLAGS" diff --git a/libswfdec-gtk/Makefile.am b/libswfdec-gtk/Makefile.am index eb16f88..b2dfb72 100644 --- a/libswfdec-gtk/Makefile.am +++ b/libswfdec-gtk/Makefile.am @@ -13,6 +13,7 @@ lib_LTLIBRARIES = libswfdec-gtk-@SWFDEC_ libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_SOURCES = \ swfdec_playback.c \ swfdec_source.c \ + swfdec_gtk_loader.c \ swfdec_gtk_player.c \ swfdec_gtk_widget.c @@ -21,15 +22,16 @@ noinst_HEADERS = \ swfdec_source.h libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_CFLAGS = \ - $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) $(AUDIO_CFLAGS) \ + $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS) $(AUDIO_CFLAGS) $(GNOMEVFS_CFLAGS) \ -DG_LOG_DOMAIN=\"Swfdec-Gtk\" -DXP_UNIX libswfdec_gtk_@SWFDEC_MAJORMINOR@_la_LDFLAGS = \ -version-info $(SWFDEC_LIBVERSION) \ -export-symbols-regex '^(swfdec_.*)' \ - $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) + $(GTK_LIBS) $(SWFDEC_LIBS) $(AUDIO_LIBS) $(GNOMEVFS_LIBS) libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINOR@/libswfdec-gtk libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = \ swfdec-gtk.h \ + swfdec_gtk_loader.h \ swfdec_gtk_player.h \ swfdec_gtk_widget.h diff --git a/libswfdec-gtk/swfdec-gtk.h b/libswfdec-gtk/swfdec-gtk.h index c9a0ac8..5615fa0 100644 --- a/libswfdec-gtk/swfdec-gtk.h +++ b/libswfdec-gtk/swfdec-gtk.h @@ -20,6 +20,7 @@ #ifndef __SWFDEC_GTK_H__ #define __SWFDEC_GTK_H__ +#include <libswfdec-gtk/swfdec_gtk_loader.h> #include <libswfdec-gtk/swfdec_gtk_player.h> #include <libswfdec-gtk/swfdec_gtk_widget.h> diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c new file mode 100644 index 0000000..9267e86 --- /dev/null +++ b/libswfdec-gtk/swfdec_gtk_loader.c @@ -0,0 +1,215 @@ +/* Swfdec + * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "swfdec_gtk_loader.h" + +#ifndef HAVE_GNOMEVFS + +#include <libswfdec/swfdec_loader_internal.h> + +GType +swfdec_gtk_loader_get_type (void) +{ + return SWFDEC_TYPE_FILE_LOADER; +} + +SwfdecLoader * +swfdec_gtk_loader_new (const char *uri) +{ + g_return_val_if_fail (uri != NULL, NULL); + + return swfdec_loader_new_from_file (uri); +} + + +#else /* HAVE_GNOMEVFS */ + +/* size of buffer we read */ +#define BUFFER_SIZE 4096 + +#include <libgnomevfs/gnome-vfs.h> + +struct _SwfdecGtkLoader +{ + SwfdecLoader loader; + + GnomeVFSURI * guri; /* GnomeVFS URI used for resolving */ + GnomeVFSAsyncHandle * handle; /* handle to file or NULL when done */ + SwfdecBuffer * current_buffer; /* current buffer we're reading into */ +}; + +struct _SwfdecGtkLoaderClass { + SwfdecLoaderClass loader_class; +}; + +/*** SwfdecGtkLoader ***/ + +G_DEFINE_TYPE (SwfdecGtkLoader, swfdec_gtk_loader, SWFDEC_TYPE_LOADER) + +static void swfdec_gtk_loader_start_read (SwfdecGtkLoader *gtk); +static void +swfdec_gtk_loader_read_cb (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, + gpointer buffer, GnomeVFSFileSize bytes_requested, GnomeVFSFileSize bytes_read, + gpointer loaderp) +{ + SwfdecGtkLoader *gtk = loaderp; + SwfdecLoader *loader = loaderp; + + if (result == GNOME_VFS_ERROR_EOF) { + swfdec_loader_eof (loader); + swfdec_buffer_unref (gtk->current_buffer); + gtk->current_buffer = NULL; + gnome_vfs_async_cancel (gtk->handle); + gtk->handle = NULL; + return; + } else if (result != GNOME_VFS_OK) { + swfdec_loader_error (loader, gnome_vfs_result_to_string (result)); + swfdec_buffer_unref (gtk->current_buffer); + gtk->current_buffer = NULL; + gnome_vfs_async_cancel (gtk->handle); + gtk->handle = NULL; + return; + } + if (bytes_read) { + gtk->current_buffer->length = bytes_read; + swfdec_loader_push (loader, gtk->current_buffer); + } else { + swfdec_buffer_unref (gtk->current_buffer); + } + gtk->current_buffer = NULL; + swfdec_gtk_loader_start_read (gtk); +} + +static void +swfdec_gtk_loader_start_read (SwfdecGtkLoader *gtk) +{ + g_assert (gtk->current_buffer == NULL); + g_assert (gtk->handle != NULL); + + gtk->current_buffer = swfdec_buffer_new_and_alloc (BUFFER_SIZE); + gnome_vfs_async_read (gtk->handle, gtk->current_buffer->data, + gtk->current_buffer->length, swfdec_gtk_loader_read_cb, gtk); +} + +static void +swfdec_gtk_loader_open_cb (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, + gpointer loaderp) +{ + SwfdecGtkLoader *gtk = loaderp; + SwfdecLoader *loader = loaderp; + + if (result != GNOME_VFS_OK) { + swfdec_loader_error (loader, gnome_vfs_result_to_string (result)); + gnome_vfs_async_cancel (gtk->handle); + gtk->handle = NULL; + return; + } + swfdec_gtk_loader_start_read (gtk); +} + +static SwfdecLoader * +swfdec_gtk_loader_new_from_uri (GnomeVFSURI *uri) +{ + SwfdecGtkLoader *gtk; + + g_assert (uri); + gtk = g_object_new (SWFDEC_TYPE_GTK_LOADER, NULL); + gtk->guri = uri; + gnome_vfs_async_open_uri (>k->handle, uri, GNOME_VFS_OPEN_READ, + GNOME_VFS_PRIORITY_DEFAULT, swfdec_gtk_loader_open_cb, gtk); + SWFDEC_LOADER (gtk)->url = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD); + return SWFDEC_LOADER (gtk); +} + +static void +swfdec_gtk_loader_dispose (GObject *object) +{ + SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (object); + + if (gtk->current_buffer) { + swfdec_buffer_unref (gtk->current_buffer); + gtk->current_buffer = NULL; + } + if (gtk->handle) { + gnome_vfs_async_cancel (gtk->handle); + gtk->handle = NULL; + } + if (gtk->guri) { + gnome_vfs_uri_unref (gtk->guri); + gtk->guri = NULL; + } + + G_OBJECT_CLASS (swfdec_gtk_loader_parent_class)->dispose (object); +} + +static SwfdecLoader * +swfdec_gtk_loader_load (SwfdecLoader *loader, const char *url) +{ + SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (loader); + GnomeVFSURI *parent, *new; + + /* FIXME: security! */ + parent = gnome_vfs_uri_get_parent (gtk->guri); + new = gnome_vfs_uri_resolve_relative (parent, url); + gnome_vfs_uri_unref (parent); + return swfdec_gtk_loader_new_from_uri (new); +} + +static void +swfdec_gtk_loader_class_init (SwfdecGtkLoaderClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfdecLoaderClass *loader_class = SWFDEC_LOADER_CLASS (klass); + + object_class->dispose = swfdec_gtk_loader_dispose; + + loader_class->load = swfdec_gtk_loader_load; +} + +static void +swfdec_gtk_loader_init (SwfdecGtkLoader *gtk_loader) +{ +} + +/** + * swfdec_gtk_loader_new: + * @uri: The location of the file to open + * + * Creates a new loader for the given URI using gnome-vfs (or using the local + * file backend, if compiled without gnome-vfs support). + * + * Returns: a new #SwfdecLoader using gnome-vfs. + **/ +SwfdecLoader * +swfdec_gtk_loader_new (const char *uri) +{ + GnomeVFSURI *guri; + + g_return_val_if_fail (uri != NULL, NULL); + + gnome_vfs_init (); + guri = gnome_vfs_uri_new (uri); + return swfdec_gtk_loader_new_from_uri (guri); +} + +#endif /* HAVE_GNOMEVFS */ diff --git a/libswfdec-gtk/swfdec_gtk_loader.h b/libswfdec-gtk/swfdec_gtk_loader.h new file mode 100644 index 0000000..09a3558 --- /dev/null +++ b/libswfdec-gtk/swfdec_gtk_loader.h @@ -0,0 +1,44 @@ +/* Swfdec + * Copyright (C) 2006 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef _SWFDEC_GTK_LOADER_H_ +#define _SWFDEC_GTK_LOADER_H_ + +#include <libswfdec/swfdec.h> + +G_BEGIN_DECLS + + +typedef struct _SwfdecGtkLoader SwfdecGtkLoader; +typedef struct _SwfdecGtkLoaderClass SwfdecGtkLoaderClass; + +#define SWFDEC_TYPE_GTK_LOADER (swfdec_gtk_loader_get_type()) +#define SWFDEC_IS_GTK_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_GTK_LOADER)) +#define SWFDEC_IS_GTK_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_GTK_LOADER)) +#define SWFDEC_GTK_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_GTK_LOADER, SwfdecGtkLoader)) +#define SWFDEC_GTK_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_GTK_LOADER, SwfdecGtkLoaderClass)) +#define SWFDEC_GTK_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_GTK_LOADER, SwfdecGtkLoaderClass)) + +GType swfdec_gtk_loader_get_type (void); + +SwfdecLoader * swfdec_gtk_loader_new (const char * uri); + + +G_END_DECLS +#endif diff --git a/libswfdec-gtk/swfdec_gtk_player.c b/libswfdec-gtk/swfdec_gtk_player.c index 58edd40..06a71c5 100644 --- a/libswfdec-gtk/swfdec_gtk_player.c +++ b/libswfdec-gtk/swfdec_gtk_player.c @@ -22,6 +22,7 @@ #endif #include <libswfdec/swfdec_player_internal.h> +#include "libswfdec-gtk/swfdec_gtk_loader.h" #include "libswfdec-gtk/swfdec_gtk_player.h" #include "libswfdec-gtk/swfdec_playback.h" #include "libswfdec-gtk/swfdec_source.h" @@ -190,14 +191,14 @@ swfdec_gtk_player_new (void) * Returns: a new player. **/ SwfdecPlayer * -swfdec_gtk_player_new_from_file (const char *uri) +swfdec_gtk_player_new_from_uri (const char *uri) { SwfdecLoader *loader; SwfdecPlayer *player; g_return_val_if_fail (uri != NULL, NULL); - loader = swfdec_loader_new_new_from_file (uri); + loader = swfdec_gtk_loader_new (uri); player = swfdec_gtk_player_new (); swfdec_player_set_loader (player, loader); diff --git a/libswfdec-gtk/swfdec_gtk_player.h b/libswfdec-gtk/swfdec_gtk_player.h index 50bce84..b040fe9 100644 --- a/libswfdec-gtk/swfdec_gtk_player.h +++ b/libswfdec-gtk/swfdec_gtk_player.h @@ -37,14 +37,16 @@ typedef struct _SwfdecGtkPlayerClass Swf GType swfdec_gtk_player_get_type (void); SwfdecPlayer * swfdec_gtk_player_new (void); -SwfdecPlayer * swfdec_gtk_player_new_from_file (const char * filename); +SwfdecPlayer * swfdec_gtk_player_new_from_uri (const char * uri); void swfdec_gtk_player_set_playing (SwfdecGtkPlayer * player, gboolean playing); gboolean swfdec_gtk_player_get_playing (SwfdecGtkPlayer * player); -void swfdec_gtk_player_set_audio_enabled (SwfdecGtkPlayer * player, +void swfdec_gtk_player_set_audio_enabled + (SwfdecGtkPlayer * player, gboolean enabled); -gboolean swfdec_gtk_player_get_audio_enabled (SwfdecGtkPlayer * player); +gboolean swfdec_gtk_player_get_audio_enabled + (SwfdecGtkPlayer * player); void swfdec_gtk_player_set_speed (SwfdecGtkPlayer * player, double speed); double swfdec_gtk_player_get_speed (SwfdecGtkPlayer * player); diff-tree a6d61c0101f96f031463545c96383b3ebfeafe63 (from 493905baa1c07054276adb078f086e7ca4acc26b) Author: Benjamin Otte <otte@gnome.org> Date: Mon Apr 2 12:04:05 2007 +0200 Change the semantics of swfdec_loader_new_from_file This function will now always return a loader (no NULL with error anymore), but will set the loader's error property instead. diff --git a/libswfdec-gtk/swfdec_gtk_player.c b/libswfdec-gtk/swfdec_gtk_player.c index 766f92d..58edd40 100644 --- a/libswfdec-gtk/swfdec_gtk_player.c +++ b/libswfdec-gtk/swfdec_gtk_player.c @@ -177,27 +177,27 @@ swfdec_gtk_player_new (void) } /** - * swfdec_gtk_player_new_from_file: - * @filename: name of the file to play - * @error: return location for error or %NULL + * swfdec_gtk_player_new_from_uri: + * @uri: URI to play * - * Tries to create a player to play back the given file. If the file does not - * exist or another error occurs, %NULL is returned. + * Create a player to play back the given URI. If compiled with gnome-vfs + * support, it will use gnome-vfs to resolve the given URI. Note that there + * is no way to figure out if the referenced URI really references a file that + * Swfdec can play back. If you need this, you should use #SwfdecGtkLoader + * directly and use its error property. * This function calls swfdec_init () for you if it wasn't called before. * - * Returns: a new player or %NULL on error. + * Returns: a new player. **/ SwfdecPlayer * -swfdec_gtk_player_new_from_file (const char *filename, GError **error) +swfdec_gtk_player_new_from_file (const char *uri) { SwfdecLoader *loader; SwfdecPlayer *player; - g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); - loader = swfdec_loader_new_from_file (filename, error); - if (loader == NULL) - return NULL; + loader = swfdec_loader_new_new_from_file (uri); player = swfdec_gtk_player_new (); swfdec_player_set_loader (player, loader); diff --git a/libswfdec-gtk/swfdec_gtk_player.h b/libswfdec-gtk/swfdec_gtk_player.h index 715259b..50bce84 100644 --- a/libswfdec-gtk/swfdec_gtk_player.h +++ b/libswfdec-gtk/swfdec_gtk_player.h @@ -37,8 +37,7 @@ typedef struct _SwfdecGtkPlayerClass Swf GType swfdec_gtk_player_get_type (void); SwfdecPlayer * swfdec_gtk_player_new (void); -SwfdecPlayer * swfdec_gtk_player_new_from_file (const char * filename, - GError ** error); +SwfdecPlayer * swfdec_gtk_player_new_from_file (const char * filename); void swfdec_gtk_player_set_playing (SwfdecGtkPlayer * player, gboolean playing); diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c index 81d536c..35a74c7 100644 --- a/libswfdec/swfdec_loader.c +++ b/libswfdec/swfdec_loader.c @@ -181,28 +181,6 @@ swfdec_loader_init (SwfdecLoader *loader /*** SwfdecFileLoader ***/ -typedef struct _SwfdecFileLoader SwfdecFileLoader; -typedef struct _SwfdecFileLoaderClass SwfdecFileLoaderClass; - -#define SWFDEC_TYPE_FILE_LOADER (swfdec_file_loader_get_type()) -#define SWFDEC_IS_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_FILE_LOADER)) -#define SWFDEC_IS_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_FILE_LOADER)) -#define SWFDEC_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoader)) -#define SWFDEC_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoaderClass)) -#define SWFDEC_FILE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoaderClass)) - -struct _SwfdecFileLoader -{ - SwfdecLoader loader; - - char * dir; /* base directory for load operations */ -}; - -struct _SwfdecFileLoaderClass -{ - SwfdecLoaderClass loader_class; -}; - G_DEFINE_TYPE (SwfdecFileLoader, swfdec_file_loader, SWFDEC_TYPE_LOADER) static void @@ -316,23 +294,22 @@ swfdec_loader_queue_parse (SwfdecLoader /** * swfdec_loader_new_from_file: * @filename: name of the file to load - * @error: return loacation for an error or NULL * - * Creates a new loader for local files. + * Creates a new loader for local files. If an error occurred, the loader will + * be in error. * - * Returns: a new loader on success or NULL on failure + * Returns: a new loader **/ SwfdecLoader * -swfdec_loader_new_from_file (const char *filename, GError ** error) +swfdec_loader_new_from_file (const char *filename) { SwfdecBuffer *buf; SwfdecLoader *loader; + GError *error = NULL; g_return_val_if_fail (filename != NULL, NULL); - buf = swfdec_buffer_new_from_file (filename, error); - if (buf == NULL) - return NULL; + buf = swfdec_buffer_new_from_file (filename, &error); loader = g_object_new (SWFDEC_TYPE_FILE_LOADER, NULL); if (g_path_is_absolute (filename)) { @@ -343,9 +320,14 @@ swfdec_loader_new_from_file (const char g_free (cur); } SWFDEC_FILE_LOADER (loader)->dir = g_path_get_dirname (loader->url); - swfdec_loader_set_size (loader, buf->length); - swfdec_loader_push (loader, buf); - swfdec_loader_eof (loader); + if (buf == NULL) { + swfdec_loader_error (loader, error->message); + g_error_free (error); + } else { + swfdec_loader_set_size (loader, buf->length); + swfdec_loader_push (loader, buf); + swfdec_loader_eof (loader); + } return loader; } diff --git a/libswfdec/swfdec_loader.h b/libswfdec/swfdec_loader.h index 482c810..b64c9a4 100644 --- a/libswfdec/swfdec_loader.h +++ b/libswfdec/swfdec_loader.h @@ -68,8 +68,7 @@ struct _SwfdecLoaderClass GType swfdec_loader_get_type (void); -SwfdecLoader * swfdec_loader_new_from_file (const char * filename, - GError ** error); +SwfdecLoader * swfdec_loader_new_from_file (const char * filename); void swfdec_loader_push (SwfdecLoader * loader, SwfdecBuffer * buffer); diff --git a/libswfdec/swfdec_loader_internal.h b/libswfdec/swfdec_loader_internal.h index d47a1ed..303088a 100644 --- a/libswfdec/swfdec_loader_internal.h +++ b/libswfdec/swfdec_loader_internal.h @@ -25,6 +25,28 @@ G_BEGIN_DECLS +typedef struct _SwfdecFileLoader SwfdecFileLoader; +typedef struct _SwfdecFileLoaderClass SwfdecFileLoaderClass; + +#define SWFDEC_TYPE_FILE_LOADER (swfdec_file_loader_get_type()) +#define SWFDEC_IS_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_FILE_LOADER)) +#define SWFDEC_IS_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_FILE_LOADER)) +#define SWFDEC_FILE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoader)) +#define SWFDEC_FILE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoaderClass)) +#define SWFDEC_FILE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_FILE_LOADER, SwfdecFileLoaderClass)) + +struct _SwfdecFileLoader +{ + SwfdecLoader loader; + + char * dir; /* base directory for load operations */ +}; + +struct _SwfdecFileLoaderClass +{ + SwfdecLoaderClass loader_class; +}; + SwfdecLoader * swfdec_loader_load (SwfdecLoader * loader, const char * url); diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c index b9bf7e9..f0c360d 100644 --- a/libswfdec/swfdec_player.c +++ b/libswfdec/swfdec_player.c @@ -1155,25 +1155,23 @@ swfdec_player_set_loader_with_variables /** * swfdec_player_new_from_file: * @filename: name of the file to play - * @error: return location for error or NULL * - * Tries to create a player to play back the given file. If the file does not - * exist or another error occurs, NULL is returned. + * Creates a player to play back the given file. If the file does not + * exist or another error occurs, the player will be in an error state and not + * be initialized. * This function calls swfdec_init () for you if it wasn't called before. * - * Returns: a new player or NULL on error. + * Returns: a new player **/ SwfdecPlayer * -swfdec_player_new_from_file (const char *filename, GError **error) +swfdec_player_new_from_file (const char *filename) { SwfdecLoader *loader; SwfdecPlayer *player; g_return_val_if_fail (filename != NULL, NULL); - loader = swfdec_loader_new_from_file (filename, error); - if (loader == NULL) - return NULL; + loader = swfdec_loader_new_from_file (filename); player = swfdec_player_new (); swfdec_player_set_loader (player, loader); diff --git a/libswfdec/swfdec_player.h b/libswfdec/swfdec_player.h index 0c6f70c..0bbf3d9 100644 --- a/libswfdec/swfdec_player.h +++ b/libswfdec/swfdec_player.h @@ -48,8 +48,7 @@ void swfdec_init (void); GType swfdec_player_get_type (void); SwfdecPlayer * swfdec_player_new (void); -SwfdecPlayer * swfdec_player_new_from_file (const char * filename, - GError ** error); +SwfdecPlayer * swfdec_player_new_from_file (const char * filename); void swfdec_player_set_loader (SwfdecPlayer * player, SwfdecLoader * loader); void swfdec_player_set_loader_with_variables diff --git a/player/swfdebug.c b/player/swfdebug.c index af7f7dc..8b2e9f2 100644 --- a/player/swfdebug.c +++ b/player/swfdebug.c @@ -408,10 +408,10 @@ main (int argc, char *argv[]) return 1; } - loader = swfdec_loader_new_from_file (argv[1], &error); - if (loader == NULL) { - g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], error->message); - g_error_free (error); + loader = swfdec_loader_new_from_file (argv[1]); + if (loader->error) { + g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], loader->error); + g_object_unref (loader); return 1; } player = swfdec_debugger_new (); diff --git a/player/swfplay.c b/player/swfplay.c index 81bbd3c..78c5c48 100644 --- a/player/swfplay.c +++ b/player/swfplay.c @@ -109,10 +109,10 @@ main (int argc, char *argv[]) return 1; } - loader = swfdec_loader_new_from_file (argv[1], &error); - if (loader == NULL) { - g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], error->message); - g_error_free (error); + loader = swfdec_gtk_loader_new (argv[1]); + if (loader->error) { + g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], loader->error); + g_object_unref (loader); return 1; } player = swfdec_gtk_player_new (); @@ -123,13 +123,6 @@ main (int argc, char *argv[]) loader = swfdec_slow_loader_new (loader, delay); swfdec_player_set_loader_with_variables (player, loader, variables); - /* FIXME add smarter "not my file" detection */ - if (!swfdec_player_is_initialized (player) && delay == 0) { - g_printerr ("File \"%s\" is not a file Swfdec can play\n", argv[1]); - g_object_unref (player); - player = NULL; - return 1; - } if (no_sound) swfdec_gtk_player_set_audio_enabled (SWFDEC_GTK_PLAYER (player), FALSE); diff --git a/test/dump.c b/test/dump.c index e248729..9c0475e 100644 --- a/test/dump.c +++ b/test/dump.c @@ -382,10 +382,10 @@ main (int argc, char *argv[]) fn = argv[1]; } - player = swfdec_player_new_from_file (argv[1], &error); - if (player == NULL) { - g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], error->message); - g_error_free (error); + player = swfdec_player_new_from_file (argv[1]); + if (player->loader->error) { + g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], player->loader->error); + g_object_unref (player); return 1; } s = (SwfdecSwfDecoder *) SWFDEC_ROOT_MOVIE (player->roots->data)->decoder; diff --git a/test/image/image.c b/test/image/image.c index 29b96a3..4113304 100644 --- a/test/image/image.c +++ b/test/image/image.c @@ -155,16 +155,16 @@ run_test (const char *filename) SwfdecLoader *loader; SwfdecPlayer *player = NULL; guint i, msecs; - GError *error = NULL; int w, h; cairo_surface_t *surface; cairo_t *cr; g_print ("Testing %s:\n", filename); - loader = swfdec_loader_new_from_file (filename, &error); - if (loader == NULL) { - g_print (" ERROR: %s\n", error->message); + loader = swfdec_loader_new_from_file (filename); + if (loader->error) { + g_print (" ERROR: %s\n", loader->error); + g_object_unref (loader); goto error; } player = swfdec_player_new (); @@ -193,8 +193,6 @@ run_test (const char *filename) return TRUE; error: - if (error) - g_error_free (error); if (player) g_object_unref (player); return FALSE; diff --git a/test/parse.c b/test/parse.c index d56c22c..6fa7234 100644 --- a/test/parse.c +++ b/test/parse.c @@ -30,7 +30,6 @@ main (int argc, char *argv[]) { char *fn = "it.swf"; SwfdecPlayer *player; - GError *error = NULL; swfdec_init (); @@ -38,13 +37,8 @@ main (int argc, char *argv[]) fn = argv[1]; } - player = swfdec_player_new_from_file (argv[1], &error); - if (player == NULL) { - g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], error->message); - g_error_free (error); - return 1; - } - if (swfdec_player_get_rate (player) == 0) { + player = swfdec_player_new_from_file (argv[1]); + if (!swfdec_player_is_initialized (player)) { g_printerr ("Error parsing file \"%s\"\n", argv[1]); g_object_unref (player); player = NULL; diff --git a/test/sound/sound.c b/test/sound/sound.c index f42149f..4cf348a 100644 --- a/test/sound/sound.c +++ b/test/sound/sound.c @@ -184,6 +184,7 @@ run_test (const char *filename) dir = g_dir_open (dirname, 0, &error); if (!dir) { g_print (" ERROR: %s\n", error->message); + g_error_free (error); return FALSE; } while ((name = g_dir_read_name (dir))) { @@ -195,9 +196,10 @@ run_test (const char *filename) } g_dir_close (dir); - loader = swfdec_loader_new_from_file (filename, &error); - if (loader == NULL) { - g_print (" ERROR: %s\n", error->message); + loader = swfdec_loader_new_from_file (filename); + if (loader->error) { + g_print (" ERROR: %s\n", loader->error); + g_object_unref (loader); goto error; } player = swfdec_player_new (); @@ -233,8 +235,6 @@ run_test (const char *filename) } error: - if (error) - g_error_free (error); if (player) g_object_unref (player); g_list_foreach (data.files, (GFunc) g_free, NULL); diff --git a/test/swfdec-extract.c b/test/swfdec-extract.c index da0964b..5ac1f8b 100644 --- a/test/swfdec-extract.c +++ b/test/swfdec-extract.c @@ -229,7 +229,6 @@ main (int argc, char *argv[]) SwfdecCharacter *character; int ret = 0; SwfdecPlayer *player; - GError *error = NULL; glong id; swfdec_init (); @@ -239,13 +238,8 @@ main (int argc, char *argv[]) return 0; } - player = swfdec_player_new_from_file (argv[1], &error); - if (player == NULL) { - g_printerr ("Couldn't open file \"%s\": %s\n", argv[1], error->message); - g_error_free (error); - return 1; - } - if (swfdec_player_get_rate (player) == 0) { + player = swfdec_player_new_from_file (argv[1]); + if (!SWFDEC_IS_ROOT_MOVIE (player->roots->data)) { g_printerr ("Error parsing file \"%s\"\n", argv[1]); g_object_unref (player); player = NULL; diff --git a/test/trace/trace.c b/test/trace/trace.c index 9a5a841..2c7ced7 100644 --- a/test/trace/trace.c +++ b/test/trace/trace.c @@ -18,14 +18,14 @@ run_test (const char *filename) SwfdecPlayer *player; SwfdecBuffer *buffer; guint time_left; - GError *error = NULL; char *str; GString *string; + GError *error = NULL; g_print ("Testing %s:\n", filename); - loader = swfdec_loader_new_from_file (filename, &error); - if (loader == NULL) { - g_print (" ERROR: %s\n", error->message); + loader = swfdec_loader_new_from_file (filename); + if (loader->error) { + g_print (" ERROR: %s\n", loader->error); return FALSE; } string = g_string_new (""); @@ -69,6 +69,7 @@ run_test (const char *filename) if (!g_spawn_sync (NULL, command, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, NULL, &error)) { g_printerr (" Couldn't spawn diff to compare the results: %s\n", error->message); + g_error_free (error); } } g_string_free (string, TRUE);
Apparently Analagous Threads
- Branch 'as' - 16 commits - configure.ac libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_script_function.c
- Branch 'as' - 5 commits - libswfdec/Makefile.am libswfdec/swfdec_as_strings.c libswfdec/swfdec_js_net_stream.c libswfdec/swfdec_movie.c libswfdec/swfdec_net_connection.c libswfdec/swfdec_net_stream_as.c libswfdec/swfdec_net_stream.c
- 17 commits - doc/swfdec-sections.txt libswfdec/compiler.c libswfdec/.gitignore libswfdec/Makefile.am libswfdec/swfdec_asbroadcaster.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_strings.c
- Branch 'as' - 7 commits - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_strings.c
- 6 commits - libswfdec/Makefile.am libswfdec/swfdec_js.c libswfdec/swfdec_js_mouse.c libswfdec/swfdec_listener.c libswfdec/swfdec_listener.h libswfdec/swfdec_movie.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_root_movie.c