[Swfdec] 3 commits - libswfdec/Makefile.am libswfdec/swfdec_as_number.c libswfdec/swfdec_as_types.h libswfdec/swfdec_filter_as.c libswfdec/swfdec_filter.c libswfdec/swfdec_filter.h libswfdec/swfdec_player_as.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_tag.c libswfdec/swfdec_tag.h libswfdec/swfdec_types.h vivified/ui

Benjamin Otte company at kemper.freedesktop.org
Fri Aug 31 09:22:55 PDT 2007


 libswfdec/Makefile.am              |   15 ++
 libswfdec/swfdec_as_number.c       |    4 
 libswfdec/swfdec_as_types.h        |    2 
 libswfdec/swfdec_filter.c          |  125 +++++++++++++++++++++
 libswfdec/swfdec_filter.h          |   60 ++++++++++
 libswfdec/swfdec_filter_as.c       |   47 +++++++
 libswfdec/swfdec_player_as.c       |    6 -
 libswfdec/swfdec_player_internal.h |    3 
 libswfdec/swfdec_sprite_movie.c    |    7 -
 libswfdec/swfdec_tag.c             |   68 -----------
 libswfdec/swfdec_tag.h             |    4 
 libswfdec/swfdec_types.h           |    1 
 vivified/ui/Makefile.am            |    4 
 vivified/ui/main.c                 |   57 ---------
 vivified/ui/vivi_window.c          |  220 +++++++++++++++++++++++++++++++++++++
 vivified/ui/vivi_window.h          |   64 ++++++++++
 16 files changed, 557 insertions(+), 130 deletions(-)

New commits:
diff-tree fbeb9d7acfe930070ee0c2a89c2214d4d7ebce70 (from ad147c01da110ddc2e48fe033f55ed9e93b9dda2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 31 18:22:36 2007 +0200

    implement SWFDEC_AS_CONSTRUCTOR
    
    This is just like SWFDEC_AS_NATIVE, but allows to add a get_type function that
    will be used as the construct type. See swfdec_as_native_function_set_construct_type
    for details.

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index abed01e..d1b3d95 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -244,15 +244,21 @@ CLEANFILES = \
 swfdec_asnative.h: $(libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES)
 	(cd $(srcdir) \
 	  && echo "#include \"swfdec_as_types.h\"" \
-	  && echo "#define SWFDEC_AS_NATIVE(x, y, func) void func (SwfdecAsContext *cx, \\" \
+	  && echo "#define SWFDEC_AS_NATIVE(x,y,func) void func (SwfdecAsContext *cx, \\" \
 	  && echo "    SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);" \
+	  && echo "#define SWFDEC_AS_CONSTRUCTOR(x,y,func,type) SWFDEC_AS_NATIVE(x,y,func) GType type (void);" \
+	  && grep -he "^SWFDEC_AS_CONSTRUCTOR" $(libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES) \
 	  && grep -he "^SWFDEC_AS_NATIVE" $(libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES) \
+	  && echo "#undef SWFDEC_AS_CONSTRUCTOR" \
 	  && echo "#undef SWFDEC_AS_NATIVE" \
-	  && echo "#define SWFDEC_AS_NATIVE(x,y,func) { x, y, func, G_STRINGIFY (func) }," \
-	  && echo "static const struct { guint x, y; SwfdecAsNative func; const char *name; } native_funcs[] = {" \
+	  && echo "#define SWFDEC_AS_NATIVE(x,y,func) SWFDEC_AS_CONSTRUCTOR(x,y,func,NULL)" \
+	  && echo "#define SWFDEC_AS_CONSTRUCTOR(x,y,func,type) { x, y, func, G_STRINGIFY (func), type }," \
+	  && echo "static const struct { guint x, y; SwfdecAsNative func; const char *name; GType (* get_type) (void); } native_funcs[] = {" \
+	  && grep -he "^SWFDEC_AS_CONSTRUCTOR" $(libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES) \
 	  && grep -he "^SWFDEC_AS_NATIVE" $(libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES) \
 	  && echo "  { 0, 0, NULL }" \
 	  && echo "};" \
+	  && echo "#undef SWFDEC_AS_CONSTRUCTOR" \
 	  && echo "#undef SWFDEC_AS_NATIVE" \
 	 ) >> xgen-san \
 	&& (cmp -s xgen-san swfdec_asnative.h || cp xgen-san swfdec_asnative.h) \
diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c
index 24b1259..d53e725 100644
--- a/libswfdec/swfdec_as_number.c
+++ b/libswfdec/swfdec_as_number.c
@@ -29,6 +29,7 @@
 #include "swfdec_as_native_function.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
+#include "swfdec_player_internal.h"
 
 G_DEFINE_TYPE (SwfdecAsNumber, swfdec_as_number, SWFDEC_TYPE_AS_OBJECT)
 
@@ -44,7 +45,8 @@ swfdec_as_number_init (SwfdecAsNumber *n
 
 /*** AS CODE ***/
 
-static void
+SWFDEC_AS_CONSTRUCTOR (106, 2, swfdec_as_number_construct, swfdec_as_number_get_type)
+void
 swfdec_as_number_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 8da685d..c338113 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -20,7 +20,7 @@
 #ifndef _SWFDEC_AS_TYPES_H_
 #define _SWFDEC_AS_TYPES_H_
 
-#include <glib.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
diff --git a/libswfdec/swfdec_player_as.c b/libswfdec/swfdec_player_as.c
index f08c48f..cb4140b 100644
--- a/libswfdec/swfdec_player_as.c
+++ b/libswfdec/swfdec_player_as.c
@@ -104,8 +104,12 @@ swfdec_get_asnative (SwfdecAsContext *cx
 
   for (i = 0; native_funcs[i].func != NULL; i++) {
     if (native_funcs[i].x == x && native_funcs[i].y == y) {
-      return swfdec_as_native_function_new (cx, native_funcs[i].name,
+      SwfdecAsFunction *fun = swfdec_as_native_function_new (cx, native_funcs[i].name,
 	  native_funcs[i].func, 0, NULL);
+      if (native_funcs[i].get_type) {
+	swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (fun),
+	    native_funcs[i].get_type ());
+      }
     }
   }
   return NULL;
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index ec7f914..d28a2f6 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -28,7 +28,8 @@
 
 G_BEGIN_DECLS
 
-#define SWFDEC_AS_NATIVE(x, y, func) void func (SwfdecAsContext *cx, \
+#define SWFDEC_AS_NATIVE(x, y, func) SWFDEC_AS_CONSTRUCTOR (x, y, func, NULL)
+#define SWFDEC_AS_CONSTRUCTOR(x, y, func, type) void func (SwfdecAsContext *cx, \
     SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);
 
 typedef enum {
diff-tree ad147c01da110ddc2e48fe033f55ed9e93b9dda2 (from 393f40ef723af001897e077099fb7eaf81cfc14f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 30 21:37:33 2007 +0200

    create a global window object

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index d9d0c15..4a28c90 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -13,10 +13,12 @@ vivified_SOURCES = \
 	vivi_player.c \
 	vivi_vivi_docklet.c \
 	vivi_widget.c \
+	vivi_window.c \
 	main.c
 
 noinst_HEADERS = \
 	vivi_movie_list.h \
+	vivi_vivi_docklet.h \
 	vivi_widget.h \
-	vivi_vivi_docklet.h
+	vivi_window.h
 
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index f497e32..3462be6 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -25,15 +25,7 @@
 #include <libswfdec-gtk/swfdec-gtk.h>
 #include "vivified/core/vivified-core.h"
 #include "vivified/dock/vivified-dock.h"
-
-static void
-try_grab_focus (GtkWidget *widget, gpointer unused)
-{
-  if (GTK_IS_ENTRY (widget))
-    gtk_widget_grab_focus (widget);
-  else if (GTK_IS_CONTAINER (widget))
-    gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
-}
+#include "vivi_window.h"
 
 static gboolean
 delete_event (GtkWidget *widget, GdkEvent *event, ViviApplication *app)
@@ -46,63 +38,22 @@ delete_event (GtkWidget *widget, GdkEven
 }
 
 static void
-set_title (ViviApplication *app, GParamSpec *pspec, GtkWindow *window)
-{
-  const char *filename = vivi_application_get_filename (app);
-
-  if (filename == NULL)
-    filename = "Vivified";
-  gtk_window_set_title (window, filename);
-}
-
-static void
 setup (const char *filename, const char *variables)
 {
-  GtkWidget *window, *box, *paned, *widget;
+  GtkWidget *window;
   ViviApplication *app;
-  GtkBuilder *builder;
-  GError *error = NULL;
 
   app = vivi_application_new ();
   vivi_application_set_filename (app, filename);
   vivi_application_set_variables (app, variables);
 
-  builder = gtk_builder_new ();
-  if (!gtk_builder_add_from_file (builder, "vivi_player.xml", &error) ||
-      !gtk_builder_add_from_file (builder, "vivi_command_line.xml", &error) ||
-      !gtk_builder_add_from_file (builder, "vivi_movies.xml", &error))
-    g_error ("%s", error->message);
-  gtk_builder_connect_signals (builder, app);
+  window = vivi_window_new (app);
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_window_set_default_size (GTK_WINDOW (window), 600, 450);
   g_signal_connect_swapped (app, "notify::quit", G_CALLBACK (gtk_widget_destroy), window);
-  g_signal_connect (app, "notify::filename", G_CALLBACK (set_title), window);
-  set_title (app, NULL, GTK_WINDOW (window));
-  paned = gtk_hpaned_new ();
-  gtk_paned_set_position (GTK_PANED (paned), 200);
-  gtk_container_add (GTK_CONTAINER (window), paned);
-
-  box = vivi_vdock_new ();
-  gtk_paned_add2 (GTK_PANED (paned), box);
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "player"));
-  g_object_set (widget, "application", app, NULL);
-  vivi_vdock_add (VIVI_VDOCK (box), widget);
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "command-line"));
-  g_object_set (widget, "application", app, NULL);
-  vivi_vdock_add (VIVI_VDOCK (box), widget);
-  gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
-
-  box = vivi_vdock_new ();
-  gtk_paned_add1 (GTK_PANED (paned), box);
-  widget = GTK_WIDGET (gtk_builder_get_object (builder, "movies"));
-  g_object_set (widget, "application", app, NULL);
-  vivi_vdock_add (VIVI_VDOCK (box), widget);
-
   g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), app);
   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), app);
+
   gtk_widget_show_all (window);
-  g_object_unref (builder);
 }
 
 int
diff --git a/vivified/ui/vivi_window.c b/vivified/ui/vivi_window.c
new file mode 100644
index 0000000..9d8b6ac
--- /dev/null
+++ b/vivified/ui/vivi_window.c
@@ -0,0 +1,220 @@
+/* Swfdec
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "vivi_window.h"
+
+enum {
+  PROP_0,
+  PROP_APP,
+  PROP_MOVIE
+};
+
+G_DEFINE_TYPE (ViviWindow, vivi_window, GTK_TYPE_WINDOW)
+
+static void
+vivi_window_app_notify (ViviApplication *app, GParamSpec *pspec, ViviWindow *window)
+{
+  if (g_str_equal (pspec->name, "player")) {
+    vivi_window_set_movie (window, NULL);
+  } else if (g_str_equal (pspec->name, "filename")) {
+    const char *filename = vivi_application_get_filename (app);
+
+    if (filename == NULL)
+      filename = "Vivified";
+    gtk_window_set_title (GTK_WINDOW (window), filename);
+  }
+}
+
+static void
+vivi_window_set_application (ViviWindow *window, ViviApplication *app)
+{
+  g_return_if_fail (VIVI_IS_WINDOW (window));
+  g_return_if_fail (app == NULL || VIVI_IS_APPLICATION (app));
+
+  vivi_window_set_movie (window, NULL);
+  if (window->app) {
+    g_signal_handlers_disconnect_by_func (window->app, vivi_window_app_notify, window);
+    g_object_unref (window->app);
+  }
+  window->app = app;
+  if (app) {
+    g_object_ref (app);
+    g_signal_connect (app, "notify", G_CALLBACK (vivi_window_app_notify), window);
+  }
+  g_object_notify (G_OBJECT (window), "application");
+}
+
+static void
+vivi_window_get_property (GObject *object, guint param_id, GValue *value, 
+    GParamSpec * pspec)
+{
+  ViviWindow *window = VIVI_WINDOW (object);
+  
+  switch (param_id) {
+    case PROP_APP:
+      g_value_set_object (value, window->app);
+      break;
+    case PROP_MOVIE:
+      g_value_set_object (value, window->movie);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_window_set_property (GObject *object, guint param_id, const GValue *value,
+    GParamSpec *pspec)
+{
+  ViviWindow *window = VIVI_WINDOW (object);
+  
+  switch (param_id) {
+    case PROP_APP:
+      vivi_window_set_application (window, VIVI_APPLICATION (g_value_get_object (value)));
+      break;
+    case PROP_MOVIE:
+      vivi_window_set_movie (window, SWFDEC_MOVIE (g_value_get_object (value)));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_window_dispose (GObject *object)
+{
+  ViviWindow *window = VIVI_WINDOW (object);
+
+  vivi_window_set_application (window, NULL);
+  vivi_window_set_movie (window, NULL);
+
+  G_OBJECT_CLASS (vivi_window_parent_class)->dispose (object);
+}
+
+static void
+vivi_window_class_init (ViviWindowClass * g_class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+
+  object_class->dispose = vivi_window_dispose;
+  object_class->get_property = vivi_window_get_property;
+  object_class->set_property = vivi_window_set_property;
+
+  g_object_class_install_property (object_class, PROP_APP,
+      g_param_spec_object ("application", "application", "application that is playing",
+	  VIVI_TYPE_APPLICATION, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_MOVIE,
+      g_param_spec_object ("movie", "movie", "selected movie",
+	  SWFDEC_TYPE_MOVIE, G_PARAM_READWRITE));
+}
+
+static void
+vivi_window_init (ViviWindow *window)
+{
+}
+
+static void
+try_grab_focus (GtkWidget *widget, gpointer unused)
+{
+  if (GTK_IS_ENTRY (widget))
+    gtk_widget_grab_focus (widget);
+  else if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
+}
+
+GtkWidget *
+vivi_window_new (ViviApplication *app)
+{
+  GtkWidget *window, *box, *paned, *widget;
+  GtkBuilder *builder;
+  GError *error = NULL;
+
+  g_return_val_if_fail (VIVI_IS_APPLICATION (app), NULL);
+
+  window = g_object_new (VIVI_TYPE_WINDOW, "application", app, 
+      "type", GTK_WINDOW_TOPLEVEL, "default-width", 600, "default-height", 450,
+      NULL);
+
+  builder = gtk_builder_new ();
+  if (!gtk_builder_add_from_file (builder, "vivi_player.xml", &error) ||
+      !gtk_builder_add_from_file (builder, "vivi_command_line.xml", &error) ||
+      !gtk_builder_add_from_file (builder, "vivi_movies.xml", &error))
+    g_error ("%s", error->message);
+  gtk_builder_connect_signals (builder, app);
+
+  gtk_window_set_default_size (GTK_WINDOW (window), 600, 450);
+  paned = gtk_hpaned_new ();
+  gtk_paned_set_position (GTK_PANED (paned), 200);
+  gtk_container_add (GTK_CONTAINER (window), paned);
+
+  box = vivi_vdock_new ();
+  gtk_paned_add2 (GTK_PANED (paned), box);
+  widget = GTK_WIDGET (gtk_builder_get_object (builder, "player"));
+  g_object_set (widget, "application", app, NULL);
+  vivi_vdock_add (VIVI_VDOCK (box), widget);
+  widget = GTK_WIDGET (gtk_builder_get_object (builder, "command-line"));
+  g_object_set (widget, "application", app, NULL);
+  vivi_vdock_add (VIVI_VDOCK (box), widget);
+  gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
+
+  box = vivi_vdock_new ();
+  gtk_paned_add1 (GTK_PANED (paned), box);
+  widget = GTK_WIDGET (gtk_builder_get_object (builder, "movies"));
+  g_object_set (widget, "application", app, NULL);
+  vivi_vdock_add (VIVI_VDOCK (box), widget);
+
+  g_object_unref (builder);
+
+  return window;
+}
+
+ViviApplication *
+vivi_window_get_application (ViviWindow *window)
+{
+  g_return_val_if_fail (VIVI_IS_WINDOW (window), NULL);
+
+  return window->app;
+}
+
+void
+vivi_window_set_movie (ViviWindow *window, SwfdecMovie *movie)
+{
+  g_return_if_fail (VIVI_IS_WINDOW (window));
+  g_return_if_fail (movie == NULL || SWFDEC_IS_MOVIE (movie));
+
+  if (window->movie == movie)
+    return;
+
+  if (window->movie) {
+    g_object_unref (window->movie);
+  }
+  window->movie = movie;
+  if (window->movie) {
+    g_object_ref (movie);
+  }
+  g_object_notify (G_OBJECT (window), "movie");
+}
+
diff --git a/vivified/ui/vivi_window.h b/vivified/ui/vivi_window.h
new file mode 100644
index 0000000..80c0b27
--- /dev/null
+++ b/vivified/ui/vivi_window.h
@@ -0,0 +1,64 @@
+/* Vivi
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_WINDOW_H_
+#define _VIVI_WINDOW_H_
+
+#include <vivified/dock/vivified-dock.h>
+#include <vivified/core/vivified-core.h>
+/* FIXME */
+#include <libswfdec/swfdec_movie.h>
+
+G_BEGIN_DECLS
+
+typedef struct _ViviWindow ViviWindow;
+typedef struct _ViviWindowClass ViviWindowClass;
+
+#define VIVI_TYPE_WINDOW                    (vivi_window_get_type())
+#define VIVI_IS_WINDOW(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_WINDOW))
+#define VIVI_IS_WINDOW_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_WINDOW))
+#define VIVI_WINDOW(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_WINDOW, ViviWindow))
+#define VIVI_WINDOW_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_WINDOW, ViviWindowClass))
+
+struct _ViviWindow
+{
+  GtkWindow     	window;
+
+  ViviApplication *	app;		/* application we are displaying */
+
+  SwfdecMovie *		movie;		/* the currently active movie or NULL if none */
+};
+
+struct _ViviWindowClass
+{
+  GtkWindowClass	window_class;
+};
+
+GType			vivi_window_get_type		(void);
+
+GtkWidget *		vivi_window_new			(ViviApplication *	app);
+
+ViviApplication *	vivi_window_get_application	(ViviWindow *		window);
+void			vivi_window_set_movie		(ViviWindow *		window,
+							 SwfdecMovie *		movie);
+SwfdecMovie *		vivi_window_get_movie		(ViviWindow *		window);
+
+
+G_END_DECLS
+#endif
diff-tree 393f40ef723af001897e077099fb7eaf81cfc14f (from da2933ac249d01058d9cf2e5b24a79e00e756fa3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 30 13:48:29 2007 +0200

    create a SwfdecFilter class
    
    Includes code to move parsing of filters to swfdec_filter.c and use an API that
    actually returns a list of filters. However, for now the filters are just
    discarded after parsing and the Button filters are discarded way too early. The
    button parsing code needs some serious cleanup.

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 0ad870d..abed01e 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -66,6 +66,8 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_enums.c \
 	swfdec_event.c \
 	swfdec_file_loader.c \
+	swfdec_filter.c \
+	swfdec_filter_as.c \
 	swfdec_flv_decoder.c \
 	swfdec_font.c \
 	swfdec_graphic.c \
@@ -185,6 +187,7 @@ noinst_HEADERS = \
 	swfdec_edittext.h \
 	swfdec_edittext_movie.h \
 	swfdec_event.h \
+	swfdec_filter.h \
 	swfdec_flv_decoder.h \
 	swfdec_font.h \
 	swfdec_graphic.h \
diff --git a/libswfdec/swfdec_filter.c b/libswfdec/swfdec_filter.c
new file mode 100644
index 0000000..3a1e7bd
--- /dev/null
+++ b/libswfdec/swfdec_filter.c
@@ -0,0 +1,125 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *		 2007 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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_filter.h"
+#include "swfdec_debug.h"
+
+G_DEFINE_ABSTRACT_TYPE (SwfdecFilter, swfdec_filter, SWFDEC_TYPE_AS_OBJECT)
+
+static void
+swfdec_filter_class_init (SwfdecFilterClass *klass)
+{
+}
+
+static void
+swfdec_filter_init (SwfdecFilter *array)
+{
+}
+
+cairo_pattern_t *
+swfdec_filter_apply (SwfdecFilter *filter, cairo_pattern_t *pattern)
+{
+  SwfdecFilterClass *klass;
+  cairo_pattern_t *ret;
+
+  g_return_val_if_fail (SWFDEC_IS_FILTER (filter), NULL);
+  g_return_val_if_fail (pattern != NULL, NULL);
+
+  klass = SWFDEC_FILTER_GET_CLASS (filter);
+  g_assert (klass->apply);
+  
+  ret = klass->apply (filter, pattern);
+  cairo_pattern_destroy (pattern);
+  return ret;
+}
+
+GSList *
+swfdec_filter_parse (SwfdecPlayer *player, SwfdecBits *bits)
+{
+  GSList *filters = NULL;
+  guint i, n_filters, filter_id;
+
+  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+  g_return_val_if_fail (bits != NULL, NULL);
+
+  n_filters = swfdec_bits_get_u8 (bits);
+  SWFDEC_LOG ("  filters: %u", n_filters);
+  for (i = 0; i < n_filters && swfdec_bits_left (bits); i++) {
+    filter_id = swfdec_bits_get_u8 (bits);
+    switch (filter_id) {
+      case 0:
+	SWFDEC_WARNING ("    drop shadow");
+	swfdec_bits_skip_bytes (bits, 16);
+	break;
+      case 1:
+	SWFDEC_WARNING ("    blur");
+	swfdec_bits_skip_bytes (bits, 9);
+	break;
+      case 2:
+	SWFDEC_WARNING ("    glow");
+	swfdec_bits_skip_bytes (bits, 15);
+	break;
+      case 3:
+	SWFDEC_WARNING ("    bevel");
+	swfdec_bits_skip_bytes (bits, 27);
+	break;
+      case 4:
+	{
+	  guint n;
+	  n = swfdec_bits_get_u8 (bits);
+	  SWFDEC_WARNING ("    gradient glow");
+	  swfdec_bits_skip_bytes (bits, n * 5 + 19);
+	}
+	break;
+      case 5:
+	{
+	  guint x, y;
+	  x = swfdec_bits_get_u8 (bits);
+	  y = swfdec_bits_get_u8 (bits);
+	  SWFDEC_WARNING ("    %u x %u convolution", x, y);
+	  swfdec_bits_skip_bytes (bits, (x + y) * 4 + 13);
+	}
+	break;
+      case 6:
+	SWFDEC_WARNING ("    color matrix");
+	swfdec_bits_skip_bytes (bits, 20 * 4);
+	break;
+      case 7:
+	{
+	  guint n;
+	  n = swfdec_bits_get_u8 (bits);
+	  SWFDEC_WARNING ("    gradient bevel");
+	  swfdec_bits_skip_bytes (bits, n * 5 + 19);
+	}
+	break;
+      default:
+	SWFDEC_ERROR ("unknown filter id %u", filter_id);
+	break;
+    }
+  }
+
+  filters = g_slist_reverse (filters);
+  return filters;
+}
+
diff --git a/libswfdec/swfdec_filter.h b/libswfdec/swfdec_filter.h
new file mode 100644
index 0000000..2f39f15
--- /dev/null
+++ b/libswfdec/swfdec_filter.h
@@ -0,0 +1,60 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _SWFDEC_FILTER_H_
+#define _SWFDEC_FILTER_H_
+
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_as_object.h>
+#include <libswfdec/swfdec_bits.h>
+#include <libswfdec/swfdec_types.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecFilterClass SwfdecFilterClass;
+
+#define SWFDEC_TYPE_FILTER                    (swfdec_filter_get_type())
+#define SWFDEC_IS_FILTER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_FILTER))
+#define SWFDEC_IS_FILTER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_FILTER))
+#define SWFDEC_FILTER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_FILTER, SwfdecFilter))
+#define SWFDEC_FILTER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_FILTER, SwfdecFilterClass))
+#define SWFDEC_FILTER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_FILTER, SwfdecFilterClass))
+
+struct _SwfdecFilter {
+  SwfdecAsObject	object;
+};
+
+struct _SwfdecFilterClass {
+  SwfdecAsObjectClass	object_class;
+
+  SwfdecFilter *	(* clone)		(SwfdecFilter *		filter);
+  cairo_pattern_t *	(* apply)		(SwfdecFilter *		filter,
+						 cairo_pattern_t *	pattern);
+};
+
+GType			swfdec_filter_get_type	(void);
+
+cairo_pattern_t *	swfdec_filter_apply	(SwfdecFilter *		filter,
+						 cairo_pattern_t *	pattern);
+GSList *		swfdec_filter_parse	(SwfdecPlayer *		player,
+						 SwfdecBits *		bits);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_filter_as.c b/libswfdec/swfdec_filter_as.c
new file mode 100644
index 0000000..53a0674
--- /dev/null
+++ b/libswfdec/swfdec_filter_as.c
@@ -0,0 +1,47 @@
+/* Swfdec
+ * Copyright (C) 2006-2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec_filter.h"
+#include "swfdec_debug.h"
+#include "swfdec_player_internal.h"
+
+SWFDEC_AS_NATIVE (1112, 1, swfdec_filter_clone)
+void
+swfdec_filter_clone (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  SwfdecFilter *filter;
+  SwfdecFilterClass *klass;
+
+  if (!SWFDEC_IS_FILTER (object))
+    return;
+
+  filter = SWFDEC_FILTER (object);
+  klass = SWFDEC_FILTER_GET_CLASS (filter);
+  g_assert (klass->clone);
+
+  filter = klass->clone (filter);
+  if (filter)
+    SWFDEC_AS_VALUE_SET_OBJECT (retval, SWFDEC_AS_OBJECT (filter));
+}
+
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 15d005b..6152535 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -29,6 +29,7 @@
 #include "swfdec_audio_event.h"
 #include "swfdec_audio_stream.h"
 #include "swfdec_debug.h"
+#include "swfdec_filter.h"
 #include "swfdec_graphic_movie.h"
 #include "swfdec_player_internal.h"
 #include "swfdec_ringbuffer.h"
@@ -179,8 +180,10 @@ swfdec_sprite_movie_perform_place (Swfde
     clip_depth = 0;
   }
 
-  if (has_filter)
-    swfdec_filters_parse (bits);
+  if (has_filter) {
+    GSList *filters = swfdec_filter_parse (player, bits);
+    g_slist_free (filters);
+  }
 
   if (has_blend_mode) {
     blend_mode = swfdec_bits_get_u8 (bits);
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index 2fe1a04..f8fb5e8 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -33,6 +33,7 @@
 #include "swfdec_button.h"
 #include "swfdec_debug.h"
 #include "swfdec_edittext.h"
+#include "swfdec_filter.h"
 #include "swfdec_font.h"
 #include "swfdec_image.h"
 #include "swfdec_morphshape.h"
@@ -252,67 +253,6 @@ tag_func_define_sprite (SwfdecSwfDecoder
   return SWFDEC_STATUS_OK;
 }
 
-void
-swfdec_filters_parse (SwfdecBits *bits)
-{
-  guint i, n_filters, filter_id;
-  n_filters = swfdec_bits_get_u8 (bits);
-  SWFDEC_WARNING ("  filters: %u", n_filters);
-  for (i = 0; i < n_filters && swfdec_bits_left (bits); i++) {
-    filter_id = swfdec_bits_get_u8 (bits);
-    switch (filter_id) {
-      case 0:
-	SWFDEC_WARNING ("    drop shadow");
-	swfdec_bits_skip_bytes (bits, 16);
-	break;
-      case 1:
-	SWFDEC_WARNING ("    blur");
-	swfdec_bits_skip_bytes (bits, 9);
-	break;
-      case 2:
-	SWFDEC_WARNING ("    glow");
-	swfdec_bits_skip_bytes (bits, 15);
-	break;
-      case 3:
-	SWFDEC_WARNING ("    bevel");
-	swfdec_bits_skip_bytes (bits, 27);
-	break;
-      case 4:
-	{
-	  guint n;
-	  n = swfdec_bits_get_u8 (bits);
-	  SWFDEC_WARNING ("    gradient glow");
-	  swfdec_bits_skip_bytes (bits, n * 5 + 19);
-	}
-	break;
-      case 5:
-	{
-	  guint x, y;
-	  x = swfdec_bits_get_u8 (bits);
-	  y = swfdec_bits_get_u8 (bits);
-	  SWFDEC_WARNING ("    %u x %u convolution", x, y);
-	  swfdec_bits_skip_bytes (bits, (x + y) * 4 + 13);
-	}
-	break;
-      case 6:
-	SWFDEC_WARNING ("    color matrix");
-	swfdec_bits_skip_bytes (bits, 20 * 4);
-	break;
-      case 7:
-	{
-	  guint n;
-	  n = swfdec_bits_get_u8 (bits);
-	  SWFDEC_WARNING ("    gradient bevel");
-	  swfdec_bits_skip_bytes (bits, n * 5 + 19);
-	}
-	break;
-      default:
-	SWFDEC_ERROR ("unknown filter id %u", filter_id);
-	break;
-    }
-  }
-}
-
 #define CONTENT_IN_FRAME(content, frame) \
   ((content)->sequence->start <= frame && \
    (content)->sequence->end > frame)
@@ -458,8 +398,10 @@ tag_func_define_button_2 (SwfdecSwfDecod
       content->blend_mode = swfdec_bits_get_u8 (&bits);
       SWFDEC_LOG ("  blend mode = %u", content->blend_mode);
     }
-    if (has_filters)
-      swfdec_filters_parse (&bits);
+    if (has_filters) {
+      GSList *list = swfdec_filter_parse (SWFDEC_DECODER (s)->player, &bits);
+      g_slist_free (list);
+    }
     if (!SWFDEC_IS_GRAPHIC (content->graphic)) {
       SWFDEC_ERROR ("id %u does not reference a graphic, ignoring", character);
       swfdec_content_free (content);
diff --git a/libswfdec/swfdec_tag.h b/libswfdec/swfdec_tag.h
index 91bba34..cbb6de0 100644
--- a/libswfdec/swfdec_tag.h
+++ b/libswfdec/swfdec_tag.h
@@ -92,9 +92,5 @@ typedef enum {
   SWFDEC_TAG_DEFINEMORPHSHAPE2    = 84
 } SwfdecTag;
 
-/* FIXME: put this somewhere sane */
-#include "swfdec_bits.h"
-void	swfdec_filters_parse	(SwfdecBits *	bits);
-
 
 #endif
diff --git a/libswfdec/swfdec_types.h b/libswfdec/swfdec_types.h
index b66ecd9..d5c9a8b 100644
--- a/libswfdec/swfdec_types.h
+++ b/libswfdec/swfdec_types.h
@@ -39,6 +39,7 @@ typedef struct _SwfdecColorTransform Swf
 typedef struct _SwfdecContent SwfdecContent;
 typedef struct _SwfdecDecoder SwfdecDecoder;
 typedef struct _SwfdecEventList SwfdecEventList;
+typedef struct _SwfdecFilter SwfdecFilter;
 typedef struct _SwfdecFont SwfdecFont;
 typedef struct _SwfdecGraphic SwfdecGraphic;
 typedef struct _SwfdecImage SwfdecImage;


More information about the Swfdec mailing list