[Swfdec-commits] 15 commits - swfdec-gtk/swfdec_gtk_widget.c swfdec/swfdec_as_strings.c swfdec/swfdec_debugger.c swfdec/swfdec_debugger.h swfdec/swfdec_decoder.c swfdec/swfdec_flv_decoder.h swfdec/swfdec_movie.c swfdec/swfdec_movie.h swfdec/swfdec_player.c swfdec/swfdec_player.h swfdec/swfdec_player_internal.h swfdec/swfdec_selection.c swfdec/swfdec_tag.c test/trace vivified/code

Benjamin Otte company at kemper.freedesktop.org
Fri Mar 28 10:02:45 PDT 2008


 swfdec-gtk/swfdec_gtk_widget.c               |   43 +
 swfdec/swfdec_as_strings.c                   |    5 
 swfdec/swfdec_debugger.c                     |  617 ---------------------------
 swfdec/swfdec_debugger.h                     |  108 ----
 swfdec/swfdec_decoder.c                      |    6 
 swfdec/swfdec_flv_decoder.h                  |    3 
 swfdec/swfdec_movie.c                        |   26 +
 swfdec/swfdec_movie.h                        |    7 
 swfdec/swfdec_player.c                       |  179 ++++++-
 swfdec/swfdec_player.h                       |    3 
 swfdec/swfdec_player_internal.h              |   11 
 swfdec/swfdec_selection.c                    |   33 +
 swfdec/swfdec_tag.c                          |  184 --------
 test/trace/Makefile.am                       |    9 
 test/trace/selection-focus-5.swf             |binary
 test/trace/selection-focus-5.swf.trace       |   30 +
 test/trace/selection-focus-6.swf             |binary
 test/trace/selection-focus-6.swf.trace       |   32 +
 test/trace/selection-focus-7.swf             |binary
 test/trace/selection-focus-7.swf.trace       |   32 +
 test/trace/selection-focus-8.swf             |binary
 test/trace/selection-focus-8.swf.trace       |   32 +
 test/trace/selection-focus.as                |   31 +
 vivified/code/Makefile.am                    |   13 
 vivified/code/decompiler.c                   |   27 +
 vivified/code/test/Makefile.am               |    5 
 vivified/code/test/function-calls.as         |    6 
 vivified/code/test/function-calls.swf        |binary
 vivified/code/test/function-calls.swf.expect |   10 
 vivified/code/vivi_code_assignment.c         |   14 
 vivified/code/vivi_code_assignment.h         |    4 
 vivified/code/vivi_code_return.c             |    7 
 vivified/code/vivi_code_return.h             |    1 
 vivified/code/vivi_decompiler.c              |   44 +
 34 files changed, 560 insertions(+), 962 deletions(-)

New commits:
commit 31434d235eda37f9bf8197329618ce948b0a56dd
Merge: 7e193d8... 13ee60f...
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Mar 28 18:02:35 2008 +0100

    Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec

commit 7e193d854e7a81e67addee93434ea07080478333
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Mar 28 16:25:54 2008 +0100

    don't add my test compile stuff (unconditionally) to Makefile.am

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 03f5969..57a7b4c 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -71,7 +71,7 @@ noinst_HEADERS = \
 	vivified-compiler.h
 
 
-noinst_PROGRAMS = vivi-decompile vivi-decompile-gtk
+noinst_PROGRAMS = vivi-decompile
 
 vivi_decompile_SOURCES = \
 	decompiler.c
@@ -80,6 +80,9 @@ vivi_decompile_CFLAGS =  $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS)
 vivi_decompile_LDFLAGS = $(SWFDEC_LIBS)
 vivi_decompile_LDADD = libvivified-compiler.la
 
+if SECRET_TEST_CODE
+noinst_PROGRAMS += vivi-decompile-gtk
+
 vivi_decompile_gtk_SOURCES = \
 	vivi_code_gtk_printer.c \
 	vivi_code_gtk_printer.h \
@@ -88,3 +91,4 @@ vivi_decompile_gtk_SOURCES = \
 vivi_decompile_gtk_CFLAGS =  $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS)
 vivi_decompile_gtk_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS)
 vivi_decompile_gtk_LDADD = libvivified-compiler.la
+endif
commit a8fd4a79cbaf7a4d5b78e0320f118e95857142fc
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Mar 28 16:19:37 2008 +0100

    add focus handling code to SwfdecGtkWidget
    
    It's untested, because I couldn't come up with a way to test it

diff --git a/swfdec-gtk/swfdec_gtk_widget.c b/swfdec-gtk/swfdec_gtk_widget.c
index 4836aa0..f0c47b6 100644
--- a/swfdec-gtk/swfdec_gtk_widget.c
+++ b/swfdec-gtk/swfdec_gtk_widget.c
@@ -183,6 +183,30 @@ swfdec_gtk_widget_key_release (GtkWidget *gtkwidget, GdkEventKey *event)
   return FALSE;
 }
 
+/* NB: called for both focus in and focus out */
+static gboolean
+swfdec_gtk_widget_focus_inout (GtkWidget *gtkwidget, GdkEventFocus *focus)
+{
+  SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget);
+  SwfdecGtkWidgetPrivate *priv = widget->priv;
+
+  if (priv->interactive && priv->player)
+    swfdec_player_set_focus (priv->player, focus->in);
+  return FALSE;
+}
+
+static gboolean
+swfdec_gtk_widget_focus (GtkWidget *gtkwidget, GtkDirectionType direction)
+{
+  SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (gtkwidget);
+  SwfdecGtkWidgetPrivate *priv = widget->priv;
+
+  if (!priv->interactive || priv->player == NULL)
+    return FALSE;
+
+  return GTK_WIDGET_CLASS (swfdec_gtk_widget_parent_class)->focus (gtkwidget, direction);
+}
+
 static cairo_surface_t *
 swfdec_gtk_widget_create_renderer (cairo_surface_type_t type, int width, int height)
 {
@@ -404,7 +428,8 @@ swfdec_gtk_widget_realize (GtkWidget *widget)
 			   GDK_POINTER_MOTION_MASK | 
 			   GDK_POINTER_MOTION_HINT_MASK |
 			   GDK_KEY_PRESS_MASK |
-			   GDK_KEY_RELEASE_MASK;
+			   GDK_KEY_RELEASE_MASK |
+			   GDK_FOCUS_CHANGE_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y;
 
@@ -453,6 +478,9 @@ swfdec_gtk_widget_class_init (SwfdecGtkWidgetClass * g_class)
   widget_class->leave_notify_event = swfdec_gtk_widget_leave_notify;
   widget_class->key_press_event = swfdec_gtk_widget_key_press;
   widget_class->key_release_event = swfdec_gtk_widget_key_release;
+  widget_class->focus_in_event = swfdec_gtk_widget_focus_inout;
+  widget_class->focus_out_event = swfdec_gtk_widget_focus_inout;
+  widget_class->focus = swfdec_gtk_widget_focus;
 
   g_type_class_add_private (object_class, sizeof (SwfdecGtkWidgetPrivate));
 }
@@ -515,21 +543,22 @@ swfdec_gtk_widget_set_player (SwfdecGtkWidget *widget, SwfdecPlayer *player)
   g_return_if_fail (SWFDEC_IS_GTK_WIDGET (widget));
   g_return_if_fail (player == NULL || SWFDEC_IS_PLAYER (player));
   
-  if (priv->player) {
-    g_signal_handlers_disconnect_by_func (priv->player, swfdec_gtk_widget_invalidate_cb, widget);
-    g_signal_handlers_disconnect_by_func (priv->player, swfdec_gtk_widget_notify_cb, widget);
-    g_object_unref (priv->player);
-  }
-  priv->player = player;
   if (player) {
     g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_gtk_widget_invalidate_cb), widget);
     g_signal_connect (player, "notify", G_CALLBACK (swfdec_gtk_widget_notify_cb), widget);
     g_object_ref (player);
     swfdec_gtk_widget_update_cursor (widget);
+    swfdec_player_set_focus (player, GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (widget)));
   } else {
     if (GTK_WIDGET (widget)->window)
       gdk_window_set_cursor (GTK_WIDGET (widget)->window, NULL); 
   }
+  if (priv->player) {
+    g_signal_handlers_disconnect_by_func (priv->player, swfdec_gtk_widget_invalidate_cb, widget);
+    g_signal_handlers_disconnect_by_func (priv->player, swfdec_gtk_widget_notify_cb, widget);
+    g_object_unref (priv->player);
+  }
+  priv->player = player;
   gtk_widget_queue_resize (GTK_WIDGET (widget));
   g_object_notify (G_OBJECT (widget), "player");
 }
commit 885df5005b03aa0e9b06480a3bf8728c4d03e828
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Mar 28 10:59:33 2008 +0100

    add public API for focus handling
    
    That is:
    - swfdec_player_[gs]et_focus()
    - "focus" property

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 982002b..e7d7f36 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -663,7 +663,8 @@ enum {
   PROP_BASE_URL,
   PROP_URL,
   PROP_VARIABLES,
-  PROP_START_TIME
+  PROP_START_TIME,
+  PROP_FOCUS
 };
 
 G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, SWFDEC_TYPE_AS_CONTEXT)
@@ -783,6 +784,9 @@ swfdec_player_get_property (GObject *object, guint param_id, GValue *value,
     case PROP_VARIABLES:
       g_value_set_string (value, priv->variables);
       break;
+    case PROP_FOCUS:
+      g_value_set_boolean (value, priv->has_focus);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -924,6 +928,9 @@ swfdec_player_set_property (GObject *object, guint param_id, const GValue *value
 	/* else use default time from context */
       }
       break;
+    case PROP_FOCUS:
+      swfdec_player_set_focus (player, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -1802,6 +1809,9 @@ swfdec_player_class_init (SwfdecPlayerClass *klass)
   g_object_class_install_property (object_class, PROP_START_TIME,
       g_param_spec_boxed ("start-time", "start-time", "time to use as the beginning time for this player",
 	  SWFDEC_TYPE_TIME_VAL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class, PROP_FOCUS,
+      g_param_spec_boolean ("focus", "focus", "TRUE if the player has keyboard focus",
+	  TRUE, G_PARAM_READWRITE));
 
   /**
    * SwfdecPlayer::invalidate:
@@ -1992,6 +2002,7 @@ swfdec_player_init (SwfdecPlayer *player)
   priv->mouse_cursor = SWFDEC_MOUSE_CURSOR_NORMAL;
   priv->stage_width = -1;
   priv->stage_height = -1;
+  priv->has_focus = TRUE;
 }
 
 void
@@ -2556,6 +2567,7 @@ swfdec_player_key_press (SwfdecPlayer *player, guint keycode, guint character)
   gboolean ret;
 
   g_return_val_if_fail (SWFDEC_IS_PLAYER (player), FALSE);
+  g_return_val_if_fail (player->priv->has_focus, FALSE);
   g_return_val_if_fail (keycode < 256, FALSE);
 
   g_signal_emit (player, signals[HANDLE_KEY], 0, keycode, character, TRUE, &ret);
@@ -2581,6 +2593,7 @@ swfdec_player_key_release (SwfdecPlayer *player, guint keycode, guint character)
   gboolean ret;
 
   g_return_val_if_fail (SWFDEC_IS_PLAYER (player), FALSE);
+  g_return_val_if_fail (player->priv->has_focus, FALSE);
   g_return_val_if_fail (keycode < 256, FALSE);
 
   g_signal_emit (player, signals[HANDLE_KEY], 0, keycode, character, FALSE, &ret);
@@ -3092,6 +3105,66 @@ swfdec_player_set_scripting (SwfdecPlayer *player, SwfdecPlayerScripting *script
   g_object_notify (G_OBJECT (player), "scripting");
 }
 
+static void
+swfdec_player_update_focus (gpointer playerp, gpointer unused)
+{
+  SwfdecPlayer *player = playerp;
+  SwfdecPlayerPrivate *priv = player->priv;
+
+  if (priv->has_focus) {
+    swfdec_player_grab_focus (player, priv->focus_previous);
+  } else {
+    swfdec_player_grab_focus (player, NULL);
+  }
+}
+
+/**
+ * swfdec_player_get_focus:
+ * @player: a #SwfdecPlayer
+ *
+ * Checks if the @player has keyboard focus. See swfdec_player_set_focus() for
+ * details.
+ *
+ * Returns: %TRUE if the player has keyboard focus.
+ **/
+gboolean
+swfdec_player_get_focus (SwfdecPlayer *player)
+{
+  g_return_val_if_fail (SWFDEC_IS_PLAYER (player), FALSE);
+
+  return player->priv->has_focus;
+}
+
+/**
+ * swfdec_player_set_focus:
+ * @player: the player
+ * @focus: if the player is focussed
+ *
+ * Tells the @player whether keyboard focus is inside it. The player will use 
+ * this information to draw focus indicators around objects. Note that this
+ * update will not happen immediately, but only the next time you call 
+ * swfdec_player_advance(). The player is focussed by default. So if you 
+ * integrate it into a widget system such, you likely want to unset this upon 
+ * creation of the player.
+ * <note><para>The player must be focussed to receive keyboard events.</para>
+ * </note>
+ **/
+void
+swfdec_player_set_focus	(SwfdecPlayer *player, gboolean	focus)
+{
+  SwfdecPlayerPrivate *priv;
+
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
+  priv = player->priv;
+  if (priv->has_focus == focus)
+    return;
+
+  priv->has_focus = focus;
+  swfdec_player_add_external_action (player, player, swfdec_player_update_focus, NULL);
+  g_object_notify (G_OBJECT (player), "focus");
+}
+
 /**
  * swfdec_player_get_base_url:
  * @player: a #SwfdecPlayer
diff --git a/swfdec/swfdec_player.h b/swfdec/swfdec_player.h
index aa16c1b..21f6670 100644
--- a/swfdec/swfdec_player.h
+++ b/swfdec/swfdec_player.h
@@ -145,6 +145,9 @@ SwfdecPlayerScripting *
 		swfdec_player_get_scripting	(SwfdecPlayer *		player);
 void		swfdec_player_set_scripting	(SwfdecPlayer *		player,
 						 SwfdecPlayerScripting *scripting);
+gboolean	swfdec_player_get_focus		(SwfdecPlayer *		player);
+void		swfdec_player_set_focus		(SwfdecPlayer *		player,
+						 gboolean		focus);
 					 
 void		swfdec_player_render		(SwfdecPlayer *	player,
 						 cairo_t *	cr,
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index c351603..fca27d8 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -76,6 +76,7 @@ struct _SwfdecPlayerPrivate
   GHashTable *		scripting_callbacks;	/* GC string => SwfdecAsFunction mapping of script callbacks */
   GType			loader_type;		/* type to use for creating sockets */
   GType			socket_type;		/* type to use for creating sockets */
+  gboolean		has_focus;		/* TRUE if this movie is given focus */
   /* stage properties */
   guint			internal_width;		/* width used by the scripting engine */
   guint			internal_height;	/* height used by the scripting engine */
commit c0c62bf10d00a130ffe9edad569249d4e1438685
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Mar 28 10:18:48 2008 +0100

    add test for selection focus handling

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 4664e79..68a91a7 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -2607,6 +2607,15 @@ EXTRA_DIST = \
 	scope-chain-with-and-scope-chain-7.swf.trace \
 	scope-chain-with-and-scope-chain-8.swf \
 	scope-chain-with-and-scope-chain-8.swf.trace \
+	selection-focus-5.swf \
+	selection-focus-5.swf.trace \
+	selection-focus-6.swf \
+	selection-focus-6.swf.trace \
+	selection-focus-7.swf \
+	selection-focus-7.swf.trace \
+	selection-focus-8.swf \
+	selection-focus-8.swf.trace \
+	selection-focus.as \
 	selection-properties.as \
 	selection-properties-5.swf \
 	selection-properties-5.swf.trace \
diff --git a/test/trace/selection-focus-5.swf b/test/trace/selection-focus-5.swf
new file mode 100644
index 0000000..35f6be3
Binary files /dev/null and b/test/trace/selection-focus-5.swf differ
diff --git a/test/trace/selection-focus-5.swf.trace b/test/trace/selection-focus-5.swf.trace
new file mode 100644
index 0000000..ece0e00
--- /dev/null
+++ b/test/trace/selection-focus-5.swf.trace
@@ -0,0 +1,30 @@
+null (null)
+false
+null
+ (): true
+null (null)
+true
+_level0 (true): false
+null (null)
+true
+ (): true
+null (null)
+true
+ (): true
+null (null)
+true
+ (): true
+null (null)
+true
+ (): true
+null (null)
+true
+ (): true
+null (null)
+true
+ (): true
+null (null)
+true
+ (): true
+null (null)
+true
diff --git a/test/trace/selection-focus-6.swf b/test/trace/selection-focus-6.swf
new file mode 100644
index 0000000..308a69b
Binary files /dev/null and b/test/trace/selection-focus-6.swf differ
diff --git a/test/trace/selection-focus-6.swf.trace b/test/trace/selection-focus-6.swf.trace
new file mode 100644
index 0000000..f6431f4
--- /dev/null
+++ b/test/trace/selection-focus-6.swf.trace
@@ -0,0 +1,32 @@
+null (null)
+false
+null
+ (): true
+null (null)
+true
+_level0 (true): false
+null (null)
+true
+_level0.a (): false
+null (null)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (false): false
+null (null)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+getter
+getter
+_level0.a (true): false
+_level0.a (string)
+true
diff --git a/test/trace/selection-focus-7.swf b/test/trace/selection-focus-7.swf
new file mode 100644
index 0000000..9b40d3c
Binary files /dev/null and b/test/trace/selection-focus-7.swf differ
diff --git a/test/trace/selection-focus-7.swf.trace b/test/trace/selection-focus-7.swf.trace
new file mode 100644
index 0000000..6b40b85
--- /dev/null
+++ b/test/trace/selection-focus-7.swf.trace
@@ -0,0 +1,32 @@
+null (null)
+false
+null
+undefined (undefined): true
+null (null)
+true
+_level0 (true): false
+null (null)
+true
+_level0.a (undefined): false
+null (null)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (false): false
+null (null)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+getter
+getter
+_level0.a (true): false
+_level0.a (string)
+true
diff --git a/test/trace/selection-focus-8.swf b/test/trace/selection-focus-8.swf
new file mode 100644
index 0000000..561978e
Binary files /dev/null and b/test/trace/selection-focus-8.swf differ
diff --git a/test/trace/selection-focus-8.swf.trace b/test/trace/selection-focus-8.swf.trace
new file mode 100644
index 0000000..6b40b85
--- /dev/null
+++ b/test/trace/selection-focus-8.swf.trace
@@ -0,0 +1,32 @@
+null (null)
+false
+null
+undefined (undefined): true
+null (null)
+true
+_level0 (true): false
+null (null)
+true
+_level0.a (undefined): false
+null (null)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (false): false
+null (null)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+_level0.a (true): false
+_level0.a (string)
+true
+getter
+getter
+_level0.a (true): false
+_level0.a (string)
+true
diff --git a/test/trace/selection-focus.as b/test/trace/selection-focus.as
new file mode 100644
index 0000000..5395229
--- /dev/null
+++ b/test/trace/selection-focus.as
@@ -0,0 +1,31 @@
+// makeswf -v 7 -s 200x150 -r 1 -o selection-focus.swf selection-focus.as
+
+function check(x) {
+  trace (x + " (" + x.focusEnabled + "): " + Selection.setFocus (x));
+  trace (Selection.getFocus () + " (" + typeof (Selection.getFocus ()) + ")");
+  trace (Selection.setFocus (null));
+};
+trace (Selection.getFocus () + " (" + typeof (Selection.getFocus ()) + ")");
+
+trace (Selection.setFocus ());
+trace (Selection.getFocus ());
+check (undefined);
+
+this.focusEnabled = true;
+check (this);
+createEmptyMovieClip ("a", 0);
+check (a);
+a.focusEnabled = true;
+check (a);
+a.focusEnabled = false;
+check (a);
+a.focusEnabled = true;
+check (a);
+delete a.tabEnabled;
+check (a);
+a.__proto__.focusEnabled = true;
+check (a);
+a.addProperty ("focusEnabled", function () { trace ("getter"); return true; }, null);
+check (a);
+
+getURL ("fscommand:quit", "");
commit 2a314d47bd24a5b15782c6de4078185f2b4be40e
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Mar 28 10:16:44 2008 +0100

    first step at focus implementation
    
    Selection.getFocus and Selection.setFocus work

diff --git a/swfdec/swfdec_as_strings.c b/swfdec/swfdec_as_strings.c
index 50db45a..8e6cb9c 100644
--- a/swfdec/swfdec_as_strings.c
+++ b/swfdec/swfdec_as_strings.c
@@ -491,5 +491,10 @@ const char swfdec_as_strings[] =
   SWFDEC_AS_CONSTANT_STRING ("height")
   SWFDEC_AS_CONSTANT_STRING ("deblocking")
   SWFDEC_AS_CONSTANT_STRING ("smoothing")
+  SWFDEC_AS_CONSTANT_STRING ("onKillFocus")
+  SWFDEC_AS_CONSTANT_STRING ("onSetFocus")
+  SWFDEC_AS_CONSTANT_STRING ("Selection")
+  SWFDEC_AS_CONSTANT_STRING ("tabEnabled")
+  SWFDEC_AS_CONSTANT_STRING ("focusEnabled")
   /* add more here */
 ;
diff --git a/swfdec/swfdec_movie.c b/swfdec/swfdec_movie.c
index c4d0b55..01c02cf 100644
--- a/swfdec/swfdec_movie.c
+++ b/swfdec/swfdec_movie.c
@@ -42,6 +42,7 @@
 #include "swfdec_sprite_movie.h"
 #include "swfdec_resource.h"
 #include "swfdec_system.h"
+#include "swfdec_text_field_movie.h"
 #include "swfdec_utils.h"
 #include "swfdec_as_internal.h"
 
@@ -797,6 +798,31 @@ swfdec_movie_do_contains (SwfdecMovie *movie, double x, double y, gboolean event
   return NULL;
 }
 
+gboolean
+swfdec_movie_can_focus (SwfdecMovie *movie)
+{
+  SwfdecAsValue val;
+
+  g_return_val_if_fail (SWFDEC_IS_MOVIE (movie), FALSE);
+
+  /* FIXME: subclass plz? */
+  if (!SWFDEC_IS_TEXT_FIELD_MOVIE (movie) &&
+      !SWFDEC_IS_BUTTON_MOVIE (movie) &&
+      !SWFDEC_IS_SPRITE_MOVIE (movie))
+    return FALSE;
+
+  /* apparently root movies can't receive focus? */
+  if (movie->parent == NULL)
+    return FALSE;
+
+  if (!swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (movie),
+	SWFDEC_AS_STR_focusEnabled, &val) ||
+      swfdec_as_value_to_boolean (SWFDEC_AS_OBJECT (movie)->context, &val) == FALSE)
+    return FALSE;
+
+  return TRUE;
+}
+
 static gboolean
 swfdec_movie_needs_group (SwfdecMovie *movie)
 {
diff --git a/swfdec/swfdec_movie.h b/swfdec/swfdec_movie.h
index 296e495..f7da3f7 100644
--- a/swfdec/swfdec_movie.h
+++ b/swfdec/swfdec_movie.h
@@ -182,10 +182,8 @@ struct _SwfdecMovieClass {
 						 double			x,
 						 double			y);
   /* keyboard handling */
-  void			(* focus_in)		(SwfdecMovie *		movie,
-						 SwfdecMovie *		previous);
-  void			(* focus_out)		(SwfdecMovie *		movie,
-						 SwfdecMovie *		next);
+  void			(* focus_in)		(SwfdecMovie *		movie);
+  void			(* focus_out)		(SwfdecMovie *		movie);
   void			(* key_pressed)		(SwfdecMovie *		movie,
 						 guint			keycode,
 						 guint			character);
@@ -253,6 +251,7 @@ void		swfdec_movie_rect_global_to_local (SwfdecMovie *	movie,
 void		swfdec_movie_set_depth		(SwfdecMovie *		movie,
 						 int			depth);
 
+gboolean	swfdec_movie_can_focus		(SwfdecMovie *		movie);
 void		swfdec_movie_get_mouse		(SwfdecMovie *		movie,
 						 double *		x,
 						 double *		y);
diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 92b1011..982002b 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -1025,26 +1025,96 @@ swfdec_player_dispose (GObject *object)
 }
 
 static void
-swfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, const char *signal)
+swfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, const char *signal,
+    guint argc, SwfdecAsValue *argv)
 {
   GSList *walk;
-  SwfdecAsValue val;
+  SwfdecAsValue vals[3];
   SwfdecAsObject *obj;
 
+  /* FIXME: extend when needed, by increasing the array size above */
+  g_return_if_fail (argc <= 2);
+
+  if (argc > 0) {
+    memcpy (&vals[1], argv, argc * sizeof (SwfdecAsValue));
+  }
+
   SWFDEC_DEBUG ("broadcasting message %s.%s", object_name, signal);
+  /* FIXME: sandbox ordering? */
   for (walk = player->priv->sandboxes; walk; walk = walk->next) {
     SwfdecSandbox *sandbox = walk->data;
-    swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (sandbox), object_name, &val);
-    if (!SWFDEC_AS_VALUE_IS_OBJECT (&val))
+    swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (sandbox), object_name, &vals[0]);
+    if (!SWFDEC_AS_VALUE_IS_OBJECT (&vals[0]))
       return;
-    obj = SWFDEC_AS_VALUE_GET_OBJECT (&val);
-    SWFDEC_AS_VALUE_SET_STRING (&val, signal);
+    obj = SWFDEC_AS_VALUE_GET_OBJECT (&vals[0]);
+    SWFDEC_AS_VALUE_SET_STRING (&vals[0], signal);
     swfdec_sandbox_use (sandbox);
-    swfdec_as_object_call (obj, SWFDEC_AS_STR_broadcastMessage, 1, &val, NULL);
+    swfdec_as_object_call (obj, SWFDEC_AS_STR_broadcastMessage, argc + 1, vals, NULL);
     swfdec_sandbox_unuse (sandbox);
   }
 }
 
+/**
+ * swfdec_player_grab_focus:
+ * @player: the player
+ * @movie: the movie to give focus or %NULL to unset focus
+ *
+ * This function handles passing the focus around. It is supposed to be called
+ * by all functions that wish to change keyboard focus. Note that only the 
+ * currently focused movie receives keyboard events - i.e. key_pressed and 
+ * key_released vfuncs.
+ **/
+void
+swfdec_player_grab_focus (SwfdecPlayer *player, SwfdecMovie *movie)
+{
+  SwfdecAsValue vals[2];
+  SwfdecPlayerPrivate *priv;
+  SwfdecMovieClass *klass;
+  SwfdecMovie *prev;
+
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+  g_return_if_fail (movie == NULL || SWFDEC_IS_MOVIE (movie));
+
+  /* set variables */
+  priv = player->priv;
+  if (movie == priv->focus) {
+    SWFDEC_DEBUG ("nothing to do, focus change request from movie %s to itself", movie ? movie->name : "---");
+    return;
+  }
+  prev = priv->focus;
+  if (prev) {
+    SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], SWFDEC_AS_OBJECT (prev));
+  } else {
+    SWFDEC_AS_VALUE_SET_NULL (&vals[0]);
+  }
+  if (movie) {
+    SWFDEC_AS_VALUE_SET_OBJECT (&vals[1], SWFDEC_AS_OBJECT (movie));
+  } else {
+    SWFDEC_AS_VALUE_SET_NULL (&vals[1]);
+  }
+  if (prev) {
+    swfdec_sandbox_use (prev->resource->sandbox);
+    swfdec_as_object_call (SWFDEC_AS_OBJECT (prev), SWFDEC_AS_STR_onKillFocus,
+	1, &vals[1], NULL);
+    swfdec_sandbox_unuse (prev->resource->sandbox);
+    klass = SWFDEC_MOVIE_GET_CLASS (prev);
+    if (klass->focus_out)
+      klass->focus_out (prev);
+  }
+  priv->focus_previous = prev;
+  priv->focus = movie;
+  if (movie) {
+    swfdec_sandbox_use (movie->resource->sandbox);
+    swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_STR_onSetFocus,
+	1, &vals[0], NULL);
+    swfdec_sandbox_unuse (movie->resource->sandbox);
+    klass = SWFDEC_MOVIE_GET_CLASS (movie);
+    if (klass->focus_in)
+      klass->focus_in (movie);
+  }
+  swfdec_player_broadcast (player, SWFDEC_AS_STR_Selection, SWFDEC_AS_STR_onSetFocus, 2, vals);
+}
+
 static void
 swfdec_player_update_mouse_cursor (SwfdecPlayer *player)
 {
@@ -1184,7 +1254,7 @@ swfdec_player_do_mouse_move (SwfdecPlayer *player, double x, double y)
     for (walk = priv->movies; walk; walk = walk->next) {
       swfdec_movie_queue_script (walk->data, SWFDEC_EVENT_MOUSE_MOVE);
     }
-    swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_onMouseMove);
+    swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_onMouseMove, 0, NULL);
   }
   swfdec_player_grab_mouse_movie (player);
   if (priv->mouse_grab) {
@@ -1210,7 +1280,7 @@ swfdec_player_do_mouse_press (SwfdecPlayer *player, guint button)
     for (walk = priv->movies; walk; walk = walk->next) {
       swfdec_movie_queue_script (walk->data, SWFDEC_EVENT_MOUSE_DOWN);
     }
-    swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_onMouseDown);
+    swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_onMouseDown, 0, NULL);
   }
   if (priv->mouse_grab) {
     SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (priv->mouse_grab);
@@ -1233,7 +1303,7 @@ swfdec_player_do_mouse_release (SwfdecPlayer *player, guint button)
     for (walk = priv->movies; walk; walk = walk->next) {
       swfdec_movie_queue_script (walk->data, SWFDEC_EVENT_MOUSE_UP);
     }
-    swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_onMouseUp);
+    swfdec_player_broadcast (player, SWFDEC_AS_STR_Mouse, SWFDEC_AS_STR_onMouseUp, 0, NULL);
   }
   if (priv->mouse_grab) {
     SwfdecMovieClass *klass = SWFDEC_MOVIE_GET_CLASS (priv->mouse_grab);
@@ -1311,7 +1381,8 @@ swfdec_player_do_handle_key (SwfdecPlayer *player, guint keycode, guint characte
   } else {
     priv->key_pressed[keycode / 8] &= ~(1 << keycode % 8);
   }
-  swfdec_player_broadcast (player, SWFDEC_AS_STR_Key, down ? SWFDEC_AS_STR_onKeyDown : SWFDEC_AS_STR_onKeyUp);
+  swfdec_player_broadcast (player, SWFDEC_AS_STR_Key, 
+      down ? SWFDEC_AS_STR_onKeyDown : SWFDEC_AS_STR_onKeyUp, 0, NULL);
   swfdec_player_perform_actions (player);
   swfdec_player_unlock (player);
 
@@ -2742,7 +2813,7 @@ swfdec_player_update_size (gpointer playerp, gpointer unused)
 
   priv->broadcasted_width = priv->internal_width;
   priv->broadcasted_height = priv->internal_height;
-  swfdec_player_broadcast (player, SWFDEC_AS_STR_Stage, SWFDEC_AS_STR_onResize);
+  swfdec_player_broadcast (player, SWFDEC_AS_STR_Stage, SWFDEC_AS_STR_onResize, 0, NULL);
 }
 
 /**
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index c5c9b8c..c351603 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -121,6 +121,9 @@ struct _SwfdecPlayerPrivate
   guint			last_keycode;		/* last keycode that was pressed/released */
   guint			last_character;		/* UCS4 of last character pressed/released */
   guint8		key_pressed[256/8];   	/* boolean array for isDown */
+  SwfdecMovie *		focus;			/* movie that currently has keyboard focus (or NULL if none) */
+  SwfdecMovie *		focus_previous;		/* the last movie that had focus */
+  GList *		focus_list;	      	/* list of movies with a tabIndex set or NULL for no tabIndex usage */
 
   /* audio */
   GList *		audio;		 	/* list of playing SwfdecAudio */
@@ -181,6 +184,8 @@ SwfdecSocket *	swfdec_player_create_socket	(SwfdecPlayer *		player,
 						 const char *		hostname,
 						 guint			port);
 
+void		swfdec_player_grab_focus	(SwfdecPlayer *		player,
+						 SwfdecMovie *		movie);
 #define swfdec_player_is_mouse_pressed(player) ((player)->priv->mouse_button & 1)
 void		swfdec_player_invalidate	(SwfdecPlayer *		player,
 						 const SwfdecRect *	rect);
diff --git a/swfdec/swfdec_selection.c b/swfdec/swfdec_selection.c
index e23e494..d3343be 100644
--- a/swfdec/swfdec_selection.c
+++ b/swfdec/swfdec_selection.c
@@ -25,6 +25,9 @@
 #include "swfdec_as_strings.h"
 #include "swfdec_as_context.h"
 #include "swfdec_debug.h"
+#include "swfdec_movie.h"
+#include "swfdec_player_internal.h"
+#include "swfdec_sandbox.h"
 
 SWFDEC_AS_NATIVE (600, 0, swfdec_selection_getBeginIndex)
 void
@@ -55,7 +58,14 @@ void
 swfdec_selection_getFocus (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SWFDEC_STUB ("Selection.getFocus (static)");
+  SwfdecPlayerPrivate *priv = SWFDEC_PLAYER (cx)->priv;
+
+  if (priv->focus) {
+    char *s = swfdec_movie_get_path (priv->focus, TRUE);
+    SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_give_string (cx, s));
+  } else {
+    SWFDEC_AS_VALUE_SET_NULL (ret);
+  }
 }
 
 SWFDEC_AS_NATIVE (600, 4, swfdec_selection_setFocus)
@@ -63,7 +73,26 @@ void
 swfdec_selection_setFocus (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  SWFDEC_STUB ("Selection.setFocus (static)");
+  SwfdecMovie *movie;
+  SwfdecSandbox *sandbox;
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, FALSE);
+  SWFDEC_AS_CHECK (0, NULL, "O", &movie);
+
+  if (movie != NULL &&
+      (!SWFDEC_IS_MOVIE (movie) ||
+      !swfdec_movie_can_focus (movie)))
+    return;
+
+  /* FIXME: how is security handled here? */
+  sandbox = SWFDEC_SANDBOX (cx->global);
+  swfdec_sandbox_unuse (sandbox);
+  swfdec_player_grab_focus (SWFDEC_PLAYER (cx), movie);
+  swfdec_sandbox_use (sandbox);
+  if (movie == NULL) {
+    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, TRUE);
+  }
+  return;
 }
 
 SWFDEC_AS_NATIVE (600, 5, swfdec_selection_setSelection)
commit 56b5f8b11e160b636f38a3e55134baeb7ce1cb13
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 27 13:40:25 2008 +0100

    remove more outdated code

diff --git a/swfdec/swfdec_tag.c b/swfdec/swfdec_tag.c
index 9c5b8c9..16582e9 100644
--- a/swfdec/swfdec_tag.c
+++ b/swfdec/swfdec_tag.c
@@ -252,190 +252,6 @@ tag_func_define_sprite (SwfdecSwfDecoder * s, guint define_sprite_tag)
   return SWFDEC_STATUS_OK;
 }
 
-#if 0
-static int
-tag_func_define_button_2 (SwfdecSwfDecoder * s, guint tag)
-{
-  SwfdecBits bits;
-  int id, reserved;
-  guint length;
-  SwfdecButton *button;
-  char *script_name;
-
-  id = swfdec_bits_get_u16 (&s->b);
-  button = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_BUTTON);
-  if (!button)
-    return SWFDEC_STATUS_OK;
-
-  SWFDEC_LOG ("  ID: %d", id);
-
-  reserved = swfdec_bits_getbits (&s->b, 7);
-  button->menubutton = swfdec_bits_getbit (&s->b) ? TRUE : FALSE;
-  length = swfdec_bits_get_u16 (&s->b);
-
-  SWFDEC_LOG ("  reserved = %d", reserved);
-  SWFDEC_LOG ("  menu = %d", button->menubutton);
-  SWFDEC_LOG ("  length of region = %d", length);
-
-  if (length)
-    swfdec_bits_init_bits (&bits, &s->b, length > 2 ? length - 2 : 0);
-  else
-    swfdec_bits_init_bits (&bits, &s->b, swfdec_bits_left (&s->b) / 8);
-  while (swfdec_bits_peek_u8 (&bits)) {
-    guint character;
-    guint depth;
-    guint states;
-    gboolean has_blend_mode, has_filters;
-    SwfdecContent *content;
-
-    if (s->version >= 8) {
-      reserved = swfdec_bits_getbits (&bits, 2);
-      has_blend_mode = swfdec_bits_getbit (&bits);
-      has_filters = swfdec_bits_getbit (&bits);
-      SWFDEC_LOG ("  reserved = %d", reserved);
-      SWFDEC_LOG ("  has_blend_mode = %d", has_blend_mode);
-      SWFDEC_LOG ("  has_filters = %d", has_filters);
-    } else {
-      reserved = swfdec_bits_getbits (&bits, 4);
-      has_blend_mode = 0;
-      has_filters = 0;
-      SWFDEC_LOG ("  reserved = %d", reserved);
-    }
-    states = swfdec_bits_getbits (&bits, 4);
-    character = swfdec_bits_get_u16 (&bits);
-    depth = swfdec_bits_get_u16 (&bits);
-
-    SWFDEC_LOG ("  states: %s%s%s%scharacter=%u layer=%u",
-        states & (1 << SWFDEC_BUTTON_HIT) ? "HIT " : "", 
-	states & (1 << SWFDEC_BUTTON_DOWN) ? "DOWN " : "", 
-        states & (1 << SWFDEC_BUTTON_OVER) ? "OVER " : "",
-	states & (1 << SWFDEC_BUTTON_UP) ? "UP " : "", 
-	character, depth);
-    content = swfdec_content_new (depth);
-
-    swfdec_bits_get_matrix (&bits, &content->transform, NULL);
-    content->has_transform = TRUE;
-    SWFDEC_LOG ("matrix: %g %g  %g %g   %g %g",
-	content->transform.xx, content->transform.yy, 
-	content->transform.xy, content->transform.yx,
-	content->transform.x0, content->transform.y0);
-    swfdec_bits_get_color_transform (&bits, &content->color_transform);
-    content->has_color_transform = TRUE;
-
-    content->graphic = swfdec_swf_decoder_get_character (s, character);
-    if (has_blend_mode) {
-      content->blend_mode = swfdec_bits_get_u8 (&bits);
-      SWFDEC_LOG ("  blend mode = %u", content->blend_mode);
-    }
-    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);
-    } else {
-      swfdec_button_append_content (button, states, content);
-    }
-  }
-  swfdec_bits_get_u8 (&bits);
-  if (swfdec_bits_left (&bits)) {
-    SWFDEC_WARNING ("%u bytes left when parsing button records", swfdec_bits_left (&bits) / 8);
-  }
-
-  script_name = g_strdup_printf ("Button%u", SWFDEC_CHARACTER (button)->id);
-  while (length != 0) {
-    guint condition, key;
-
-    length = swfdec_bits_get_u16 (&s->b);
-    if (length)
-      swfdec_bits_init_bits (&bits, &s->b, length > 2 ? length - 2 : 0);
-    else
-      swfdec_bits_init_bits (&bits, &s->b, swfdec_bits_left (&s->b) / 8);
-    condition = swfdec_bits_get_u16 (&bits);
-    key = condition >> 9;
-    condition &= 0x1FF;
-
-    SWFDEC_LOG (" length = %d", length);
-
-    if (button->events == NULL)
-      button->events = swfdec_event_list_new (SWFDEC_DECODER (s)->player);
-    SWFDEC_LOG ("  new event for condition %u (key %u)", condition, key);
-    swfdec_event_list_parse (button->events, &bits, s->version, condition, key,
-	script_name);
-    if (swfdec_bits_left (&bits)) {
-      SWFDEC_WARNING ("%u bytes left after parsing script", swfdec_bits_left (&bits) / 8);
-    }
-  }
-  g_free (script_name);
-
-  return SWFDEC_STATUS_OK;
-}
-
-static int
-tag_func_define_button (SwfdecSwfDecoder * s, guint tag)
-{
-  SwfdecBits *bits = &s->b;
-  int id;
-  SwfdecButton *button;
-  char *script_name;
-
-  id = swfdec_bits_get_u16 (bits);
-  button = swfdec_swf_decoder_create_character (s, id, SWFDEC_TYPE_BUTTON);
-  if (!button)
-    return SWFDEC_STATUS_OK;
-
-  SWFDEC_LOG ("  ID: %d", id);
-
-  while (swfdec_bits_peek_u8 (bits)) {
-    int reserved;
-    guint character;
-    guint depth;
-    guint states;
-    SwfdecContent *content;
-
-    swfdec_bits_syncbits (bits);
-    reserved = swfdec_bits_getbits (bits, 4);
-    states = swfdec_bits_getbits (bits, 4);
-    character = swfdec_bits_get_u16 (bits);
-    depth = swfdec_bits_get_u16 (bits);
-
-    SWFDEC_LOG ("  reserved = %d", reserved);
-    SWFDEC_LOG ("states: %s%s%s%scharacter=%u layer=%u",
-        states & (1 << SWFDEC_BUTTON_HIT) ? "HIT " : "", 
-	states & (1 << SWFDEC_BUTTON_DOWN) ? "DOWN " : "", 
-        states & (1 << SWFDEC_BUTTON_OVER) ? "OVER " : "",
-	states & (1 << SWFDEC_BUTTON_UP) ? "UP " : "", 
-	character, depth);
-    content = swfdec_content_new (depth);
-
-    swfdec_bits_get_matrix (bits, &content->transform, NULL);
-    content->has_transform = TRUE;
-    SWFDEC_LOG ("matrix: %g %g  %g %g   %g %g",
-	content->transform.xx, content->transform.yy, 
-	content->transform.xy, content->transform.yx,
-	content->transform.x0, content->transform.y0);
-
-    content->graphic = swfdec_swf_decoder_get_character (s, character);
-    if (!SWFDEC_IS_GRAPHIC (content->graphic)) {
-      SWFDEC_ERROR ("id %u does not reference a graphic, ignoring", character);
-      swfdec_content_free (content);
-    } else {
-      swfdec_button_append_content (button, states, content);
-    }
-  }
-  swfdec_bits_get_u8 (bits);
-
-  script_name = g_strdup_printf ("Button%u", SWFDEC_CHARACTER (button)->id);
-  button->events = swfdec_event_list_new (SWFDEC_DECODER (s)->player);
-  swfdec_event_list_parse (button->events, &s->b, s->version, 
-      SWFDEC_BUTTON_OVER_UP_TO_OVER_DOWN, 0, script_name);
-  g_free (script_name);
-
-  return SWFDEC_STATUS_OK;
-}
-#endif
-
 static int
 tag_func_file_attributes (SwfdecSwfDecoder *s, guint tag)
 {
commit ab81bea0e9f3325cf5963da70fc2e9c8d0ef3047
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 27 13:38:55 2008 +0100

    remove outdated leftover files

diff --git a/swfdec/swfdec_debugger.c b/swfdec/swfdec_debugger.c
deleted file mode 100644
index 2dca1df..0000000
--- a/swfdec/swfdec_debugger.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/* Swfdec
- * Copyright (C) 2006 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 <string.h>
-#include "swfdec_debugger.h"
-#include "swfdec_as_context.h"
-#include "swfdec_as_frame_internal.h"
-#include "swfdec_as_interpret.h"
-#include "swfdec_debug.h"
-#include "swfdec_decoder.h"
-#include "swfdec_movie.h"
-#include "swfdec_player_internal.h"
-
-enum {
-  SCRIPT_ADDED,
-  SCRIPT_REMOVED,
-  BREAKPOINT,
-  BREAKPOINT_ADDED,
-  BREAKPOINT_REMOVED,
-  MOVIE_ADDED,
-  MOVIE_REMOVED,
-  LAST_SIGNAL
-};
-
-G_DEFINE_TYPE (SwfdecDebugger, swfdec_debugger, SWFDEC_TYPE_PLAYER)
-static guint signals[LAST_SIGNAL] = { 0, };
-
-/*** SwfdecDebuggerScript ***/
-
-typedef struct {
-  guint			version;	/* version of parsed file */
-  SwfdecConstantPool *	constant_pool;	/* current constant pool */
-  GArray *		commands;	/* SwfdecDebuggerCommands parsed so far */
-} ScriptParser;
-
-static char *
-swfdec_debugger_print_push (ScriptParser *parser, const guint8 *data, guint len)
-{
-  gboolean first = TRUE;
-  SwfdecBits bits;
-  GString *string = g_string_new ("Push");
-
-  swfdec_bits_init_data (&bits, data, len);
-  while (swfdec_bits_left (&bits)) {
-    guint type = swfdec_bits_get_u8 (&bits);
-    if (first)
-      g_string_append (string, " ");
-    else
-      g_string_append (string, ", ");
-    first = FALSE;
-    switch (type) {
-      case 0: /* string */
-	{
-	  char *s = swfdec_bits_get_string (&bits, parser->version);
-	  if (!s)
-	    goto error;
-	  g_string_append_c (string, '"');
-	  g_string_append (string, s);
-	  g_string_append_c (string, '"');
-	  g_free (s);
-	  break;
-	}
-      case 1: /* float */
-	g_string_append_printf (string, "%g", swfdec_bits_get_float (&bits));
-	break;
-      case 2: /* null */
-	g_string_append (string, "null");
-	break;
-      case 3: /* undefined */
-	g_string_append (string, "undefined");
-	break;
-      case 4: /* register */
-	g_string_append_printf (string, "Register %u", swfdec_bits_get_u8 (&bits));
-	break;
-      case 5: /* boolean */
-	g_string_append (string, swfdec_bits_get_u8 (&bits) ? "True" : "False");
-	break;
-      case 6: /* double */
-	g_string_append_printf (string, "%g", swfdec_bits_get_double (&bits));
-	break;
-      case 7: /* 32bit int */
-	g_string_append_printf (string, "%d", swfdec_bits_get_u32 (&bits));
-	break;
-      case 8: /* 8bit ConstantPool address */
-      case 9: /* 16bit ConstantPool address */
-	{
-	  guint id;
-	  const char *s;
-
-	  if (!parser->constant_pool) {
-	    SWFDEC_ERROR ("no constant pool");
-	    goto error;
-	  }
-	  id = type == 8 ? swfdec_bits_get_u8 (&bits) : swfdec_bits_get_u16 (&bits);
-	  if (id >= swfdec_constant_pool_size (parser->constant_pool)) {
-	    SWFDEC_ERROR ("constant pool size too small");
-	    goto error;
-	  }
-	  s = swfdec_constant_pool_get (parser->constant_pool, id);
-	  g_string_append_c (string, '"');
-	  g_string_append (string, s);
-	  g_string_append_c (string, '"');
-	}
-	break;
-      default:
-	SWFDEC_ERROR ("Push: type %u not implemented", type);
-	goto error;
-    }
-  }
-  return g_string_free (string, FALSE);
-
-error:
-  g_string_free (string, TRUE);
-  return g_strdup ("erroneous action Push");
-}
-
-/* NB: constant pool actions are special in that they are called at init time */
-static gboolean
-swfdec_debugger_add_command (gconstpointer bytecode, guint action, 
-    const guint8 *data, guint len, gpointer parserp)
-{
-  ScriptParser *parser = parserp;
-  SwfdecDebuggerCommand command;
-
-  command.code = bytecode;
-  if (action == SWFDEC_AS_ACTION_PUSH) {
-    command.description = swfdec_debugger_print_push (parser, data, len);
-  } else {
-    command.description = swfdec_script_print_action (action, data, len);
-  }
-  g_assert (command.description != NULL);
-  g_array_append_val (parser->commands, command);
-  if (action == SWFDEC_AS_ACTION_CONSTANT_POOL) {
-    if (parser->constant_pool)
-      swfdec_constant_pool_free (parser->constant_pool);
-    parser->constant_pool = swfdec_constant_pool_new_from_action (data, len, parser->version);
-  }
-  return TRUE;
-}
-
-static SwfdecDebuggerScript *
-swfdec_debugger_script_new (SwfdecScript *script)
-{
-  ScriptParser parser;
-  SwfdecDebuggerScript *ret;
-
-  ret = g_new0 (SwfdecDebuggerScript, 1);
-  ret->script = script;
-  swfdec_script_ref (script);
-  parser.commands = g_array_new (TRUE, FALSE, sizeof (SwfdecDebuggerCommand));
-  parser.version = script->version;
-  if (script->constant_pool) {
-    parser.constant_pool = swfdec_constant_pool_new_from_action (
-	script->constant_pool->data, script->constant_pool->length, parser.version);
-  } else {
-    parser.constant_pool = NULL;
-  }
-  swfdec_script_foreach (script, swfdec_debugger_add_command, &parser);
-  ret->n_commands = parser.commands->len;
-  ret->commands = (SwfdecDebuggerCommand *) g_array_free (parser.commands, FALSE);
-  if (parser.constant_pool)
-    swfdec_constant_pool_free (parser.constant_pool);
-
-  return ret;
-}
-
-static void
-swfdec_debugger_script_free (SwfdecDebuggerScript *script)
-{
-  guint i;
-
-  g_assert (script);
-  swfdec_script_unref (script->script);
-  for (i = 0; i < script->n_commands; i++) {
-    g_free (script->commands[i].description);
-  }
-  g_free (script->commands);
-  g_free (script);
-}
-
-/*** BREAKPOINTS ***/
-
-typedef enum {
-  BREAKPOINT_NONE,
-  BREAKPOINT_PC
-} BreakpointType;
-
-typedef struct {
-  BreakpointType	type;
-  const guint8 *	pc;
-} Breakpoint;
-
-static void
-swfdec_debugger_update_interrupting (SwfdecDebugger *debugger)
-{
-  guint i;
-  
-  debugger->has_breakpoints = debugger->stepping;
-
-  for (i = 0; i < debugger->breakpoints->len && !debugger->has_breakpoints; i++) {
-    Breakpoint *br = &g_array_index (debugger->breakpoints, Breakpoint, i);
-
-    if (br->type != BREAKPOINT_NONE)
-      debugger->has_breakpoints = TRUE;
-  }
-}
-
-guint
-swfdec_debugger_set_breakpoint (SwfdecDebugger *debugger, 
-    SwfdecDebuggerScript *script, guint line)
-{
-  guint i;
-  Breakpoint *br = NULL;
-
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), 0);
-  g_return_val_if_fail (script != NULL, 0);
-  g_return_val_if_fail (line < script->n_commands, 0);
-
-  for (i = 0; i < debugger->breakpoints->len; i++) {
-    br = &g_array_index (debugger->breakpoints, Breakpoint, i);
-    if (br->type == BREAKPOINT_NONE)
-      break;
-    br = NULL;
-  }
-
-  if (br == NULL) {
-    g_array_set_size (debugger->breakpoints, debugger->breakpoints->len + 1);
-    br = &g_array_index (debugger->breakpoints, Breakpoint, 
-	debugger->breakpoints->len - 1);
-  }
-  br->type = BREAKPOINT_PC;
-  br->pc = script->commands[line].code;
-  swfdec_debugger_update_interrupting (debugger);
-  g_signal_emit (debugger, signals[BREAKPOINT_ADDED], 0, i + 1);
-  return i + 1;
-}
-
-void
-swfdec_debugger_unset_breakpoint (SwfdecDebugger *debugger, guint id)
-{
-  Breakpoint *br;
-
-  g_return_if_fail (SWFDEC_IS_DEBUGGER (debugger));
-  g_return_if_fail (id > 0);
-
-  if (debugger->breakpoints == NULL)
-    return;
-  if (id > debugger->breakpoints->len)
-    return;
-  br = &g_array_index (debugger->breakpoints, Breakpoint, id - 1);
-  if (br->type == BREAKPOINT_NONE)
-    return;
-
-  g_signal_emit (debugger, signals[BREAKPOINT_REMOVED], 0, id);
-  br->type = BREAKPOINT_NONE;
-  swfdec_debugger_update_interrupting (debugger);
-}
-
-static gboolean
-swfdec_debugger_get_from_as (SwfdecDebugger *debugger, SwfdecScript *script, 
-    const guint8 *pc, SwfdecDebuggerScript **script_out, guint *line_out)
-{
-  guint line;
-  SwfdecDebuggerScript *dscript = swfdec_debugger_get_script (debugger, script);
-
-  if (dscript == NULL)
-    return FALSE;
-  for (line = 0; line < dscript->n_commands; line++) {
-    if (pc == dscript->commands[line].code) {
-      if (script_out)
-	*script_out = dscript;
-      if (line_out)
-	*line_out = line;
-      return TRUE;
-    }
-    if (pc < (guint8 *) dscript->commands[line].code)
-      return FALSE;
-  }
-  return FALSE;
-}
-
-gboolean
-swfdec_debugger_get_current (SwfdecDebugger *debugger,
-    SwfdecDebuggerScript **dscript, guint *line)
-{
-  SwfdecAsFrame *frame;
-
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), FALSE);
-
-  frame = SWFDEC_AS_CONTEXT (debugger)->frame;
-  if (frame == NULL)
-    return FALSE;
-  if (frame->script == NULL) /* native function */
-    return FALSE;
-  return swfdec_debugger_get_from_as (debugger, frame->script, frame->pc, dscript, line);
-}
-
-typedef struct {
-  const guint8 *pc;
-  SwfdecScript *current;
-} BreakpointFinder;
-
-static void
-swfdec_debugger_find_script (gpointer key, gpointer value, gpointer data)
-{
-  BreakpointFinder *find = data;
-  SwfdecScript *script = key;
-
-  if (script->buffer->data > find->pc ||
-      find->pc >= (script->buffer->data + script->buffer->length))
-    return;
-  if (find->current == NULL ||
-      find->current->buffer->length > script->buffer->length)
-    find->current = script;
-}
-
-gboolean
-swfdec_debugger_get_breakpoint (SwfdecDebugger *debugger, guint id, 
-    SwfdecDebuggerScript **script, guint *line)
-{
-  Breakpoint *br;
-  BreakpointFinder find = { NULL, NULL };
-
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), FALSE);
-  g_return_val_if_fail (id > 0, FALSE);
-
-  if (debugger->breakpoints == NULL)
-    return FALSE;
-  if (id > debugger->breakpoints->len)
-    return FALSE;
-  br = &g_array_index (debugger->breakpoints, Breakpoint, id - 1);
-  if (br->type == BREAKPOINT_NONE)
-    return FALSE;
-
-  find.pc = br->pc;
-  g_hash_table_foreach (debugger->scripts, swfdec_debugger_find_script, &find);
-  if (find.current == NULL)
-    return FALSE;
-  return swfdec_debugger_get_from_as (debugger, find.current, find.pc, script, line);
-}
-
-guint
-swfdec_debugger_get_n_breakpoints (SwfdecDebugger *debugger)
-{
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), 0);
-
-  if (debugger->breakpoints == NULL)
-    return 0;
-
-  return debugger->breakpoints->len;
-}
-
-/*** SwfdecDebugger ***/
-
-static void
-swfdec_debugger_dispose (GObject *object)
-{
-  SwfdecDebugger *debugger = SWFDEC_DEBUGGER (object);
-
-  swfdec_debugger_set_stepping (debugger, FALSE);
-  g_assert (g_hash_table_size (debugger->scripts) == 0);
-  g_hash_table_destroy (debugger->scripts);
-  if (debugger->breakpoints)
-    g_array_free (debugger->breakpoints, TRUE);
-
-  G_OBJECT_CLASS (swfdec_debugger_parent_class)->dispose (object);
-}
-
-#if 0
-static void
-swfdec_debugger_do_breakpoint (SwfdecDebugger *debugger, guint id)
-{
-  SwfdecPlayer *player = SWFDEC_PLAYER (debugger);
-
-  GList *walk;
-  for (walk = player->roots; walk; walk = walk->next) {
-    swfdec_movie_update (walk->data);
-  }
-  g_object_thaw_notify (G_OBJECT (debugger));
-  if (!swfdec_rect_is_empty (&player->invalid)) {
-    double x, y, width, height;
-    x = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x0);
-    y = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y0);
-    width = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x1 - player->invalid.x0);
-    height = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y1 - player->invalid.y0);
-    g_signal_emit_by_name (player, "invalidate", x, y, width, height);
-    swfdec_rect_init_empty (&player->invalid);
-  }
-
-  g_signal_emit (debugger, signals[BREAKPOINT], 0, id);
-
-  g_object_freeze_notify (G_OBJECT (debugger));
-}
-
-static void
-swfdec_debugger_step (SwfdecAsContext *context)
-{
-  SwfdecDebugger *debugger = SWFDEC_DEBUGGER (context);
-
-  if (context->state != SWFDEC_AS_CONTEXT_RUNNING)
-    return;
-  if (!debugger->has_breakpoints)
-    return;
-
-  if (debugger->stepping) {
-    swfdec_debugger_do_breakpoint (debugger, 0);
-  } else {
-    guint i;
-    Breakpoint *br;
-    const guint8 *pc = context->frame->pc;
-
-    for (i = 0; i < debugger->breakpoints->len; i++) {
-      br = &g_array_index (debugger->breakpoints, Breakpoint, i);
-      if (br->type == BREAKPOINT_NONE)
-	continue;
-      if (br->pc == pc) {
-	swfdec_debugger_do_breakpoint (debugger, i + 1);
-	return;
-      }
-    }
-  }
-}
-#endif
-
-static void
-swfdec_debugger_class_init (SwfdecDebuggerClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->dispose = swfdec_debugger_dispose;
-
-  signals[SCRIPT_ADDED] = g_signal_new ("script-added", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER,
-      G_TYPE_NONE, 1, G_TYPE_POINTER);
-  signals[SCRIPT_REMOVED] = g_signal_new ("script-removed", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER,
-      G_TYPE_NONE, 1, G_TYPE_POINTER);
-  signals[BREAKPOINT] = g_signal_new ("breakpoint", 
-      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
-      g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
-  signals[BREAKPOINT_ADDED] = g_signal_new ("breakpoint-added", 
-      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
-      g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
-  signals[BREAKPOINT_REMOVED] = g_signal_new ("breakpoint-removed", 
-      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
-      g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
-  signals[MOVIE_ADDED] = g_signal_new ("movie-added", 
-      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
-      g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
-  signals[MOVIE_REMOVED] = g_signal_new ("movie-removed", 
-      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, 
-      g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
-}
-
-static void
-swfdec_debugger_init (SwfdecDebugger *debugger)
-{
-  debugger->scripts = g_hash_table_new_full (g_direct_hash, g_direct_equal, 
-      NULL, (GDestroyNotify) swfdec_debugger_script_free);
-  debugger->breakpoints = g_array_new (FALSE, FALSE, sizeof (Breakpoint));
-}
-
-/**
- * swfdec_debugger_new:
- *
- * Creates a #SwfdecPlayer that can be debugged.
- *
- * Returns: a new #SwfdecDebugger
- **/
-SwfdecPlayer *
-swfdec_debugger_new (void)
-{
-  SwfdecPlayer *player;
-
-  swfdec_init ();
-  player = g_object_new (SWFDEC_TYPE_DEBUGGER, NULL);
-  return player;
-}
-
-void
-swfdec_debugger_add_script (SwfdecDebugger *debugger, SwfdecScript *script)
-{
-  SwfdecDebuggerScript *dscript = swfdec_debugger_script_new (script);
-
-  g_hash_table_insert (debugger->scripts, script, dscript);
-  g_signal_emit (debugger, signals[SCRIPT_ADDED], 0, dscript);
-}
-
-SwfdecDebuggerScript *
-swfdec_debugger_get_script (SwfdecDebugger *debugger, SwfdecScript *script)
-{
-  SwfdecDebuggerScript *dscript = g_hash_table_lookup (debugger->scripts, script);
-
-  return dscript;
-}
-
-void
-swfdec_debugger_remove_script (SwfdecDebugger *debugger, SwfdecScript *script)
-{
-  SwfdecDebuggerScript *dscript = g_hash_table_lookup (debugger->scripts, script);
-
-  g_assert (dscript);
-  g_signal_emit (debugger, signals[SCRIPT_REMOVED], 0, dscript);
-  g_hash_table_remove (debugger->scripts, script);
-}
-
-typedef struct {
-  GFunc func;
-  gpointer data;
-} ForeachData;
-
-static void
-do_foreach (gpointer key, gpointer value, gpointer data)
-{
-  ForeachData *fdata = data;
-
-  fdata->func (value, fdata->data);
-}
-
-void
-swfdec_debugger_foreach_script (SwfdecDebugger *debugger, GFunc func, gpointer data)
-{
-  ForeachData fdata = { func, data };
-  g_hash_table_foreach (debugger->scripts, do_foreach, &fdata);
-}
-
-void
-swfdec_debugger_set_stepping (SwfdecDebugger *debugger, gboolean stepping)
-{
-  g_return_if_fail (SWFDEC_IS_DEBUGGER (debugger));
-
-  if (debugger->stepping == stepping)
-    return;
-  debugger->stepping = stepping;
-}
-
-gboolean
-swfdec_debugger_get_stepping (SwfdecDebugger *debugger)
-{
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), FALSE);
-
-  return debugger->stepping;
-}
-
-const char *
-swfdec_debugger_run (SwfdecDebugger *debugger, const char *command)
-{
-  SwfdecPlayer *player;
-  GList *walk;
-
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), NULL);
-  g_return_val_if_fail (command != NULL, NULL);
-  
-  player = SWFDEC_PLAYER (debugger);
-  g_object_freeze_notify (G_OBJECT (debugger));
-
-
-  SWFDEC_ERROR ("ooops");
-
-
-  for (walk = player->roots; walk; walk = walk->next) {
-    swfdec_movie_update (walk->data);
-  }
-  if (!swfdec_rect_is_empty (&player->invalid)) {
-    double x, y, width, height;
-    x = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x0);
-    y = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y0);
-    width = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.x1 - player->invalid.x0);
-    height = SWFDEC_TWIPS_TO_DOUBLE (player->invalid.y1 - player->invalid.y0);
-    g_signal_emit_by_name (player, "invalidate", x, y, width, height);
-    swfdec_rect_init_empty (&player->invalid);
-  }
-  g_object_thaw_notify (G_OBJECT (debugger));
-
-  return command;
-}
-
-guint
-swfdec_debugger_script_has_breakpoint (SwfdecDebugger *debugger, 
-    SwfdecDebuggerScript *script, guint line)
-{
-  guint i;
-  const guint8 *pc;
-
-  g_return_val_if_fail (SWFDEC_IS_DEBUGGER (debugger), FALSE);
-  g_return_val_if_fail (script != NULL, FALSE);
-  g_return_val_if_fail (line < script->n_commands, FALSE);
-
-  pc = script->commands[line].code;
-  for (i = 0; i < debugger->breakpoints->len; i++) {
-    Breakpoint *br = &g_array_index (debugger->breakpoints, Breakpoint, i);
-
-    if (br->type == BREAKPOINT_PC && pc == br->pc)
-      return i + 1;
-  }
-  return 0;
-}
diff --git a/swfdec/swfdec_debugger.h b/swfdec/swfdec_debugger.h
deleted file mode 100644
index 00999ba..0000000
--- a/swfdec/swfdec_debugger.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Swfdec
- * Copyright (C) 2006 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_DEBUGGER_H_
-#define _SWFDEC_DEBUGGER_H_
-
-#include <glib-object.h>
-#include <swfdec/swfdec.h>
-#include <swfdec/swfdec_player_internal.h>
-#include <swfdec/swfdec_script.h>
-#include <swfdec/swfdec_types.h>
-
-G_BEGIN_DECLS
-
-//typedef struct _SwfdecDebugger SwfdecDebugger;
-typedef struct _SwfdecDebuggerClass SwfdecDebuggerClass;
-typedef struct _SwfdecDebuggerScript SwfdecDebuggerScript;
-typedef struct _SwfdecDebuggerCommand SwfdecDebuggerCommand;
-
-#define SWFDEC_TYPE_DEBUGGER                    (swfdec_debugger_get_type())
-#define SWFDEC_IS_DEBUGGER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_DEBUGGER))
-#define SWFDEC_IS_DEBUGGER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_DEBUGGER))
-#define SWFDEC_DEBUGGER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_DEBUGGER, SwfdecDebugger))
-#define SWFDEC_DEBUGGER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_DEBUGGER, SwfdecDebuggerClass))
-#define SWFDEC_DEBUGGER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_DEBUGGER, SwfdecDebuggerClass))
-
-struct _SwfdecDebuggerCommand {
-  const guint8 *	code;		/* pointer to start bytecode in SwfdecScript */
-  char *		description;	/* string describing the action */
-};
-
-struct _SwfdecDebuggerScript {
-  SwfdecScript *      	script;		/* the script */
-  SwfdecDebuggerCommand *commands;	/* commands executed in the script (NULL-terminated) */
-  guint			n_commands;	/* number of commands */
-};
-
-struct _SwfdecDebugger {
-  SwfdecPlayer		player;
-
-  GHashTable *		scripts;	/* JSScript => SwfdecDebuggerScript mapping */
-  GArray *		breakpoints;	/* all breakpoints */
-  gboolean		stepping;	/* TRUE if we're currently stepping through the code */
-  gboolean		has_breakpoints; /* performance: track if there's breakpoints */
-};
-
-struct _SwfdecDebuggerClass {
-  SwfdecPlayerClass   	player_class;
-};
-
-GType			swfdec_debugger_get_type        (void);
-SwfdecPlayer *		swfdec_debugger_new		(void);
-
-gboolean		swfdec_debugger_get_current	(SwfdecDebugger *	debugger,
-							 SwfdecDebuggerScript **dscript,
-							 guint *		line);
-guint			swfdec_debugger_set_breakpoint	(SwfdecDebugger *	debugger,
-							 SwfdecDebuggerScript *	script,
-							 guint			line);
-void			swfdec_debugger_unset_breakpoint
-							(SwfdecDebugger *	debugger,
-							 guint			id);
-gboolean		swfdec_debugger_get_breakpoint	(SwfdecDebugger *	debugger,
-							 guint			id,
-							 SwfdecDebuggerScript **script,
-							 guint *      		line);
-guint			swfdec_debugger_get_n_breakpoints
-							(SwfdecDebugger *	debugger);
-void			swfdec_debugger_set_stepping	(SwfdecDebugger *	debugger,
-							 gboolean		stepping);
-gboolean		swfdec_debugger_get_stepping	(SwfdecDebugger *	debugger);
-
-void			swfdec_debugger_add_script	(SwfdecDebugger *	debugger,
-							 SwfdecScript *		script);
-SwfdecDebuggerScript *	swfdec_debugger_get_script	(SwfdecDebugger *       debugger,
-							 SwfdecScript *		script);
-void			swfdec_debugger_remove_script	(SwfdecDebugger *	debugger,
-							 SwfdecScript *		script);
-void			swfdec_debugger_foreach_script	(SwfdecDebugger *	debugger,
-							 GFunc			func,
-							 gpointer		data);
-guint			swfdec_debugger_script_has_breakpoint
-							(SwfdecDebugger *       debugger,
-							 SwfdecDebuggerScript *	script,
-							 guint			line);
-
-const char *	      	swfdec_debugger_run		(SwfdecDebugger *	debugger,
-							 const char *		command);
-
-
-G_END_DECLS
-#endif
commit 57664ca360fe1b2d6b66b6fb80f1a8b7119c7a8f
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 27 13:38:05 2008 +0100

    remove last traces of native FLV support

diff --git a/swfdec/swfdec_decoder.c b/swfdec/swfdec_decoder.c
index 24bbda0..f3a3289 100644
--- a/swfdec/swfdec_decoder.c
+++ b/swfdec/swfdec_decoder.c
@@ -59,12 +59,6 @@ swfdec_decoder_new (SwfdecPlayer *player, const SwfdecBuffer *buffer)
       data[1] == 'W' &&
       data[2] == 'S') {
     retval = g_object_new (SWFDEC_TYPE_SWF_DECODER, NULL);
-#if 0
-  } else if (data[0] == 'F' &&
-      data[1] == 'L' &&
-      data[2] == 'V') {
-    retval = g_object_new (SWFDEC_TYPE_FLV_DECODER, NULL);
-#endif
   } else if (swfdec_image_detect (data) != SWFDEC_IMAGE_TYPE_UNKNOWN) {
     retval = g_object_new (SWFDEC_TYPE_IMAGE_DECODER, NULL);
   } else {
diff --git a/swfdec/swfdec_flv_decoder.h b/swfdec/swfdec_flv_decoder.h
index 0061c02..0c27d50 100644
--- a/swfdec/swfdec_flv_decoder.h
+++ b/swfdec/swfdec_flv_decoder.h
@@ -76,8 +76,7 @@ SwfdecBuffer *	swfdec_flv_decoder_get_data		(SwfdecFlvDecoder *	flv,
 							 guint			timestamp,
 							 guint *		real_timestamp);
 
-SwfdecMovie *	swfdec_flv_decoder_add_movie		(SwfdecFlvDecoder *	flv,
-							 SwfdecMovie *		parent);
+
 G_END_DECLS
 
 #endif
commit 8cf50843f011d94f6dc5a5b48aa311892d7f249a
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 27 13:36:55 2008 +0100

    remove nonexxisting/unused functions

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index ff1327d..92b1011 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -668,15 +668,6 @@ enum {
 
 G_DEFINE_TYPE (SwfdecPlayer, swfdec_player, SWFDEC_TYPE_AS_CONTEXT)
 
-void
-swfdec_player_remove_movie (SwfdecPlayer *player, SwfdecMovie *movie)
-{
-  SwfdecPlayerPrivate *priv = player->priv;
-
-  swfdec_movie_remove (movie);
-  priv->movies = g_list_remove (priv->movies, movie);
-}
-
 static guint
 swfdec_player_alignment_to_flags (SwfdecAlignment alignment)
 {
diff --git a/swfdec/swfdec_player_internal.h b/swfdec/swfdec_player_internal.h
index 71569be..c5c9b8c 100644
--- a/swfdec/swfdec_player_internal.h
+++ b/swfdec/swfdec_player_internal.h
@@ -150,11 +150,6 @@ void		swfdec_player_initialize	(SwfdecPlayer *		player,
 						 guint			width,
 						 guint			height);
 void		swfdec_player_start_ticking	(SwfdecPlayer *		player);
-void		swfdec_player_add_movie		(SwfdecPlayer *		player,
-						 guint			depth,
-						 const char *		url);
-void		swfdec_player_remove_movie	(SwfdecPlayer *		player,
-						 SwfdecMovie *		movie);
 
 gboolean	swfdec_player_lock		(SwfdecPlayer *		player);
 void		swfdec_player_lock_soft		(SwfdecPlayer *		player);
commit b6cf12a676a537b36965f5d65d1a71c72a57254a
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Mar 27 09:45:13 2008 +0100

    add a test for decompilation of functin calls

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 786c688..03f5969 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -71,7 +71,7 @@ noinst_HEADERS = \
 	vivified-compiler.h
 
 
-noinst_PROGRAMS = vivi-decompile
+noinst_PROGRAMS = vivi-decompile vivi-decompile-gtk
 
 vivi_decompile_SOURCES = \
 	decompiler.c
@@ -79,3 +79,12 @@ vivi_decompile_SOURCES = \
 vivi_decompile_CFLAGS =  $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS)
 vivi_decompile_LDFLAGS = $(SWFDEC_LIBS)
 vivi_decompile_LDADD = libvivified-compiler.la
+
+vivi_decompile_gtk_SOURCES = \
+	vivi_code_gtk_printer.c \
+	vivi_code_gtk_printer.h \
+	gtk_decompiler.c
+
+vivi_decompile_gtk_CFLAGS =  $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(GTK_CFLAGS)
+vivi_decompile_gtk_LDFLAGS = $(SWFDEC_LIBS) $(GTK_LIBS)
+vivi_decompile_gtk_LDADD = libvivified-compiler.la
diff --git a/vivified/code/test/Makefile.am b/vivified/code/test/Makefile.am
index 410e333..3ad5b13 100644
--- a/vivified/code/test/Makefile.am
+++ b/vivified/code/test/Makefile.am
@@ -17,6 +17,9 @@ EXTRA_DIST = \
 	and-or.as \
 	and-or.swf \
 	and-or.swf.expect \
+	function-calls.as \
+	function-calls.swf \
+	function-calls.swf.expect \
 	hello-world.as \
 	hello-world.swf \
 	hello-world.swf.expect \
diff --git a/vivified/code/test/function-calls.as b/vivified/code/test/function-calls.as
new file mode 100644
index 0000000..3efa898
--- /dev/null
+++ b/vivified/code/test/function-calls.as
@@ -0,0 +1,6 @@
+// makeswf -v 7 -s 200x150 -r 1 -o function-calls.swf function-calls.as
+
+foo ();
+bar (baz);
+this.foo (1, 2, 3);
+bar.baz ();
diff --git a/vivified/code/test/function-calls.swf b/vivified/code/test/function-calls.swf
new file mode 100644
index 0000000..dfa5349
Binary files /dev/null and b/vivified/code/test/function-calls.swf differ
diff --git a/vivified/code/test/function-calls.swf.expect b/vivified/code/test/function-calls.swf.expect
new file mode 100644
index 0000000..176d2aa
--- /dev/null
+++ b/vivified/code/test/function-calls.swf.expect
@@ -0,0 +1,10 @@
+/* version: 7 - size: 200x150 */
+
+/* Sprite0_Frame0 */
+function () {
+  foo ();
+  bar (baz);
+  this.foo (1, 2, 3);
+  bar.baz ();
+}
+
commit e3ea605eb5285c6f110a81f317fb1fcc9ed533d4
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Mar 26 19:41:13 2008 +0100

    use a proper order when decompiling scripts

diff --git a/vivified/code/decompiler.c b/vivified/code/decompiler.c
index 8de2ffe..296fa25 100644
--- a/vivified/code/decompiler.c
+++ b/vivified/code/decompiler.c
@@ -32,7 +32,7 @@
 #include "vivi_code_text_printer.h"
 
 static void
-decode_script (gpointer offset, gpointer scriptp, gpointer unused)
+decode_script (gpointer scriptp, gpointer unused)
 {
   SwfdecScript *script = scriptp;
   ViviCodeValue *fun;
@@ -49,12 +49,30 @@ decode_script (gpointer offset, gpointer scriptp, gpointer unused)
   g_object_unref (fun);
 }
 
+static void
+enqueue (gpointer offset, gpointer script, gpointer listp)
+{
+  GList **list = listp;
+
+  *list = g_list_prepend (*list, script);
+}
+
+static int
+script_compare (gconstpointer a, gconstpointer b)
+{
+  const SwfdecScript *scripta = a;
+  const SwfdecScript *scriptb = b;
+
+  return scripta->main - scriptb->main;
+}
+
 int 
 main (int argc, char *argv[])
 {
   SwfdecPlayer *player;
   SwfdecSwfDecoder *dec;
   SwfdecURL *url;
+  GList *scripts;
 
   if (argc < 2) {
     g_print ("%s FILENAME\n", argv[0]);
@@ -79,8 +97,13 @@ main (int argc, char *argv[])
   g_print ("/* version: %d - size: %ux%u */\n", dec->version,
       player->priv->width, player->priv->height);
   g_print ("\n");
-  g_hash_table_foreach (dec->scripts, decode_script, NULL);
+  scripts = NULL;
+  g_hash_table_foreach (dec->scripts, enqueue, &scripts);
+  scripts = g_list_sort (scripts, script_compare);
+  
+  g_list_foreach (scripts, decode_script, NULL);
 
+  g_list_free (scripts);
   g_object_unref (player);
   return 0;
 }
commit 1b9a4cc1a33d91d63498affec9066c0b2f95dc51
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Mar 26 18:58:14 2008 +0100

    tell which test is currently run

diff --git a/vivified/code/test/Makefile.am b/vivified/code/test/Makefile.am
index b8c3087..410e333 100644
--- a/vivified/code/test/Makefile.am
+++ b/vivified/code/test/Makefile.am
@@ -1,7 +1,7 @@
 check-local: ../vivi-decompile
 	RESULT=""; \
 	for file in $(srcdir)/*.swf; do \
-	  ../vivi-decompile $$file | diff -u $$file.expect - || RESULT="$$RESULT $$file"; \
+	  echo "$$file ..." && ../vivi-decompile $$file | diff -u $$file.expect - || RESULT="$$RESULT $$file"; \
 	done; \
 	if test "x$$RESULT" == "x"; then \
 	  echo "OK"; \
commit ecb901419931fdb71e71d48355f50ebc7828c2eb
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Mar 26 18:55:12 2008 +0100

    remove empty return statements at the end of functions

diff --git a/vivified/code/vivi_code_return.c b/vivified/code/vivi_code_return.c
index 1afe780..2bc68f2 100644
--- a/vivified/code/vivi_code_return.c
+++ b/vivified/code/vivi_code_return.c
@@ -88,3 +88,10 @@ vivi_code_return_set_value (ViviCodeReturn *ret, ViviCodeValue *value)
   ret->value = value;
 }
 
+ViviCodeValue *
+vivi_code_return_get_value (ViviCodeReturn *ret)
+{
+  g_return_val_if_fail (VIVI_IS_CODE_RETURN (ret), NULL);
+
+  return ret->value;
+}
diff --git a/vivified/code/vivi_code_return.h b/vivified/code/vivi_code_return.h
index 330ffbe..c0e5aeb 100644
--- a/vivified/code/vivi_code_return.h
+++ b/vivified/code/vivi_code_return.h
@@ -54,6 +54,7 @@ ViviCodeStatement *   	vivi_code_return_new		(void);
 
 void			vivi_code_return_set_value	(ViviCodeReturn *	ret,
 							 ViviCodeValue *	value);
+ViviCodeValue *		vivi_code_return_get_value	(ViviCodeReturn *	ret);
 
 
 G_END_DECLS
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index 22ee7b0..1914ef5 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -919,6 +919,23 @@ vivi_decompiler_find_start_block (GList *list, const guint8 *startpc)
   return NULL;
 }
 
+static void
+vivi_decompiler_remove_return (ViviCodeBlock *block)
+{
+  ViviCodeStatement *stmt;
+  guint len;
+
+  while ((len = vivi_code_block_get_n_statements (block))) {
+    stmt = vivi_code_block_get_statement (block, len - 1);
+    if (VIVI_IS_CODE_RETURN (stmt) &&
+	vivi_code_return_get_value (VIVI_CODE_RETURN (stmt)) == NULL) {
+      vivi_code_block_remove_statement (block, stmt);
+    } else {
+      break;
+    }
+  }
+}
+
 #define ASSERT_BLOCK_LIST(list) \
   { \
     GList *_walk; \
@@ -973,6 +990,8 @@ vivi_decompiler_merge_blocks_last_resort (GList *list, const guint8 *startpc)
   }
   g_list_foreach (ordered, (GFunc) g_object_unref, NULL);
   g_list_free (ordered);
+
+  vivi_decompiler_remove_return (block);
   return VIVI_CODE_STATEMENT (block);
 }
 
commit 0136529086ac08860ccd4746eaca7a7d14fd939f
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Mar 26 18:45:38 2008 +0100

    handle var assignments

diff --git a/vivified/code/vivi_code_assignment.c b/vivified/code/vivi_code_assignment.c
index 45a4682..f8bbd36 100644
--- a/vivified/code/vivi_code_assignment.c
+++ b/vivified/code/vivi_code_assignment.c
@@ -51,6 +51,9 @@ vivi_code_assignment_print (ViviCodeToken *token, ViviCodePrinter*printer)
   else
     varname = NULL;
 
+  if (assignment->local)
+    vivi_code_printer_print (printer, "var ");
+
   if (assignment->from) {
     vivi_code_printer_print_value (printer, assignment->from, VIVI_PRECEDENCE_MEMBER);
     if (varname) {
@@ -129,3 +132,14 @@ vivi_code_assignment_new_name (const char *name, ViviCodeValue *value)
   g_object_unref (constant);
   return result;
 }
+
+void
+vivi_code_assignment_set_local (ViviCodeAssignment *assign, gboolean local)
+{
+  g_return_if_fail (VIVI_IS_CODE_ASSIGNMENT (assign));
+  /* can't assign to non-local variables */
+  g_return_if_fail (assign->from == NULL);
+
+  assign->local = local;
+}
+
diff --git a/vivified/code/vivi_code_assignment.h b/vivified/code/vivi_code_assignment.h
index 56b3492..411c89a 100644
--- a/vivified/code/vivi_code_assignment.h
+++ b/vivified/code/vivi_code_assignment.h
@@ -43,6 +43,7 @@ struct _ViviCodeAssignment
   ViviCodeValue *	from;
   ViviCodeValue *	name;
   ViviCodeValue	*	value;
+  gboolean		local;
 };
 
 struct _ViviCodeAssignmentClass
@@ -58,6 +59,9 @@ ViviCodeStatement *	vivi_code_assignment_new		(ViviCodeValue *	from,
 ViviCodeStatement *	vivi_code_assignment_new_name		(const char *		name,
 								 ViviCodeValue *	value);
 
+void			vivi_code_assignment_set_local		(ViviCodeAssignment *	assign,
+								 gboolean		local);
+
 
 G_END_DECLS
 #endif
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index 78a8bb3..22ee7b0 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -377,6 +377,27 @@ vivi_decompile_set_member (ViviDecompilerBlock *block, ViviDecompilerState *stat
 }
 
 static gboolean
+vivi_decompile_define_local (ViviDecompilerBlock *block, ViviDecompilerState *state,
+    guint code, const guint8 *data, guint len)
+{
+  ViviCodeValue *name, *value;
+  ViviCodeStatement *assign;
+
+  if (code == SWFDEC_AS_ACTION_DEFINE_LOCAL)
+    value = vivi_decompiler_state_pop (state);
+  else
+    value = vivi_code_constant_new_undefined ();
+  name = vivi_decompiler_state_pop (state);
+
+  assign = vivi_code_assignment_new (NULL, name, value);
+  vivi_code_assignment_set_local (VIVI_CODE_ASSIGNMENT (assign), TRUE);
+  g_object_unref (name);
+  g_object_unref (value);
+  vivi_code_block_add_statement (VIVI_CODE_BLOCK (block), assign);
+  return TRUE;
+}
+
+static gboolean
 vivi_decompile_binary (ViviDecompilerBlock *block, ViviDecompilerState *state,
     guint code, const guint8 *data, guint len)
 {
@@ -681,12 +702,12 @@ static DecompileFunc decompile_funcs[256] = {
   [SWFDEC_AS_ACTION_MB_ASCII_TO_CHAR] = NULL,
   [SWFDEC_AS_ACTION_DELETE] = NULL,
   [SWFDEC_AS_ACTION_DELETE2] = NULL,
-  [SWFDEC_AS_ACTION_DEFINE_LOCAL] = NULL,
+  [SWFDEC_AS_ACTION_DEFINE_LOCAL] = vivi_decompile_define_local,
   [SWFDEC_AS_ACTION_CALL_FUNCTION] = vivi_decompile_call,
   [SWFDEC_AS_ACTION_RETURN] = vivi_decompile_return,
   [SWFDEC_AS_ACTION_MODULO] = NULL,
   [SWFDEC_AS_ACTION_NEW_OBJECT] = vivi_decompile_call,
-  [SWFDEC_AS_ACTION_DEFINE_LOCAL2] = NULL,
+  [SWFDEC_AS_ACTION_DEFINE_LOCAL2] = vivi_decompile_define_local,
   [SWFDEC_AS_ACTION_INIT_ARRAY] = NULL,
   [SWFDEC_AS_ACTION_INIT_OBJECT] = vivi_decompile_init_object,
   [SWFDEC_AS_ACTION_TYPE_OF] = NULL,


More information about the Swfdec-commits mailing list