[Swfdec] 163 commits - autogen.sh configure.ac doc/swfdec-sections.txt libswfdec-gtk/swfdec_gtk_player.c libswfdec-gtk/swfdec_gtk_player.h libswfdec-gtk/swfdec_gtk_widget.c libswfdec-gtk/swfdec_source.c libswfdec/Makefile.am libswfdec/swfdec_as_array.c libswfdec/swfdec_as_array.h libswfdec/swfdec_as_boolean.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_debugger.c libswfdec/swfdec_as_debugger.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_frame_internal.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_native_function.h libswfdec/swfdec_as_number.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_script_function.c libswfdec/swfdec_as_script_function.h libswfdec/swfdec_as_string.c libswfdec/swfdec_as_types.h libswfdec/swfdec_button_movie.c libswfdec/swfdec_color_as.h libswfdec/swfdec_debugger.c libswfdec/swfdec_event.c libswfdec/swfdec.h libswfdec/swfdec_movie.c libswfdec/swfdec_net_connection.c libswfdec/swfdec_net_stream_as.c libswfdec/swfdec_player_as.c libswfdec/swfdec_player.c libswfdec/swfdec_player.h libswfdec/swfdec_player_internal.h libswfdec/swfdec_script.c libswfdec/swfdec_script.h libswfdec/swfdec_script_internal.h libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_tag.c libswfdec/swfdec_types.h libswfdec/swfdec_video_movie_as.c libswfdec/swfdec_xml_as.c Makefile.am player/Makefile.am player/swfdec_debug_movies.c player/swfdec_debug_movies.h player/swfdec_debug_scripts.c player/swfdec_player_manager.c player/swfplay.c test/image test/sound test/swfedit_tag.c test/swfedit_token.c test/swfscript.c test/trace vivified/core vivified/dock vivified/.gitignore vivified/Makefile.am vivified/ui

Benjamin Otte company at kemper.freedesktop.org
Wed Aug 22 01:46:38 PDT 2007


 Makefile.am                                      |    7 
 autogen.sh                                       |    2 
 configure.ac                                     |   27 +
 doc/swfdec-sections.txt                          |    3 
 libswfdec-gtk/swfdec_gtk_player.c                |    7 
 libswfdec-gtk/swfdec_gtk_player.h                |    2 
 libswfdec-gtk/swfdec_gtk_widget.c                |    2 
 libswfdec-gtk/swfdec_source.c                    |    4 
 libswfdec/Makefile.am                            |   11 
 libswfdec/swfdec.h                               |    4 
 libswfdec/swfdec_as_array.c                      |   21 -
 libswfdec/swfdec_as_array.h                      |    1 
 libswfdec/swfdec_as_boolean.c                    |   22 -
 libswfdec/swfdec_as_context.c                    |   65 ++-
 libswfdec/swfdec_as_context.h                    |    5 
 libswfdec/swfdec_as_debugger.c                   |   72 +++
 libswfdec/swfdec_as_debugger.h                   |   78 +++
 libswfdec/swfdec_as_frame.c                      |   90 ++++
 libswfdec/swfdec_as_frame.h                      |    3 
 libswfdec/swfdec_as_frame_internal.h             |    2 
 libswfdec/swfdec_as_function.c                   |   37 -
 libswfdec/swfdec_as_function.h                   |    4 
 libswfdec/swfdec_as_internal.h                   |    6 
 libswfdec/swfdec_as_interpret.c                  |   28 -
 libswfdec/swfdec_as_native_function.c            |   34 +
 libswfdec/swfdec_as_native_function.h            |    3 
 libswfdec/swfdec_as_number.c                     |   26 -
 libswfdec/swfdec_as_object.c                     |   98 +++-
 libswfdec/swfdec_as_object.h                     |   10 
 libswfdec/swfdec_as_script_function.c            |   31 +
 libswfdec/swfdec_as_script_function.h            |    3 
 libswfdec/swfdec_as_string.c                     |   27 -
 libswfdec/swfdec_as_types.h                      |   10 
 libswfdec/swfdec_button_movie.c                  |    9 
 libswfdec/swfdec_color_as.h                      |    2 
 libswfdec/swfdec_debugger.c                      |    5 
 libswfdec/swfdec_event.c                         |    4 
 libswfdec/swfdec_movie.c                         |   18 
 libswfdec/swfdec_net_connection.c                |   19 
 libswfdec/swfdec_net_stream_as.c                 |   19 
 libswfdec/swfdec_player.c                        |   41 +-
 libswfdec/swfdec_player.h                        |    3 
 libswfdec/swfdec_player_as.c                     |    2 
 libswfdec/swfdec_player_internal.h               |    2 
 libswfdec/swfdec_script.c                        |   42 --
 libswfdec/swfdec_script.h                        |   69 ---
 libswfdec/swfdec_script_internal.h               |   93 ++++
 libswfdec/swfdec_swf_decoder.c                   |    1 
 libswfdec/swfdec_tag.c                           |    7 
 libswfdec/swfdec_types.h                         |    2 
 libswfdec/swfdec_video_movie_as.c                |   10 
 libswfdec/swfdec_xml_as.c                        |   18 
 player/Makefile.am                               |   27 -
 player/swfdec_debug_movies.c                     |  381 -------------------
 player/swfdec_debug_movies.h                     |   67 ---
 player/swfdec_debug_scripts.c                    |    1 
 player/swfdec_player_manager.c                   |    1 
 player/swfplay.c                                 |    2 
 test/image/image.c                               |    2 
 test/sound/sound.c                               |    2 
 test/swfedit_tag.c                               |    4 
 test/swfedit_token.c                             |    7 
 test/swfscript.c                                 |    7 
 test/trace/Makefile.am                           |   18 
 test/trace/definefunction2-registers-5.swf       |binary
 test/trace/definefunction2-registers-5.swf.trace |   67 +++
 test/trace/definefunction2-registers-6.swf       |binary
 test/trace/definefunction2-registers-6.swf.trace |   67 +++
 test/trace/definefunction2-registers-7.swf       |binary
 test/trace/definefunction2-registers-7.swf.trace |   67 +++
 test/trace/definefunction2-registers-8.swf       |binary
 test/trace/definefunction2-registers-8.swf.trace |   67 +++
 test/trace/definefunction2-registers.xml         |  336 ++++++++++++++++
 test/trace/remove-depths-5.swf                   |binary
 test/trace/remove-depths-5.swf.trace             |    1 
 test/trace/remove-depths-6.swf                   |binary
 test/trace/remove-depths-6.swf.trace             |    3 
 test/trace/remove-depths-7.swf                   |binary
 test/trace/remove-depths-7.swf.trace             |    3 
 test/trace/remove-depths-8.swf                   |binary
 test/trace/remove-depths-8.swf.trace             |    3 
 test/trace/remove-depths.as                      |   15 
 test/trace/trace.c                               |    4 
 vivified/.gitignore                              |    2 
 vivified/Makefile.am                             |    1 
 vivified/core/.gitignore                         |   16 
 vivified/core/Makefile.am                        |   60 +++
 vivified/core/vivi_application.c                 |  415 ++++++++++++++++++++
 vivified/core/vivi_application.h                 |  114 +++++
 vivified/core/vivi_application_as.c              |  116 +++++
 vivified/core/vivi_breakpoint.c                  |  241 ++++++++++++
 vivified/core/vivi_breakpoint.h                  |   58 ++
 vivified/core/vivi_debugger.c                    |  209 ++++++++++
 vivified/core/vivi_debugger.h                    |   55 ++
 vivified/core/vivi_function.c                    |   90 ++++
 vivified/core/vivi_function.h                    |   36 +
 vivified/core/vivi_initialize.as                 |  158 +++++++
 vivified/core/vivi_initialize.s                  |    7 
 vivified/core/vivi_marshal.list                  |    4 
 vivified/core/vivi_ming.c                        |  111 +++++
 vivified/core/vivi_ming.h                        |   34 +
 vivified/core/vivi_player_as.c                   |  132 ++++++
 vivified/core/vivi_wrap.c                        |  113 +++++
 vivified/core/vivi_wrap.h                        |   60 +++
 vivified/core/vivi_wrap_as.c                     |  152 +++++++
 vivified/core/vivified-core.h                    |   25 +
 vivified/dock/.gitignore                         |   12 
 vivified/dock/Makefile.am                        |   15 
 vivified/dock/vivi_docker.c                      |   93 ++++
 vivified/dock/vivi_docker.h                      |   55 ++
 vivified/dock/vivi_docklet.c                     |  172 ++++++++
 vivified/dock/vivi_docklet.h                     |   61 +++
 vivified/dock/vivi_vdock.c                       |  159 +++++++
 vivified/dock/vivi_vdock.h                       |   60 +++
 vivified/dock/vivified-dock.h                    |   26 +
 vivified/ui/.gitignore                           |   14 
 vivified/ui/Makefile.am                          |   20 +
 vivified/ui/main.c                               |  122 ++++++
 vivified/ui/vivi_command_line.c                  |  118 +++++
 vivified/ui/vivi_command_line.xml                |   38 +
 vivified/ui/vivi_movie_list.c                    |  460 +++++++++++++++++++++++
 vivified/ui/vivi_movie_list.h                    |   66 +++
 vivified/ui/vivi_movies.c                        |   40 ++
 vivified/ui/vivi_movies.xml                      |   38 +
 vivified/ui/vivi_player.c                        |   58 ++
 vivified/ui/vivi_player.xml                      |   17 
 vivified/ui/vivi_vivi_docklet.c                  |  150 +++++++
 vivified/ui/vivi_vivi_docklet.h                  |   62 +++
 128 files changed, 5498 insertions(+), 830 deletions(-)

New commits:
diff-tree 71cba217cf8baa498b14a09685aef92266e72dba (from 585fd834a0cc155ace203941eccb2b3e3beb38eb)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 10:46:15 2007 +0200

    rework init code, so it doesn't hit constant variables

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index 81ef701..864915d 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -1077,21 +1077,18 @@ swfdec_as_array_init_context (SwfdecAsCo
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
 
-  array = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
-      SWFDEC_AS_STR_Array, 0, swfdec_as_array_construct, 0));
-  swfdec_as_native_function_set_construct_type (
-      SWFDEC_AS_NATIVE_FUNCTION (array), SWFDEC_TYPE_AS_ARRAY);
-  if (!array)
-    return;
-  context->Array = array;
   if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsArray)))
     return;
   proto = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL);
   swfdec_as_object_add (proto, context, sizeof (SwfdecAsArray));
+  array = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global,
+      SWFDEC_AS_STR_Array, 0, SWFDEC_TYPE_AS_ARRAY, swfdec_as_array_construct, 
+      0, proto));
+  if (!array)
+    return;
+  context->Array = array;
 
   /* set the right properties on the Array object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (array, SWFDEC_AS_STR_prototype, &val);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_constructor, &val);
   SWFDEC_AS_VALUE_SET_NUMBER (&val, ARRAY_SORT_OPTION_CASEINSENSITIVE);
@@ -1106,9 +1103,6 @@ swfdec_as_array_init_context (SwfdecAsCo
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_NUMERIC, &val);
 
   /* set the right properties on the Array.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
-  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
-      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, array);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, 0,
@@ -1135,4 +1129,7 @@ swfdec_as_array_init_context (SwfdecAsCo
       SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sort, 0);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_sortOn,
       SWFDEC_TYPE_AS_OBJECT, swfdec_as_array_sortOn, 0);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
+      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
 }
diff --git a/libswfdec/swfdec_as_boolean.c b/libswfdec/swfdec_as_boolean.c
index 18872cb..b883868 100644
--- a/libswfdec/swfdec_as_boolean.c
+++ b/libswfdec/swfdec_as_boolean.c
@@ -89,25 +89,21 @@ swfdec_as_boolean_init_context (SwfdecAs
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
 
-  boolean = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
-      SWFDEC_AS_STR_Boolean, SWFDEC_TYPE_AS_BOOLEAN, swfdec_as_boolean_construct, 0));
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
+  boolean = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global,
+      SWFDEC_AS_STR_Boolean, SWFDEC_TYPE_AS_BOOLEAN, SWFDEC_TYPE_AS_BOOLEAN, 
+      swfdec_as_boolean_construct, 0, proto));
   if (!boolean)
     return;
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (boolean), SWFDEC_TYPE_AS_BOOLEAN);
-  swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (boolean), SWFDEC_TYPE_AS_BOOLEAN);
-  proto = swfdec_as_object_new (context);
-  /* set the right properties on the Boolean object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (boolean, SWFDEC_AS_STR_prototype, &val);
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
-  swfdec_as_object_set_variable (boolean, SWFDEC_AS_STR_constructor, &val);
   /* set the right properties on the Boolean.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
-  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
-      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, boolean);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, SWFDEC_TYPE_AS_BOOLEAN, swfdec_as_boolean_toString, 0);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_valueOf, SWFDEC_TYPE_AS_BOOLEAN, swfdec_as_boolean_valueOf, 0);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
+      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
 }
 
diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c
index d0437b8..475d540 100644
--- a/libswfdec/swfdec_as_number.c
+++ b/libswfdec/swfdec_as_number.c
@@ -98,23 +98,15 @@ swfdec_as_number_init_context (SwfdecAsC
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
 
-  number = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
-      SWFDEC_AS_STR_Number, SWFDEC_TYPE_AS_NUMBER, swfdec_as_number_construct, 0));
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
+  number = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global,
+      SWFDEC_AS_STR_Number, SWFDEC_TYPE_AS_NUMBER, SWFDEC_TYPE_AS_NUMBER, 
+      swfdec_as_number_construct, 0, proto));
   if (!number)
     return;
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (number), SWFDEC_TYPE_AS_NUMBER);
-  swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (number), 
-      SWFDEC_TYPE_AS_NUMBER);
-  proto = swfdec_as_object_new (context);
   /* set the right properties on the Number object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable_and_flags (number, SWFDEC_AS_STR_prototype,
-      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT |
-      SWFDEC_AS_VARIABLE_CONSTANT);
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
-  swfdec_as_object_set_variable_and_flags (number, SWFDEC_AS_STR_constructor,
-      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT |
-      SWFDEC_AS_VARIABLE_CONSTANT);
   SWFDEC_AS_VALUE_SET_NUMBER (&val, NAN);
   swfdec_as_object_set_variable (number, SWFDEC_AS_STR_NaN, &val);
   SWFDEC_AS_VALUE_SET_NUMBER (&val, G_MAXDOUBLE);
@@ -126,13 +118,13 @@ swfdec_as_number_init_context (SwfdecAsC
   SWFDEC_AS_VALUE_SET_NUMBER (&val, HUGE_VAL);
   swfdec_as_object_set_variable (number, SWFDEC_AS_STR_POSITIVE_INFINITY, &val);
   /* set the right properties on the Number.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
-  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
-      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, number);
   swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor,
       &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, SWFDEC_TYPE_AS_NUMBER, swfdec_as_number_toString, 0);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_valueOf, SWFDEC_TYPE_AS_NUMBER, swfdec_as_number_valueOf, 0);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
+      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
 }
 
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 7623b7e..5800dbd 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -133,15 +133,17 @@ swfdec_as_script_function_new (SwfdecAsS
   fun->script = script;
   fun->target = target;
   swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsScriptFunction));
-  swfdec_as_function_set_constructor (SWFDEC_AS_FUNCTION (fun));
   /* set prototype */
-  proto = swfdec_as_object_new (SWFDEC_AS_OBJECT (scope)->context);
+  proto = swfdec_as_object_new_empty (context);
   if (proto == NULL)
     return NULL;
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (fun));
-  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val);
+  swfdec_as_function_set_constructor (SWFDEC_AS_FUNCTION (fun));
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (fun));
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
 
   return SWFDEC_AS_FUNCTION (fun);
 }
diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c
index ba70858..5ad6425 100644
--- a/libswfdec/swfdec_as_string.c
+++ b/libswfdec/swfdec_as_string.c
@@ -703,15 +703,15 @@ swfdec_as_string_init_context (SwfdecAsC
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
 
-  string = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
-      SWFDEC_AS_STR_String, 0, swfdec_as_string_construct, 0));
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (string), SWFDEC_TYPE_AS_STRING);
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
+  string = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global,
+      SWFDEC_AS_STR_String, 0, SWFDEC_TYPE_AS_STRING, 
+      swfdec_as_string_construct, 0, proto));
   if (!string)
     return;
-  proto = swfdec_as_object_new (context);
   /* set the right properties on the String object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (string, SWFDEC_AS_STR_prototype, &val);
   if (version <= 5) {
     swfdec_as_object_add_function (string, SWFDEC_AS_STR_fromCharCode, 0, swfdec_as_string_fromCharCode_5, 0);
   } else {
@@ -719,9 +719,6 @@ swfdec_as_string_init_context (SwfdecAsC
   }
 
   /* set the right properties on the String.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
-  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
-      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, string);
   swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor,
       &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
@@ -739,6 +736,9 @@ swfdec_as_string_init_context (SwfdecAsC
   } else {
     swfdec_as_object_add_function (proto, SWFDEC_AS_STR_split, SWFDEC_TYPE_AS_STRING, swfdec_as_string_split, 1);
   }
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR___proto__, &val,
+      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
 
   /* add properties to global object */
   swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_escape, 0, swfdec_as_string_escape, 1);
diff --git a/libswfdec/swfdec_net_connection.c b/libswfdec/swfdec_net_connection.c
index f36ea84..d154c35 100644
--- a/libswfdec/swfdec_net_connection.c
+++ b/libswfdec/swfdec_net_connection.c
@@ -139,19 +139,20 @@ swfdec_net_connection_init_context (Swfd
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
   context = SWFDEC_AS_CONTEXT (player);
-  conn = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, 
-      SWFDEC_AS_STR_NetConnection, SWFDEC_TYPE_NET_CONNECTION, NULL, 0));
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
+  conn = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global, 
+      SWFDEC_AS_STR_NetConnection, SWFDEC_TYPE_NET_CONNECTION, 
+      SWFDEC_TYPE_NET_CONNECTION, NULL, 0, proto));
   if (!conn)
     return;
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (conn), SWFDEC_TYPE_NET_CONNECTION);
-  proto = swfdec_as_object_new (context);
-  /* set the right properties on the NetConnection object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (conn, SWFDEC_AS_STR_prototype, &val);
   /* set the right properties on the NetConnection.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, conn);
-  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_connect, SWFDEC_TYPE_NET_CONNECTION,
       swfdec_net_connection_do_connect, 1);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, conn);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
 }
 
diff --git a/libswfdec/swfdec_net_stream_as.c b/libswfdec/swfdec_net_stream_as.c
index fd16876..46d607e 100644
--- a/libswfdec/swfdec_net_stream_as.c
+++ b/libswfdec/swfdec_net_stream_as.c
@@ -112,18 +112,15 @@ swfdec_net_stream_init_context (SwfdecPl
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
   context = SWFDEC_AS_CONTEXT (player);
-  stream = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, 
-      SWFDEC_AS_STR_NetStream, SWFDEC_TYPE_NET_STREAM, swfdec_net_stream_construct, 1));
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
+  stream = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global, 
+      SWFDEC_AS_STR_NetStream, SWFDEC_TYPE_NET_STREAM, SWFDEC_TYPE_NET_STREAM,
+      swfdec_net_stream_construct, 1, proto));
   if (stream == NULL)
     return;
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (stream), SWFDEC_TYPE_NET_STREAM);
-  proto = swfdec_as_object_new (context);
-  /* set the right properties on the NetStream object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (stream, SWFDEC_AS_STR_prototype, &val);
   /* set the right properties on the NetStream.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, stream);
-  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_pause, SWFDEC_TYPE_NET_STREAM,
       swfdec_net_stream_pause, 0);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_play, SWFDEC_TYPE_NET_STREAM,
@@ -134,5 +131,9 @@ swfdec_net_stream_init_context (SwfdecPl
       swfdec_net_stream_do_seek, 1);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_setBufferTime, SWFDEC_TYPE_NET_STREAM,
       swfdec_net_stream_setBufferTime, 1);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, stream);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
 }
 
diff --git a/libswfdec/swfdec_video_movie_as.c b/libswfdec/swfdec_video_movie_as.c
index bebcd58..79574e2 100644
--- a/libswfdec/swfdec_video_movie_as.c
+++ b/libswfdec/swfdec_video_movie_as.c
@@ -66,16 +66,20 @@ swfdec_video_movie_init_context (SwfdecP
   if (video == NULL)
     return;
   player->Video = video;
-  proto = swfdec_as_object_new (context);
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
   /* set the right properties on the Video object */
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (video, SWFDEC_AS_STR_prototype, &val);
   /* set the right properties on the Video.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, video);
-  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_attachVideo, SWFDEC_TYPE_VIDEO_MOVIE,
       swfdec_video_attach_video, 1);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_clear, SWFDEC_TYPE_VIDEO_MOVIE,
       swfdec_video_clear, 0);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, video);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
 }
 
diff --git a/libswfdec/swfdec_xml_as.c b/libswfdec/swfdec_xml_as.c
index db31bc0..bf182a8 100644
--- a/libswfdec/swfdec_xml_as.c
+++ b/libswfdec/swfdec_xml_as.c
@@ -52,19 +52,19 @@ swfdec_xml_init_context (SwfdecPlayer *p
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
 
   context = SWFDEC_AS_CONTEXT (player);
-  xml = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, 
-      SWFDEC_AS_STR_XML, 0, NULL, 0));
+  proto = swfdec_as_object_new_empty (context);
+  if (proto == NULL)
+    return;
+  xml = SWFDEC_AS_OBJECT (swfdec_as_object_add_constructor (context->global, 
+      SWFDEC_AS_STR_XML, 0, SWFDEC_TYPE_XML, NULL, 0, proto));
   if (xml == NULL)
     return;
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (xml), SWFDEC_TYPE_XML);
-  proto = swfdec_as_object_new (context);
-  /* set the right properties on the NetStream object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (xml, SWFDEC_AS_STR_prototype, &val);
   /* set the right properties on the NetStream.prototype object */
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, xml);
-  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_load, SWFDEC_TYPE_XML,
       swfdec_load_object_load, 0);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, xml);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
 }
 
diff-tree 585fd834a0cc155ace203941eccb2b3e3beb38eb (from 687cf30c3d7461c8222ae0d9b1e2c195ffde1c1a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 10:45:12 2007 +0200

    only check variable flags if the variable existed, not on newly created one

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index edd8258..7d7062f 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -246,9 +246,10 @@ swfdec_as_object_do_set (SwfdecAsObject 
     var = swfdec_as_object_hash_create (object, variable, flags);
     if (var == NULL)
       return;
+  } else {
+    if (var->flags & SWFDEC_AS_VARIABLE_CONSTANT)
+      return;
   }
-  if (var->flags & SWFDEC_AS_VARIABLE_CONSTANT)
-    return;
   if (var->get) {
     if (var->set) {
       SwfdecAsValue tmp;
diff-tree 687cf30c3d7461c8222ae0d9b1e2c195ffde1c1a (from 5981d5765cc96487a8bcec321fd36bb54bb09463)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 10:09:38 2007 +0200

    more trap avoidance

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 4027aab..edd8258 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -1032,12 +1032,12 @@ swfdec_as_object_set_constructor (Swfdec
     SWFDEC_WARNING ("constructor has no prototype, using Object.prototype");
     proto = object->context->Object_prototype;
   }
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__, 
-      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, construct);
   swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_constructor, 
       &val, SWFDEC_AS_VARIABLE_HIDDEN);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
+  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__, 
+      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
 }
 
 /**
diff-tree 5981d5765cc96487a8bcec321fd36bb54bb09463 (from f81b8b88652be42b8dd75171ce746276ccfdc00d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 10:08:55 2007 +0200

    switch orders a bit to not run into the CONSTANT prototype variable trap

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index f62f59b..4027aab 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -1140,26 +1140,27 @@ swfdec_as_object_init_context (SwfdecAsC
   SwfdecAsValue val;
   SwfdecAsObject *object, *proto;
 
+  proto = swfdec_as_object_new_empty (context);
+  if (!proto)
+    return;
   object = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global, 
       SWFDEC_AS_STR_Object, 0, NULL, 0));
   if (!object)
     return;
-  proto = swfdec_as_object_new_empty (context);
-  if (!proto)
-    return;
   context->Object = object;
   context->Object_prototype = proto;
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
+  /* first, set our own */
+  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_prototype,
+      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT |
+      SWFDEC_AS_VARIABLE_CONSTANT);
   if (context->Function_prototype) {
-    /* first, finish the function prototype */
+    /* then finish the function prototype (use this order or 
+     * SWFDEC_AS_VARIABLE_CONSTANT won't let us */
     swfdec_as_object_set_variable_and_flags (context->Function_prototype,
 	SWFDEC_AS_STR___proto__, &val,
 	SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   }
-  /* now, set our own */
-  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_prototype,
-      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT |
-      SWFDEC_AS_VARIABLE_CONSTANT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
   swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor,
       &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
diff-tree f81b8b88652be42b8dd75171ce746276ccfdc00d (from 0e7497632ecd482a7a2072b752a939507e5111aa)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 10:05:35 2007 +0200

    add swfdec_As_object_add_constructor()
    
    It's basically swfdec_as_object_add_function() but takes some additional
    properties relevant for constructors.

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index b2a3262..f62f59b 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -783,20 +783,54 @@ SwfdecAsFunction *
 swfdec_as_object_add_function (SwfdecAsObject *object, const char *name, GType type,
     SwfdecAsNative native, guint min_args)
 {
+  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (type == 0 || g_type_is_a (type, SWFDEC_TYPE_AS_OBJECT), NULL);
+
+  return swfdec_as_object_add_constructor (object, name, type, 0, native, min_args, NULL);
+}
+
+/**
+ * swfdec_as_object_add_function:
+ * @object: a #SwfdecAsObject
+ * @name: name of the function. The string does not have to be 
+ *        garbage-collected.
+ * @type: the required type of the this Object to make this function execute.
+ *        May be 0 to accept any type.
+ * @construct_type: type used when using this function as a constructor. May 
+ *                  be 0 to use the default type.
+ * @native: a native function or %NULL to just not do anything
+ * @min_args: minimum number of arguments to pass to @native
+ * @prototype: An optional object to be set as the "prototype" property of the
+ *             new function. The prototype will be hidden and constant.
+ *
+ * Adds @native as a constructor named @name to @object. The newly added variable
+ * will not be enumerated.
+ *
+ * Returns: the newly created #SwfdecAsFunction or %NULL on error.
+ **/
+SwfdecAsFunction *
+swfdec_as_object_add_constructor (SwfdecAsObject *object, const char *name, GType type,
+    GType construct_type, SwfdecAsNative native, guint min_args, SwfdecAsObject *prototype)
+{
   SwfdecAsFunction *function;
   SwfdecAsValue val;
 
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL);
   g_return_val_if_fail (name != NULL, NULL);
   g_return_val_if_fail (type == 0 || g_type_is_a (type, SWFDEC_TYPE_AS_OBJECT), NULL);
+  g_return_val_if_fail (construct_type == 0 || g_type_is_a (construct_type, SWFDEC_TYPE_AS_OBJECT), NULL);
+  g_return_val_if_fail (prototype == NULL || SWFDEC_IS_AS_OBJECT (prototype), NULL);
 
   if (!native)
     native = swfdec_as_object_do_nothing;
-  function = swfdec_as_native_function_new (object->context, name, native, min_args, NULL);
+  function = swfdec_as_native_function_new (object->context, name, native, min_args, prototype);
   if (function == NULL)
     return NULL;
   if (type != 0)
     swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (function), type);
+  if (construct_type != 0)
+    swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (function), construct_type);
   name = swfdec_as_context_get_string (object->context, name);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function));
   /* FIXME: I'd like to make sure no such property exists yet */
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index b14e95d..0079e2d 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -155,6 +155,14 @@ SwfdecAsFunction *swfdec_as_object_add_f
 						 GType			type,
 						 SwfdecAsNative		native,
 						 guint			min_args);
+SwfdecAsFunction *swfdec_as_object_add_constructor
+						(SwfdecAsObject *	object,
+						 const char *		name,
+						 GType			type,
+						 GType			construct_type,
+						 SwfdecAsNative		native,
+						 guint			min_args,
+						 SwfdecAsObject *	prototype);
 
 gboolean	swfdec_as_object_has_function	(SwfdecAsObject *       object,
 						 const char *		name);
diff-tree 0e7497632ecd482a7a2072b752a939507e5111aa (from 1c8bbca9cd8af8f25dc8ae654f9ecb8ff2dcf77b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 09:58:24 2007 +0200

    make swfdec_as_native_function_new() take an optional prototype argument

diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c
index 9e92e1f..4088604 100644
--- a/libswfdec/swfdec_as_native_function.c
+++ b/libswfdec/swfdec_as_native_function.c
@@ -26,6 +26,7 @@
 #include "swfdec_as_frame_internal.h"
 #include "swfdec_as_internal.h"
 #include "swfdec_as_stack.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 /*** GTK-DOC ***/
@@ -110,6 +111,8 @@ swfdec_as_native_function_init (SwfdecAs
  * @name: name of the function
  * @native: function to call when executed
  * @min_args: minimum number of arguments required
+ * @prototype: The object to be used as "prototype" property for the created 
+ *             function or %NULL for none.
  *
  * Creates a new native function, that will execute @native when called. The
  * @min_args parameter sets a requirement for the minimum number of arguments
@@ -121,12 +124,13 @@ swfdec_as_native_function_init (SwfdecAs
  **/
 SwfdecAsFunction *
 swfdec_as_native_function_new (SwfdecAsContext *context, const char *name,
-    SwfdecAsNative native, guint min_args)
+    SwfdecAsNative native, guint min_args, SwfdecAsObject *prototype)
 {
   SwfdecAsNativeFunction *fun;
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
   g_return_val_if_fail (native != NULL, NULL);
+  g_return_val_if_fail (prototype == NULL || SWFDEC_IS_AS_OBJECT (prototype), NULL);
 
   if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsNativeFunction)))
     return NULL;
@@ -137,6 +141,14 @@ swfdec_as_native_function_new (SwfdecAsC
   fun->min_args = min_args;
   fun->name = g_strdup (name);
   swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsNativeFunction));
+  /* need to set prototype before setting the constructor or Function.constructor 
+   * being CONSTANT disallows setting it. */
+  if (prototype) {
+    SwfdecAsValue val;
+    SWFDEC_AS_VALUE_SET_OBJECT (&val, prototype);
+    swfdec_as_object_set_variable_and_flags (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, 
+	&val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
+  }
   swfdec_as_function_set_constructor (SWFDEC_AS_FUNCTION (fun));
 
   return SWFDEC_AS_FUNCTION (fun);
diff --git a/libswfdec/swfdec_as_native_function.h b/libswfdec/swfdec_as_native_function.h
index b5f6232..4a1ab28 100644
--- a/libswfdec/swfdec_as_native_function.h
+++ b/libswfdec/swfdec_as_native_function.h
@@ -59,7 +59,8 @@ GType		swfdec_as_native_function_get_typ
 SwfdecAsFunction *swfdec_as_native_function_new	(SwfdecAsContext *	context,
 						 const char *		name,
 						 SwfdecAsNative		native,
-						 guint			min_args);
+						 guint			min_args,
+						 SwfdecAsObject *	prototype);
 
 void		swfdec_as_native_function_set_object_type
 						(SwfdecAsNativeFunction *function,
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index bdfee16..b2a3262 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -792,7 +792,7 @@ swfdec_as_object_add_function (SwfdecAsO
 
   if (!native)
     native = swfdec_as_object_do_nothing;
-  function = swfdec_as_native_function_new (object->context, name, native, min_args);
+  function = swfdec_as_native_function_new (object->context, name, native, min_args, NULL);
   if (function == NULL)
     return NULL;
   if (type != 0)
diff --git a/libswfdec/swfdec_player_as.c b/libswfdec/swfdec_player_as.c
index 1b8503a..f08c48f 100644
--- a/libswfdec/swfdec_player_as.c
+++ b/libswfdec/swfdec_player_as.c
@@ -105,7 +105,7 @@ 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,
-	  native_funcs[i].func, 0);
+	  native_funcs[i].func, 0, NULL);
     }
   }
   return NULL;
diff-tree 1c8bbca9cd8af8f25dc8ae654f9ecb8ff2dcf77b (from parents)
Merge: 7c86c8ada24c3ba63a98036f901bf5c92487447d 73e6028c89191b80deaf5858ea468522749bf451
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 09:44:29 2007 +0200

    Merge branch 'vivi'
    
    Conflicts:
    
    	libswfdec/swfdec_as_function.c

diff --cc libswfdec/swfdec_as_function.c
index 55a9ea3,879ed9d..9782a9c
@@@ -97,11 -90,8 +90,9 @@@
    }
    if (context->Function_prototype) {
      SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function_prototype);
-     swfdec_as_object_set_variable_and_flags (fun, SWFDEC_AS_STR___proto__,
 -    swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
++    swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__,
 +	&val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
    }
- 
-   return SWFDEC_AS_FUNCTION (fun);
  }
  
  /**
diff-tree 73e6028c89191b80deaf5858ea468522749bf451 (from 32192c024105f03a19dcf93ca92ca56f43fd5b56)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 09:34:46 2007 +0200

    clear the model when the player gets reset
    
    ALso removes another debugging g_print

diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
index 497ee27..35aa0dd 100644
--- a/vivified/ui/vivi_movie_list.c
+++ b/vivified/ui/vivi_movie_list.c
@@ -294,7 +294,6 @@ vivi_movie_list_movie_notify (SwfdecMovi
       guint i;
       guint count = g_node_n_children (parent);
       int *positions = g_new (int, count);
-      g_print ("reordering %u => %u (%u total)\n", old, new, count);
       for (i = 0; i < min; i++) {
 	positions[i] = i;
       }
@@ -393,6 +392,16 @@ vivi_movie_list_removed (ViviDebugger *d
 }
 
 static void
+vivi_movie_list_reset (ViviApplication *app, GParamSpec *pspec, ViviMovieList *movies)
+{
+  GNode *walk;
+
+  for (walk = movies->root->children; walk; walk = walk->next) {
+    vivi_movie_list_removed (NULL, walk->data, movies);
+  }
+}
+
+static void
 vivi_movie_list_dispose (GObject *object)
 {
   ViviMovieList *movies = VIVI_MOVIE_LIST (object);
@@ -400,6 +409,7 @@ vivi_movie_list_dispose (GObject *object
   GNode *walk;
 
   debugger = movies->app->debugger;
+  g_signal_handlers_disconnect_by_func (movies->app, vivi_movie_list_reset, movies);
   g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_removed, movies);
   g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_added, movies);
   g_object_unref (movies->app);
@@ -442,6 +452,7 @@ vivi_movie_list_new (ViviApplication *ap
   g_object_ref (app);
   movies->app = app;
   debugger = app->debugger;
+  g_signal_connect (app, "notify::player", G_CALLBACK (vivi_movie_list_reset), movies);
   g_signal_connect (debugger, "add", G_CALLBACK (vivi_movie_list_added), movies);
   g_signal_connect (debugger, "remove", G_CALLBACK (vivi_movie_list_removed), movies);
   return GTK_TREE_MODEL (movies);
diff-tree 32192c024105f03a19dcf93ca92ca56f43fd5b56 (from f21416fa0be5658c7e88bc2e57d77eacd369ff85)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 09:33:47 2007 +0200

    only disconnect signals when the objet still exists

diff --git a/libswfdec-gtk/swfdec_source.c b/libswfdec-gtk/swfdec_source.c
index d570710..59f0d85 100644
--- a/libswfdec-gtk/swfdec_source.c
+++ b/libswfdec-gtk/swfdec_source.c
@@ -36,7 +36,7 @@ struct _SwfdecIterateSource {
   GSource		source;
   SwfdecPlayer *	player;		/* player we manage or NULL if player was deleted */
   double		speed;		/* inverse playback speed (so 0.5 means double speed) */
-  gulong		notify;		/* set for iterate notifications */
+  gulong		notify;		/* set for iterate notifications (only valid when player != NULL) */
   GTimeVal		last;		/* last time */
 };
 
@@ -115,7 +115,7 @@ swfdec_iterate_finalize (GSource *source
 {
   SwfdecIterateSource *source = (SwfdecIterateSource *) source_;
 
-  if (source->notify) {
+  if (source->notify && source->player) {
     g_signal_handler_disconnect (source->player, source->notify);
   }
   if (source->player) {
diff-tree f21416fa0be5658c7e88bc2e57d77eacd369ff85 (from 3bd9ef83c764e80467cb95163ad7f7a779100d45)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 08:50:12 2007 +0200

    add test for depth when removing

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 6d0d774..aec7f1d 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -859,6 +859,15 @@ EXTRA_DIST = \
 	relational-6.swf.trace \
 	relational-7.swf \
 	relational-7.swf.trace \
+	remove-depths.as \
+	remove-depths-5.swf \
+	remove-depths-5.swf.trace \
+	remove-depths-6.swf \
+	remove-depths-6.swf.trace \
+	remove-depths-7.swf \
+	remove-depths-7.swf.trace \
+	remove-depths-8.swf \
+	remove-depths-8.swf.trace \
 	removesprite-depths.as \
 	removesprite-depths-5.swf \
 	removesprite-depths-5.swf.trace \
diff --git a/test/trace/remove-depths-5.swf b/test/trace/remove-depths-5.swf
new file mode 100644
index 0000000..d684bb9
Binary files /dev/null and b/test/trace/remove-depths-5.swf differ
diff --git a/test/trace/remove-depths-5.swf.trace b/test/trace/remove-depths-5.swf.trace
new file mode 100644
index 0000000..cdb6e9c
--- /dev/null
+++ b/test/trace/remove-depths-5.swf.trace
@@ -0,0 +1 @@
+Check how removing movieclips affects depth
diff --git a/test/trace/remove-depths-6.swf b/test/trace/remove-depths-6.swf
new file mode 100644
index 0000000..7545fbd
Binary files /dev/null and b/test/trace/remove-depths-6.swf differ
diff --git a/test/trace/remove-depths-6.swf.trace b/test/trace/remove-depths-6.swf.trace
new file mode 100644
index 0000000..e1b6d8b
--- /dev/null
+++ b/test/trace/remove-depths-6.swf.trace
@@ -0,0 +1,3 @@
+Check how removing movieclips affects depth
+0 => -32769
+1000 => -33769
diff --git a/test/trace/remove-depths-7.swf b/test/trace/remove-depths-7.swf
new file mode 100644
index 0000000..6bf4802
Binary files /dev/null and b/test/trace/remove-depths-7.swf differ
diff --git a/test/trace/remove-depths-7.swf.trace b/test/trace/remove-depths-7.swf.trace
new file mode 100644
index 0000000..e1b6d8b
--- /dev/null
+++ b/test/trace/remove-depths-7.swf.trace
@@ -0,0 +1,3 @@
+Check how removing movieclips affects depth
+0 => -32769
+1000 => -33769
diff --git a/test/trace/remove-depths-8.swf b/test/trace/remove-depths-8.swf
new file mode 100644
index 0000000..f0208da
Binary files /dev/null and b/test/trace/remove-depths-8.swf differ
diff --git a/test/trace/remove-depths-8.swf.trace b/test/trace/remove-depths-8.swf.trace
new file mode 100644
index 0000000..e1b6d8b
--- /dev/null
+++ b/test/trace/remove-depths-8.swf.trace
@@ -0,0 +1,3 @@
+Check how removing movieclips affects depth
+0 => -32769
+1000 => -33769
diff --git a/test/trace/remove-depths.as b/test/trace/remove-depths.as
new file mode 100644
index 0000000..562bdbf
--- /dev/null
+++ b/test/trace/remove-depths.as
@@ -0,0 +1,15 @@
+// makeswf -v 7 -s 200x150 -r 1 -o remove-depths.swf remove-depths.as
+
+depths = [ 0, -16384, -16385, 1000 ];
+for (i = 0; i < depths.length; i++) {
+  bla = createEmptyMovieClip ("foo" + i, depths[i]);
+  bla.depth = bla.getDepth ();
+  bla.onUnload = function () {
+    trace (this.depth + " => " + this.getDepth ());
+  };
+  bla.removeMovieClip ();
+}
+// We print that here so we know the onUnload gets triggered later
+trace ("Check how removing movieclips affects depth");
+
+loadMovie ("FSCommand:quit", "");
diff-tree 3bd9ef83c764e80467cb95163ad7f7a779100d45 (from cd4771d4b96dc96212d69810b22724d076d3a283)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 22 08:49:15 2007 +0200

    set the correct depth on remove

diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 6a03bd1..0f3cb91 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -260,7 +260,7 @@ swfdec_movie_do_remove (SwfdecMovie *mov
   if (player->mouse_drag == movie)
     player->mouse_drag = NULL;
   swfdec_movie_invalidate (movie);
-  swfdec_movie_set_depth (movie, -16385 - movie->depth); /* don't ask me why... */
+  swfdec_movie_set_depth (movie, -32769 - movie->depth); /* don't ask me why... */
 
   if (SWFDEC_IS_SPRITE_MOVIE (movie))
     return !swfdec_movie_queue_script (movie, SWFDEC_EVENT_UNLOAD);
diff-tree cd4771d4b96dc96212d69810b22724d076d3a283 (from 8ff61bf0eec2a7f45c5e4eabd558a8db899b489c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 23:48:43 2007 +0200

    implement depth notifications and reordering

diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
index 2ac4104..497ee27 100644
--- a/vivified/ui/vivi_movie_list.c
+++ b/vivified/ui/vivi_movie_list.c
@@ -272,6 +272,62 @@ vivi_movie_list_get_index (GNode *parent
   return i;
 }
 
+static void
+vivi_movie_list_movie_notify (SwfdecMovie *movie, GParamSpec *pspec, ViviMovieList *movies)
+{
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  GNode *node;
+
+  node = g_hash_table_lookup (movies->nodes, movie);
+  if (g_str_equal (pspec->name, "depth")) {
+    guint old, new;
+    GNode *parent;
+
+    parent = node->parent;
+    old = g_node_child_position (parent, node);
+    new = vivi_movie_list_get_index (parent, node);
+    if (old != new) {
+      /* reorder */
+      guint min = MIN (old, new);
+      guint max = MAX (old, new);
+      guint i;
+      guint count = g_node_n_children (parent);
+      int *positions = g_new (int, count);
+      g_print ("reordering %u => %u (%u total)\n", old, new, count);
+      for (i = 0; i < min; i++) {
+	positions[i] = i;
+      }
+      if (old < new) {
+	for (i = min; i < max; i++) {
+	  positions[i] = i + 1;
+	}
+      } else {
+	for (i = min + 1; i <= max; i++) {
+	  positions[i] = i - 1;
+	}
+      }
+      positions[new] = old;
+      for (i = max + 1; i < count; i++) {
+	positions[i] = i;
+      }
+      g_node_unlink (node);
+      g_node_insert (parent, new, node);
+      iter.stamp = movies->stamp;
+      iter.user_data = parent;
+      path = vivi_movie_list_node_to_path (parent);
+      gtk_tree_model_rows_reordered (GTK_TREE_MODEL (movies), path, &iter, positions);
+      gtk_tree_path_free (path);
+      g_free (positions);
+    }
+  }
+  iter.stamp = movies->stamp;
+  iter.user_data = node;
+  path = vivi_movie_list_node_to_path (node);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (movies), path, &iter);
+  gtk_tree_path_free (path);
+}
+
 static gboolean
 vivi_movie_list_added (ViviDebugger *debugger, SwfdecAsObject *object, ViviMovieList *movies)
 {
@@ -284,6 +340,7 @@ vivi_movie_list_added (ViviDebugger *deb
   if (!SWFDEC_IS_MOVIE (object))
     return FALSE;
   movie = SWFDEC_MOVIE (object);
+  g_signal_connect (movie, "notify", G_CALLBACK (vivi_movie_list_movie_notify), movies);
   if (movie->parent) {
     node = g_hash_table_lookup (movies->nodes, movie->parent);
     g_assert (node);
@@ -304,25 +361,6 @@ vivi_movie_list_added (ViviDebugger *deb
 }
 
 static void
-vivi_movie_list_movie_notify (SwfdecMovie *movie, GParamSpec *pspec, ViviMovieList *movies)
-{
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GNode *node;
-
-  node = g_hash_table_lookup (movies->nodes, movie);
-  if (g_str_equal (pspec->name, "depth")) {
-    /* reorder when depth changes */
-    g_printerr ("FIXME: implement depth changes\n");
-  }
-  iter.stamp = movies->stamp;
-  iter.user_data = node;
-  path = vivi_movie_list_node_to_path (node);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (movies), path, &iter);
-  gtk_tree_path_free (path);
-}
-
-static void
 vivi_movie_list_remove_node (ViviMovieList *movies, GNode *node)
 {
   GNode *walk;
diff-tree 8ff61bf0eec2a7f45c5e4eabd558a8db899b489c (from 4c236240442cdbb060e83af8540ef6e9253a06d3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:55:00 2007 +0200

    add a movies list on the left

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 2d492c7..c88facd 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -9,6 +9,7 @@ vivified_LDADD = \
 vivified_SOURCES = \
 	vivi_command_line.c \
 	vivi_movie_list.c \
+	vivi_movies.c \
 	vivi_player.c \
 	vivi_vivi_docklet.c \
 	main.c
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 8ca2e4b..f497e32 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -58,7 +58,7 @@ set_title (ViviApplication *app, GParamS
 static void
 setup (const char *filename, const char *variables)
 {
-  GtkWidget *window, *box, *widget;
+  GtkWidget *window, *box, *paned, *widget;
   ViviApplication *app;
   GtkBuilder *builder;
   GError *error = NULL;
@@ -69,17 +69,22 @@ setup (const char *filename, const char 
 
   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_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 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_window_set_default_size (GTK_WINDOW (window), 400, 450);
+  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_container_add (GTK_CONTAINER (window), box);
+  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);
@@ -88,6 +93,12 @@ setup (const char *filename, const char 
   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);
diff --git a/vivified/ui/vivi_movies.c b/vivified/ui/vivi_movies.c
new file mode 100644
index 0000000..a4c8e37
--- /dev/null
+++ b/vivified/ui/vivi_movies.c
@@ -0,0 +1,40 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libswfdec-gtk/swfdec-gtk.h>
+#include "vivi_vivi_docklet.h"
+#include "vivi_movie_list.h"
+
+void
+vivi_movies_application_set (ViviViviDocklet *docklet, ViviApplication *app);
+void
+vivi_movies_application_set (ViviViviDocklet *docklet, ViviApplication *app)
+{
+  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TREE_VIEW);
+  GtkTreeModel *model;
+
+  model = vivi_movie_list_new (app);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
+  g_object_unref (model);
+}
+
diff --git a/vivified/ui/vivi_movies.xml b/vivified/ui/vivi_movies.xml
new file mode 100644
index 0000000..47f1bdf
--- /dev/null
+++ b/vivified/ui/vivi_movies.xml
@@ -0,0 +1,38 @@
+<interface>
+  <object class="ViviViviDocklet" id="movies">
+    <property name="title">Movies</property>
+    <signal name="application-set" handler="vivi_movies_application_set" />
+    <child>
+      <object class="GtkScrolledWindow" id="1">
+	<property name="hscrollbar-policy">automatic</property>
+	<property name="vscrollbar-policy">automatic</property>
+	<child>
+	  <object class="GtkTreeView" id="x">
+	    <child>
+	      <object class="GtkTreeViewColumn" id="x">
+		<property name="title">Movie</property>
+		<child>
+		  <object class="GtkCellRendererText" id="x"/>
+		  <attributes>
+		    <attribute name="text">1</attribute>
+		  </attributes>
+		</child>
+	      </object>
+	    </child>
+	    <child>
+	      <object class="GtkTreeViewColumn" id="x">
+		<property name="title">Depth</property>
+		<child>
+		  <object class="GtkCellRendererText" id="x"/>
+		  <attributes>
+		    <attribute name="text">2</attribute>
+		  </attributes>
+		</child>
+	      </object>
+	    </child>
+	  </object>
+	</child>
+      </object>
+    </child>
+  </object>
+</interface>
diff-tree 4c236240442cdbb060e83af8540ef6e9253a06d3 (from cd57b9ab579ac803f64b351459380fb749daaa0f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:54:41 2007 +0200

    create the path before destroying the node

diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
index 7cca226..2ac4104 100644
--- a/vivified/ui/vivi_movie_list.c
+++ b/vivified/ui/vivi_movie_list.c
@@ -347,8 +347,8 @@ vivi_movie_list_removed (ViviDebugger *d
   if (node == NULL)
     return FALSE;
   vivi_movie_list_remove_node (movies, node);
-  g_node_destroy (node);
   path = vivi_movie_list_node_to_path (node);
+  g_node_destroy (node);
   gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);
   gtk_tree_path_free (path);
   return FALSE;
diff-tree cd57b9ab579ac803f64b351459380fb749daaa0f (from 1c017203cce97b97487e8513c645f9c6fe8b24e4)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:53:56 2007 +0200

    add a Player.sound property so disabling sound is possible
    
    It's incredibly useful in valgrind

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 68c4c09..8245fb1 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -49,6 +49,7 @@ Player = {};
 Player.addProperty ("filename", Native.player_filename_get, Native.player_filename_set);
 Player.addProperty ("frame", Native.player_frame_get, null);
 Player.addProperty ("global", Native.player_global_get, null);
+Player.addProperty ("sound", Native.player_sound_get, Native.player_sound_set);
 Player.addProperty ("variables", Native.player_variables_get, Native.player_variables_set);
 
 /*** commands available for debugging ***/
diff --git a/vivified/core/vivi_player_as.c b/vivified/core/vivi_player_as.c
index c7e36ad..4552cd4 100644
--- a/vivified/core/vivi_player_as.c
+++ b/vivified/core/vivi_player_as.c
@@ -24,6 +24,7 @@
 #include "vivi_wrap.h"
 #include "vivi_application.h"
 #include "vivi_function.h"
+#include <libswfdec-gtk/swfdec-gtk.h>
 
 VIVI_FUNCTION ("player_frame_get", vivi_player_as_frame_get)
 void
@@ -105,3 +106,27 @@ vivi_player_as_global_get (SwfdecAsConte
   }
 }
 
+VIVI_FUNCTION ("player_sound_get", vivi_player_as_sound_get)
+void
+vivi_player_as_sound_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  
+  SWFDEC_AS_VALUE_SET_BOOLEAN (retval,
+      swfdec_gtk_player_get_audio_enabled (SWFDEC_GTK_PLAYER (app->player)));
+}
+
+VIVI_FUNCTION ("player_sound_set", vivi_player_as_sound_set)
+void
+vivi_player_as_sound_set (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  
+  if (argc == 0)
+    return;
+  swfdec_gtk_player_set_audio_enabled (SWFDEC_GTK_PLAYER (app->player),
+      swfdec_as_value_to_boolean (cx, &argv[0]));
+}
+
diff-tree 1c017203cce97b97487e8513c645f9c6fe8b24e4 (from 913c4a3ab5636a3864733de41909cef0c847a52a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:53:01 2007 +0200

    save the sound enabled state across resets

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index b7f3b9f..19be22d 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -179,12 +179,16 @@ vivi_application_init_player (ViviApplic
 void
 vivi_application_reset (ViviApplication *app)
 {
+  gboolean audio;
+
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
   if (app->loop != NULL)
     g_main_loop_quit (app->loop);
+  audio = swfdec_gtk_player_get_audio_enabled (SWFDEC_GTK_PLAYER (app->player));
   g_object_unref (app->player);
   app->player = swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app->debugger));
+  swfdec_gtk_player_set_audio_enabled (SWFDEC_GTK_PLAYER (app->player), audio);
   app->player_inited = FALSE;
   g_object_notify (G_OBJECT (app), "player");
 }
diff-tree 913c4a3ab5636a3864733de41909cef0c847a52a (from e0014e23b2e4e34f777eeeb8bf5001af8cdd3ce5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:49:48 2007 +0200

    improve the assertion message

diff --git a/libswfdec/swfdec_button_movie.c b/libswfdec/swfdec_button_movie.c
index b48c746..c6d5b3c 100644
--- a/libswfdec/swfdec_button_movie.c
+++ b/libswfdec/swfdec_button_movie.c
@@ -171,7 +171,14 @@ swfdec_button_movie_change_mouse (Swfdec
 		     [(movie->mouse_in ? 2 : 0) + movie->mouse_button]
 		     [(mouse_in ? 2 : 0) + button];
 
-  g_assert (event != (guint) -1);
+#ifndef G_DISABLE_ASSERT
+  if (event == (guint) -1) {
+    g_error ("Unhandled event for %s: %u => %u",
+	movie->button->menubutton ? "menu" : "button",
+	(movie->mouse_in ? 2 : 0) + movie->mouse_button,
+	(mouse_in ? 2 : 0) + button);
+  }
+#endif
   if (event != 0) {
     SWFDEC_LOG ("emitting event for condition %u", event);
     swfdec_button_movie_execute (movie, event);
diff-tree e0014e23b2e4e34f777eeeb8bf5001af8cdd3ce5 (from 268e7076b34235aac77568686c29cc49c127171e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:49:34 2007 +0200

    mark the original name, too

diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 420c508..6a03bd1 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -794,6 +794,7 @@ swfdec_movie_mark (SwfdecAsObject *objec
   SwfdecMovie *movie = SWFDEC_MOVIE (object);
   GList *walk;
 
+  swfdec_as_string_mark (movie->original_name);
   swfdec_as_string_mark (movie->name);
   for (walk = movie->list; walk; walk = walk->next) {
     swfdec_as_object_mark (walk->data);
diff-tree 268e7076b34235aac77568686c29cc49c127171e (from 27da7a35529646e527d6430f7372f2535c66d623)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 22:04:37 2007 +0200

    print log message before executing action
    
    reason: the action can add new actions and this may invalidate the memory used
    by action. So we cannot print a debugging message with that data later

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index fa6eaab..1f9b2a3 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -309,9 +309,9 @@ swfdec_player_do_action (SwfdecPlayer *p
       return FALSE;
   } while (action->object == NULL); /* skip removed actions */
 
-  action->func (action->object, action->data);
   SWFDEC_LOG ("executing action %p %p %p", 
       action->object, action->func, action->data);
+  action->func (action->object, action->data);
 
   return TRUE;
 }
diff-tree 27da7a35529646e527d6430f7372f2535c66d623 (from 9a9bfa3d15f91d15beca8e7e926872029d1bae86)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 19:51:39 2007 +0200

    more fixes for disposing

diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
index 9177121..7cca226 100644
--- a/vivified/ui/vivi_movie_list.c
+++ b/vivified/ui/vivi_movie_list.c
@@ -329,9 +329,9 @@ vivi_movie_list_remove_node (ViviMovieLi
 
   for (walk = node->children; walk; walk = walk->next) {
     vivi_movie_list_remove_node (movies, walk);
-    g_hash_table_remove (movies->nodes, walk->data);
-    g_signal_handlers_disconnect_by_func (walk->data, vivi_movie_list_movie_notify, movies);
   }
+  g_hash_table_remove (movies->nodes, node->data);
+  g_signal_handlers_disconnect_by_func (node->data, vivi_movie_list_movie_notify, movies);
 }
 
 static gboolean
@@ -359,14 +359,21 @@ vivi_movie_list_dispose (GObject *object
 {
   ViviMovieList *movies = VIVI_MOVIE_LIST (object);
   ViviDebugger *debugger;
+  GNode *walk;
 
   debugger = movies->app->debugger;
   g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_removed, movies);
   g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_added, movies);
   g_object_unref (movies->app);
-  g_assert (g_node_n_children (movies->root) == 0);
+  for (walk = movies->root->children; walk; walk = walk->next) {
+    vivi_movie_list_remove_node (movies, walk);
+  }
   g_node_destroy (movies->root);
-  g_assert (g_hash_table_size (movies->nodes) == 0);
+#ifndef G_DISABLE_ASSERT
+  if (g_hash_table_size (movies->nodes) != 0) {
+    g_error ("%u items left in hash table", g_hash_table_size (movies->nodes));
+  }
+#endif
   g_hash_table_destroy (movies->nodes);
 
   G_OBJECT_CLASS (vivi_movie_list_parent_class)->dispose (object);
diff-tree 9a9bfa3d15f91d15beca8e7e926872029d1bae86 (from 317e8a19139a3dbf3ee2e291f7b5795bea7c2eb4)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 15:14:34 2007 +0200

    various bug fixes
    
    - crashers on removing
    - API: return a tree model from new()

diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
index 7a4ddef..9177121 100644
--- a/vivified/ui/vivi_movie_list.c
+++ b/vivified/ui/vivi_movie_list.c
@@ -322,6 +322,18 @@ vivi_movie_list_movie_notify (SwfdecMovi
   gtk_tree_path_free (path);
 }
 
+static void
+vivi_movie_list_remove_node (ViviMovieList *movies, GNode *node)
+{
+  GNode *walk;
+
+  for (walk = node->children; walk; walk = walk->next) {
+    vivi_movie_list_remove_node (movies, walk);
+    g_hash_table_remove (movies->nodes, walk->data);
+    g_signal_handlers_disconnect_by_func (walk->data, vivi_movie_list_movie_notify, movies);
+  }
+}
+
 static gboolean
 vivi_movie_list_removed (ViviDebugger *debugger, SwfdecAsObject *object, ViviMovieList *movies)
 {
@@ -331,11 +343,12 @@ vivi_movie_list_removed (ViviDebugger *d
   if (!SWFDEC_IS_MOVIE (object))
     return FALSE;
   node = g_hash_table_lookup (movies->nodes, object);
-  g_hash_table_remove (movies->nodes, object);
-  g_signal_handlers_disconnect_by_func (object, vivi_movie_list_movie_notify, movies);
-  path = vivi_movie_list_node_to_path (node);
-  g_assert (g_node_n_children (node) == 0);
+  /* happens when parent was already removed */
+  if (node == NULL)
+    return FALSE;
+  vivi_movie_list_remove_node (movies, node);
   g_node_destroy (node);
+  path = vivi_movie_list_node_to_path (node);
   gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);
   gtk_tree_path_free (path);
   return FALSE;
@@ -353,6 +366,7 @@ vivi_movie_list_dispose (GObject *object
   g_object_unref (movies->app);
   g_assert (g_node_n_children (movies->root) == 0);
   g_node_destroy (movies->root);
+  g_assert (g_hash_table_size (movies->nodes) == 0);
   g_hash_table_destroy (movies->nodes);
 
   G_OBJECT_CLASS (vivi_movie_list_parent_class)->dispose (object);
@@ -373,7 +387,7 @@ vivi_movie_list_init (ViviMovieList *mov
   movies->nodes = g_hash_table_new (g_direct_hash, g_direct_equal);
 }
 
-ViviMovieList *
+GtkTreeModel *
 vivi_movie_list_new (ViviApplication *app)
 {
   ViviMovieList *movies;
@@ -385,6 +399,6 @@ vivi_movie_list_new (ViviApplication *ap
   debugger = app->debugger;
   g_signal_connect (debugger, "add", G_CALLBACK (vivi_movie_list_added), movies);
   g_signal_connect (debugger, "remove", G_CALLBACK (vivi_movie_list_removed), movies);
-  return movies;
+  return GTK_TREE_MODEL (movies);
 }
 
diff --git a/vivified/ui/vivi_movie_list.h b/vivified/ui/vivi_movie_list.h
index ddd4a81..a030549 100644
--- a/vivified/ui/vivi_movie_list.h
+++ b/vivified/ui/vivi_movie_list.h
@@ -59,7 +59,7 @@ struct _ViviMovieListClass
 
 GType		vivi_movie_list_get_type		(void);
 
-ViviMovieList *	vivi_movie_list_new			(ViviApplication *	app);
+GtkTreeModel *	vivi_movie_list_new			(ViviApplication *	app);
 
 
 G_END_DECLS
diff-tree 317e8a19139a3dbf3ee2e291f7b5795bea7c2eb4 (from 3e6829af094100400d58f5540f3c13d7f6d7f63a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 15:13:10 2007 +0200

    make adding a third item work

diff --git a/vivified/dock/vivi_vdock.c b/vivified/dock/vivi_vdock.c
index f79cb2d..a7a4b34 100644
--- a/vivified/dock/vivi_vdock.c
+++ b/vivified/dock/vivi_vdock.c
@@ -92,7 +92,7 @@ vivi_vdock_add (ViviVDock *vdock, GtkWid
     if (parent == (GtkWidget *) vdock) {
       gtk_container_add (GTK_CONTAINER (vdock), paned);
     } else {
-      gtk_paned_pack1 (GTK_PANED (parent), paned, TRUE, FALSE);
+      gtk_paned_pack2 (GTK_PANED (parent), paned, TRUE, FALSE);
     }
   }
   vdock->docklets = g_list_prepend (vdock->docklets, widget);
diff-tree 3e6829af094100400d58f5540f3c13d7f6d7f63a (from 70040fde674cc20d5c9fa91250493cf81271542b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 14:02:05 2007 +0200

    add a Wrap.get() function to get variables

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 94507bc..68c4c09 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -21,6 +21,7 @@
 
 Wrap = function () {};
 Wrap.prototype = {};
+Wrap.prototype.get = Native.wrap_get;
 Wrap.prototype.toString = Native.wrap_toString;
 
 Frame = function () extends Wrap {};
diff --git a/vivified/core/vivi_wrap_as.c b/vivified/core/vivi_wrap_as.c
index 86aaca2..8110286 100644
--- a/vivified/core/vivi_wrap_as.c
+++ b/vivified/core/vivi_wrap_as.c
@@ -44,6 +44,29 @@ vivi_wrap_toString (SwfdecAsContext *cx,
   SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_give_string (cx, s));
 }
 
+VIVI_FUNCTION ("wrap_get", vivi_wrap_get)
+void
+vivi_wrap_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  ViviWrap *wrap;
+  SwfdecAsValue val;
+  const char *name;
+
+  if (!VIVI_IS_WRAP (this) || argc == 0)
+    return;
+  wrap = VIVI_WRAP (this);
+  if (wrap->wrap == NULL)
+    return;
+  
+  name = swfdec_as_value_to_string (cx, &argv[0]);
+  swfdec_as_object_get_variable (wrap->wrap, 
+      swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (app->player), name), 
+      &val);
+  vivi_wrap_value (app, retval, &val);
+}
+
 /*** FRAME specific code ***/
 
 VIVI_FUNCTION ("frame_name_get", vivi_wrap_name_get)
diff-tree 70040fde674cc20d5c9fa91250493cf81271542b (from ef85440d2e8a21ddaa688035b6071ce5eef6cc3b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 13:30:39 2007 +0200

    implement Frame.this

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 964f5b3..94507bc 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -28,6 +28,7 @@ Frame.prototype = new Wrap ();
 Frame.prototype.addProperty ("code", Native.frame_code_get, null);
 Frame.prototype.addProperty ("name", Native.frame_name_get, null);
 Frame.prototype.addProperty ("next", Native.frame_next_get, null);
+Frame.prototype.addProperty ("this", Native.frame_this_get, null);
 
 /*** breakpoints ***/
 
diff --git a/vivified/core/vivi_wrap_as.c b/vivified/core/vivi_wrap_as.c
index c905f34..86aaca2 100644
--- a/vivified/core/vivi_wrap_as.c
+++ b/vivified/core/vivi_wrap_as.c
@@ -106,4 +106,24 @@ vivi_wrap_next_get (SwfdecAsContext *cx,
     SWFDEC_AS_VALUE_SET_OBJECT (retval, vivi_wrap_object (VIVI_APPLICATION (cx), obj));
 }
 
+VIVI_FUNCTION ("frame_this_get", vivi_wrap_this_get)
+void
+vivi_wrap_this_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviWrap *wrap;
+  SwfdecAsObject *obj;
+
+  if (!VIVI_IS_WRAP (this))
+    return;
+  
+  wrap = VIVI_WRAP (this);
+  if (!SWFDEC_IS_AS_FRAME (wrap->wrap))
+    return;
+  
+  obj = SWFDEC_AS_OBJECT (swfdec_as_frame_get_this (SWFDEC_AS_FRAME (wrap->wrap)));
+  if (obj)
+    SWFDEC_AS_VALUE_SET_OBJECT (retval, vivi_wrap_object (VIVI_APPLICATION (cx), obj));
+}
+
 
diff-tree ef85440d2e8a21ddaa688035b6071ce5eef6cc3b (from 7f9eebf1183d28ceaaaf06d5910c9144eb5cc435)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 13:28:10 2007 +0200

    implement swfdec_as_frame_get_this ()

diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index c5f9076..019380c 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -375,6 +375,7 @@ SwfdecAsFrame
 swfdec_as_frame_get_next
 swfdec_as_frame_get_function_name
 swfdec_as_frame_get_script
+swfdec_as_frame_get_this
 SwfdecAsStackIterator
 swfdec_as_stack_iterator_init
 swfdec_as_stack_iterator_init_arguments
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index a9fe372..b7cb037 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -787,3 +787,20 @@ swfdec_as_frame_get_script (SwfdecAsFram
 
   return frame->script;
 }
+
+/**
+ * swfdec_as_frame_get_this:
+ * @frame: a #SwfdecAsFrame
+ *
+ * Gets the this object of the given @frame. If the frame has no this object,
+ * %NULL is returned.
+ *
+ * Returns: The this object of the frame or %NULL if none.
+ **/
+SwfdecAsObject *
+swfdec_as_frame_get_this (SwfdecAsFrame *frame)
+{
+  g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
+
+  return frame->thisp;
+}
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 8157858..344eaa7 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -49,6 +49,7 @@ GType		swfdec_as_frame_get_type	(void);
 SwfdecAsFrame *	swfdec_as_frame_get_next	(SwfdecAsFrame *		frame);
 const char *	swfdec_as_frame_get_function_name (SwfdecAsFrame *		frame);
 SwfdecScript *	swfdec_as_frame_get_script	(SwfdecAsFrame *		frame);
+SwfdecAsObject *swfdec_as_frame_get_this	(SwfdecAsFrame *		frame);
 
 SwfdecAsValue *	swfdec_as_stack_iterator_init	(SwfdecAsStackIterator *	iter,
 						 SwfdecAsFrame *		frame);
diff-tree 7f9eebf1183d28ceaaaf06d5910c9144eb5cc435 (from 9ee0631673a83e6a59448873ab93b90311d8d88b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 13:26:13 2007 +0200

    implement debug-printing for SwfdecAsString

diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c
index 720bc5c..96f311d 100644
--- a/libswfdec/swfdec_as_string.c
+++ b/libswfdec/swfdec_as_string.c
@@ -43,12 +43,21 @@ swfdec_as_string_do_mark (SwfdecAsObject
   SWFDEC_AS_OBJECT_CLASS (swfdec_as_string_parent_class)->mark (object);
 }
 
+static char *
+swfdec_as_string_debug (SwfdecAsObject *object)
+{
+  SwfdecAsString *string = SWFDEC_AS_STRING (object);
+
+  return g_strdup (string->string);
+}
+
 static void
 swfdec_as_string_class_init (SwfdecAsStringClass *klass)
 {
   SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass);
 
   asobject_class->mark = swfdec_as_string_do_mark;
+  asobject_class->debug = swfdec_as_string_debug;
 }
 
 static void
diff-tree 9ee0631673a83e6a59448873ab93b90311d8d88b (from c950a3ae200518bea4d98b8f0a993d3bbaafe212)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 12:48:34 2007 +0200

    consistent naming please

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 386d6cb..2d492c7 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -7,7 +7,7 @@ vivified_LDADD = \
 	$(top_builddir)/vivified/dock/libvivified-dock.la
 
 vivified_SOURCES = \
-	vivi_commandline.c \
+	vivi_command_line.c \
 	vivi_movie_list.c \
 	vivi_player.c \
 	vivi_vivi_docklet.c \
diff --git a/vivified/ui/vivi_command_line.c b/vivified/ui/vivi_command_line.c
new file mode 100644
index 0000000..4377830
--- /dev/null
+++ b/vivified/ui/vivi_command_line.c
@@ -0,0 +1,118 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include "vivi_vivi_docklet.h"
+
+static void
+vivi_command_line_execute (ViviApplication *app, const char *command)
+{
+  char *run;
+
+  if (!strpbrk (command, ";\"',()[]{}")) {
+    /* special mode: interpret as space-delimited list:
+     * first argument is function name, following arguemnts are function arguments
+     */
+    char **args = g_strsplit (command, " ", -1);
+    GString *str = g_string_new (args[0]);
+    guint i;
+
+    g_string_append (str, " (");
+    for (i = 1; args[i] != NULL; i++) {
+      if (i > 1)
+	g_string_append (str, ", ");
+      g_string_append_c (str, '"');
+      g_string_append (str, args[i]);
+      g_string_append_c (str, '"');
+    }
+    g_string_append (str, ");");
+    run = g_string_free (str, FALSE);
+  } else {
+    run = (char *) command;
+  }
+
+  
+  vivi_application_execute (app, run);
+  if (command != run)
+    g_free (run);
+}
+
+void
+vivi_command_line_activate (GtkEntry *entry, ViviApplication *app);
+void
+vivi_command_line_activate (GtkEntry *entry, ViviApplication *app)
+{
+  const char *text = gtk_entry_get_text (entry);
+
+  if (text[0] == '\0')
+    return;
+
+  vivi_command_line_execute (app, text);
+  gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
+}
+
+static void
+vivi_command_line_append_message (ViviApplication *app, guint type, const char *message, GtkTextView *view)
+{
+  GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
+  GtkTextIter iter;
+  GtkTextMark *mark;
+  const char *tag_names[] = { "input", "output", "error" };
+
+  gtk_text_buffer_get_end_iter (buffer, &iter);
+  mark = gtk_text_buffer_get_mark (buffer, "end");
+  if (mark == NULL)
+    mark = gtk_text_buffer_create_mark (buffer, "end", &iter, FALSE);
+  if (gtk_text_buffer_get_char_count (buffer) > 0)
+    gtk_text_buffer_insert (buffer, &iter, "\n", 1);
+  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1, tag_names[type], NULL);
+  gtk_text_view_scroll_to_mark (view, mark, 0.0, TRUE, 0.0, 0.0);
+}
+
+void
+vivi_command_line_application_unset (ViviViviDocklet *docklet, ViviApplication *app);
+void
+vivi_command_line_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
+{
+  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TEXT_VIEW);
+
+  g_signal_handlers_disconnect_by_func (app, vivi_command_line_append_message, view);
+}
+
+void
+vivi_command_line_application_set (ViviViviDocklet *docklet, ViviApplication *app);
+void
+vivi_command_line_application_set (ViviViviDocklet *docklet, ViviApplication *app)
+{
+  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TEXT_VIEW);
+
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
+      "error", "foreground", "red", "left-margin", 15, NULL);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
+      "input", "foreground", "dark grey", NULL);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
+      "output", "left-margin", 15, NULL);
+
+  g_signal_connect (app, "message", G_CALLBACK (vivi_command_line_append_message), view);
+}
+
diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
deleted file mode 100644
index 4377830..0000000
--- a/vivified/ui/vivi_commandline.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Vivified
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
- * Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include "vivi_vivi_docklet.h"
-
-static void
-vivi_command_line_execute (ViviApplication *app, const char *command)
-{
-  char *run;
-
-  if (!strpbrk (command, ";\"',()[]{}")) {
-    /* special mode: interpret as space-delimited list:
-     * first argument is function name, following arguemnts are function arguments
-     */
-    char **args = g_strsplit (command, " ", -1);
-    GString *str = g_string_new (args[0]);
-    guint i;
-
-    g_string_append (str, " (");
-    for (i = 1; args[i] != NULL; i++) {
-      if (i > 1)
-	g_string_append (str, ", ");
-      g_string_append_c (str, '"');
-      g_string_append (str, args[i]);
-      g_string_append_c (str, '"');
-    }
-    g_string_append (str, ");");
-    run = g_string_free (str, FALSE);
-  } else {
-    run = (char *) command;
-  }
-
-  
-  vivi_application_execute (app, run);
-  if (command != run)
-    g_free (run);
-}
-
-void
-vivi_command_line_activate (GtkEntry *entry, ViviApplication *app);
-void
-vivi_command_line_activate (GtkEntry *entry, ViviApplication *app)
-{
-  const char *text = gtk_entry_get_text (entry);
-
-  if (text[0] == '\0')
-    return;
-
-  vivi_command_line_execute (app, text);
-  gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
-}
-
-static void
-vivi_command_line_append_message (ViviApplication *app, guint type, const char *message, GtkTextView *view)
-{
-  GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
-  GtkTextIter iter;
-  GtkTextMark *mark;
-  const char *tag_names[] = { "input", "output", "error" };
-
-  gtk_text_buffer_get_end_iter (buffer, &iter);
-  mark = gtk_text_buffer_get_mark (buffer, "end");
-  if (mark == NULL)
-    mark = gtk_text_buffer_create_mark (buffer, "end", &iter, FALSE);
-  if (gtk_text_buffer_get_char_count (buffer) > 0)
-    gtk_text_buffer_insert (buffer, &iter, "\n", 1);
-  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1, tag_names[type], NULL);
-  gtk_text_view_scroll_to_mark (view, mark, 0.0, TRUE, 0.0, 0.0);
-}
-
-void
-vivi_command_line_application_unset (ViviViviDocklet *docklet, ViviApplication *app);
-void
-vivi_command_line_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
-{
-  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TEXT_VIEW);
-
-  g_signal_handlers_disconnect_by_func (app, vivi_command_line_append_message, view);
-}
-
-void
-vivi_command_line_application_set (ViviViviDocklet *docklet, ViviApplication *app);
-void
-vivi_command_line_application_set (ViviViviDocklet *docklet, ViviApplication *app)
-{
-  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TEXT_VIEW);
-
-  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
-      "error", "foreground", "red", "left-margin", 15, NULL);
-  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
-      "input", "foreground", "dark grey", NULL);
-  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
-      "output", "left-margin", 15, NULL);
-
-  g_signal_connect (app, "message", G_CALLBACK (vivi_command_line_append_message), view);
-}
-
diff-tree c950a3ae200518bea4d98b8f0a993d3bbaafe212 (from 688a8514a7bb646b3417b71c37f99472793090d4)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 12:48:03 2007 +0200

    missed the title

diff --git a/vivified/ui/vivi_command_line.xml b/vivified/ui/vivi_command_line.xml
index e1829da..5a4b2fb 100644
--- a/vivified/ui/vivi_command_line.xml
+++ b/vivified/ui/vivi_command_line.xml
@@ -1,5 +1,6 @@
 <interface>
   <object class="ViviViviDocklet" id="command-line">
+    <property name="title">Command Line</property>
     <signal name="application-set" handler="vivi_command_line_application_set" />
     <signal name="application-unset" handler="vivi_command_line_application_unset" />
     <child>
diff-tree 688a8514a7bb646b3417b71c37f99472793090d4 (from 1bb42f2089e1c0530e34c060b8e90310f682a849)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 12:47:17 2007 +0200

    xml-ify the command line widget

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 147c0cb..386d6cb 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -14,7 +14,6 @@ vivified_SOURCES = \
 	main.c
 
 noinst_HEADERS = \
-	vivi_commandline.h \
 	vivi_movie_list.h \
 	vivi_vivi_docklet.h
 
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index e6fb346..8ca2e4b 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -25,7 +25,6 @@
 #include <libswfdec-gtk/swfdec-gtk.h>
 #include "vivified/core/vivified-core.h"
 #include "vivified/dock/vivified-dock.h"
-#include "vivi_commandline.h"
 
 static void
 try_grab_focus (GtkWidget *widget, gpointer unused)
@@ -69,7 +68,8 @@ setup (const char *filename, const char 
   vivi_application_set_variables (app, variables);
 
   builder = gtk_builder_new ();
-  if (!gtk_builder_add_from_file (builder, "vivi_player.xml", &error))
+  if (!gtk_builder_add_from_file (builder, "vivi_player.xml", &error) ||
+      !gtk_builder_add_from_file (builder, "vivi_command_line.xml", &error))
     g_error ("%s", error->message);
   gtk_builder_connect_signals (builder, app);
 
@@ -83,7 +83,8 @@ setup (const char *filename, const char 
   widget = GTK_WIDGET (gtk_builder_get_object (builder, "player"));
   g_object_set (widget, "application", app, NULL);
   vivi_vdock_add (VIVI_VDOCK (box), widget);
-  widget = vivi_command_line_new (app);
+  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);
 
diff --git a/vivified/ui/vivi_command_line.xml b/vivified/ui/vivi_command_line.xml
new file mode 100644
index 0000000..e1829da
--- /dev/null
+++ b/vivified/ui/vivi_command_line.xml
@@ -0,0 +1,37 @@
+<interface>
+  <object class="ViviViviDocklet" id="command-line">
+    <signal name="application-set" handler="vivi_command_line_application_set" />
+    <signal name="application-unset" handler="vivi_command_line_application_unset" />
+    <child>
+      <object class="GtkVBox" id="box">
+	<child>
+	  <object class="GtkScrolledWindow" id="scroll">
+	    <property name="hscrollbar-policy">automatic</property>
+	    <property name="vscrollbar-policy">automatic</property>
+	    <child>
+	      <object class="GtkTextView" id="text">
+		<property name="editable">false</property>
+		<property name="wrap-mode">word-char</property>
+	      </object>
+	    </child>
+	  </object>
+	  <packing>
+	    <property name="pack-type">start</property>
+	    <property name="expand">true</property>
+	    <property name="fill">true</property>
+	  </packing>
+	</child>
+	<child>
+	  <object class="GtkEntry" id="entry">
+	    <signal name="activate" handler="vivi_command_line_activate" />
+	  </object>
+	  <packing>
+	    <property name="pack-type">end</property>
+	    <property name="expand">false</property>
+	    <property name="fill">true</property>
+	  </packing>
+	</child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
index 555e922..4377830 100644
--- a/vivified/ui/vivi_commandline.c
+++ b/vivified/ui/vivi_commandline.c
@@ -22,48 +22,10 @@
 #endif
 
 #include <string.h>
-#include "vivi_commandline.h"
-
-G_DEFINE_TYPE (ViviCommandLine, vivi_command_line, VIVI_TYPE_DOCKLET)
-
-static void
-vivi_command_line_append_message (ViviApplication *app, guint type, const char *message, GtkTextView *view)
-{
-  GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
-  GtkTextIter iter;
-  GtkTextMark *mark;
-  const char *tag_names[] = { "input", "output", "error" };
-
-  gtk_text_buffer_get_end_iter (buffer, &iter);
-  mark = gtk_text_buffer_get_mark (buffer, "end");
-  if (mark == NULL)
-    mark = gtk_text_buffer_create_mark (buffer, "end", &iter, FALSE);
-  if (gtk_text_buffer_get_char_count (buffer) > 0)
-    gtk_text_buffer_insert (buffer, &iter, "\n", 1);
-  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1, tag_names[type], NULL);
-  gtk_text_view_scroll_to_mark (view, mark, 0.0, TRUE, 0.0, 0.0);
-}
-
-static void
-vivi_command_line_dispose (GObject *object)
-{
-  ViviCommandLine *cl = VIVI_COMMAND_LINE (object);
-
-  g_signal_handlers_disconnect_by_func (cl->app, vivi_command_line_append_message, cl->view);
-
-  G_OBJECT_CLASS (vivi_command_line_parent_class)->dispose (object);
-}
-
-static void
-vivi_command_line_class_init (ViviCommandLineClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->dispose = vivi_command_line_dispose;
-}
+#include "vivi_vivi_docklet.h"
 
 static void
-vivi_command_line_execute (ViviCommandLine *cl, const char *command)
+vivi_command_line_execute (ViviApplication *app, const char *command)
 {
   char *run;
 
@@ -90,61 +52,67 @@ vivi_command_line_execute (ViviCommandLi
   }
 
   
-  vivi_application_execute (cl->app, run);
+  vivi_application_execute (app, run);
   if (command != run)
     g_free (run);
 }
 
-static void
-command_line_entry_activate_cb (GtkEntry *entry, ViviCommandLine *command_line)
+void
+vivi_command_line_activate (GtkEntry *entry, ViviApplication *app);
+void
+vivi_command_line_activate (GtkEntry *entry, ViviApplication *app)
 {
   const char *text = gtk_entry_get_text (entry);
 
   if (text[0] == '\0')
     return;
 
-  vivi_command_line_execute (command_line, text);
+  vivi_command_line_execute (app, text);
   gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
 }
 
 static void
-vivi_command_line_init (ViviCommandLine *cl)
+vivi_command_line_append_message (ViviApplication *app, guint type, const char *message, GtkTextView *view)
 {
-  GtkWidget *box, *widget, *scroll;
+  GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
+  GtkTextIter iter;
+  GtkTextMark *mark;
+  const char *tag_names[] = { "input", "output", "error" };
 
-  box = gtk_vbox_new (FALSE, 0);
-  gtk_container_add (GTK_CONTAINER (cl), box);
-  /* the text entry */
-  widget = gtk_entry_new ();
-  g_signal_connect (widget, "activate", G_CALLBACK (command_line_entry_activate_cb), cl);
-  gtk_box_pack_end (GTK_BOX (box), widget, FALSE, TRUE, 0);
-  /* the text view for outputting messages */
-  scroll = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), 
-      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-  gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
-  cl->view = gtk_text_view_new ();
-  gtk_text_view_set_editable (GTK_TEXT_VIEW (cl->view), FALSE);
-  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (cl->view), GTK_WRAP_WORD_CHAR);
-  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (cl->view)),
-      "error", "foreground", "red", "left-margin", 15, NULL);
-  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (cl->view)),
-      "input", "foreground", "dark grey", NULL);
-  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (cl->view)),
-      "output", "left-margin", 15, NULL);
-  gtk_container_add (GTK_CONTAINER (scroll), cl->view);
+  gtk_text_buffer_get_end_iter (buffer, &iter);
+  mark = gtk_text_buffer_get_mark (buffer, "end");
+  if (mark == NULL)
+    mark = gtk_text_buffer_create_mark (buffer, "end", &iter, FALSE);
+  if (gtk_text_buffer_get_char_count (buffer) > 0)
+    gtk_text_buffer_insert (buffer, &iter, "\n", 1);
+  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1, tag_names[type], NULL);
+  gtk_text_view_scroll_to_mark (view, mark, 0.0, TRUE, 0.0, 0.0);
+}
 
-  gtk_widget_show_all (box);
+void
+vivi_command_line_application_unset (ViviViviDocklet *docklet, ViviApplication *app);
+void
+vivi_command_line_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
+{
+  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TEXT_VIEW);
+
+  g_signal_handlers_disconnect_by_func (app, vivi_command_line_append_message, view);
 }
 
-GtkWidget *
-vivi_command_line_new (ViviApplication *app)
+void
+vivi_command_line_application_set (ViviViviDocklet *docklet, ViviApplication *app);
+void
+vivi_command_line_application_set (ViviViviDocklet *docklet, ViviApplication *app)
 {
-  ViviCommandLine *cl;
+  GtkWidget *view = vivi_vivi_docklet_find_widget_by_type (docklet, GTK_TYPE_TEXT_VIEW);
+
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
+      "error", "foreground", "red", "left-margin", 15, NULL);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
+      "input", "foreground", "dark grey", NULL);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)),
+      "output", "left-margin", 15, NULL);
 
-  cl = g_object_new (VIVI_TYPE_COMMAND_LINE, "title", "Command Line", NULL);
-  cl->app = app;
-  g_signal_connect (cl->app, "message", G_CALLBACK (vivi_command_line_append_message), cl->view);
-  return GTK_WIDGET (cl);
+  g_signal_connect (app, "message", G_CALLBACK (vivi_command_line_append_message), view);
 }
 
diff --git a/vivified/ui/vivi_commandline.h b/vivified/ui/vivi_commandline.h
deleted file mode 100644
index 96e5924..0000000
--- a/vivified/ui/vivi_commandline.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Vivified
- * 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 _VIVI_COMMAND_LINE_H_
-#define _VIVI_COMMAND_LINE_H_
-
-#include <vivified/core/vivified-core.h>
-#include <vivified/dock/vivified-dock.h>
-
-G_BEGIN_DECLS
-
-
-typedef struct _ViviCommandLine ViviCommandLine;
-typedef struct _ViviCommandLineClass ViviCommandLineClass;
-
-#define VIVI_TYPE_COMMAND_LINE                    (vivi_command_line_get_type())
-#define VIVI_IS_COMMAND_LINE(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_COMMAND_LINE))
-#define VIVI_IS_COMMAND_LINE_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_COMMAND_LINE))
-#define VIVI_COMMAND_LINE(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_COMMAND_LINE, ViviCommandLine))
-#define VIVI_COMMAND_LINE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_COMMAND_LINE, ViviCommandLineClass))
-#define VIVI_COMMAND_LINE_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_COMMAND_LINE, ViviCommandLineClass))
-
-struct _ViviCommandLine {
-  ViviDocklet		docklet;
-
-  ViviApplication *	app;		/* the application we connect to */
-  GtkWidget *		view;		/* text view for outputting stuff to */
-};
-
-struct _ViviCommandLineClass
-{
-  ViviDockletClass    	docklet_class;
-};
-
-GType			vivi_command_line_get_type   	(void);
-
-GtkWidget *		vivi_command_line_new		(ViviApplication *	app);
-
-
-G_END_DECLS
-#endif
diff-tree 1bb42f2089e1c0530e34c060b8e90310f682a849 (from ab10b3c5c72a4e04b5f27027f90f58023d0a3594)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 12:44:15 2007 +0200

    add find_widget function to ViviViviDocklet

diff --git a/vivified/ui/vivi_player.c b/vivified/ui/vivi_player.c
index 876eb77..6fcfee2 100644
--- a/vivified/ui/vivi_player.c
+++ b/vivified/ui/vivi_player.c
@@ -25,18 +25,6 @@
 #include "vivi_vivi_docklet.h"
 
 static void
-find_player (GtkWidget *widget, gpointer result)
-{
-  if (SWFDEC_IS_GTK_WIDGET (widget)) {
-    *(gpointer *) result = widget;
-    return;
-  }
-
-  if (GTK_IS_CONTAINER (widget))
-    gtk_container_foreach (GTK_CONTAINER (widget), find_player, result);
-}
-
-static void
 vivi_player_notify_app (ViviApplication *app, GParamSpec *pspec, SwfdecGtkWidget *player)
 {
   if (g_str_equal (pspec->name, "player")) {
@@ -51,13 +39,11 @@ vivi_player_application_set (ViviViviDoc
 void
 vivi_player_application_set (ViviViviDocklet *docklet, ViviApplication *app)
 {
-  SwfdecGtkPlayer *player = NULL;
+  SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (vivi_vivi_docklet_find_widget_by_type (docklet, SWFDEC_TYPE_GTK_WIDGET));
 
-  find_player (GTK_WIDGET (docklet), &player);
-
-  g_signal_connect (app, "notify", G_CALLBACK (vivi_player_notify_app), player);
-  swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player), vivi_application_get_player (app));
-  swfdec_gtk_widget_set_interactive (SWFDEC_GTK_WIDGET (player), !vivi_application_get_interrupted (app));
+  g_signal_connect (app, "notify", G_CALLBACK (vivi_player_notify_app), widget);
+  swfdec_gtk_widget_set_player (widget, vivi_application_get_player (app));
+  swfdec_gtk_widget_set_interactive (widget, !vivi_application_get_interrupted (app));
 }
 
 void
@@ -65,10 +51,8 @@ vivi_player_application_unset (ViviViviD
 void
 vivi_player_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
 {
-  SwfdecGtkPlayer *player = NULL;
-
-  find_player (GTK_WIDGET (docklet), &player);
+  SwfdecGtkWidget *widget = SWFDEC_GTK_WIDGET (vivi_vivi_docklet_find_widget_by_type (docklet, SWFDEC_TYPE_GTK_WIDGET));
 
-  g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, player);
+  g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, widget);
 }
 
diff --git a/vivified/ui/vivi_vivi_docklet.c b/vivified/ui/vivi_vivi_docklet.c
index 9daba21..cea4f64 100644
--- a/vivified/ui/vivi_vivi_docklet.c
+++ b/vivified/ui/vivi_vivi_docklet.c
@@ -114,7 +114,37 @@ vivi_vivi_docklet_class_init (ViviViviDo
 }
 
 static void
-vivi_vivi_docklet_init (ViviViviDocklet *vivi_docklet)
+vivi_vivi_docklet_init (ViviViviDocklet *docklet)
 {
 }
 
+typedef struct {
+  GtkWidget *	result;
+  GType		desired_type;
+} FindData;
+
+static void
+find_widget (GtkWidget *widget, gpointer datap)
+{
+  FindData *data = datap;
+
+  if (G_TYPE_CHECK_INSTANCE_TYPE (widget, data->desired_type)) {
+    data->result = widget;
+    return;
+  }
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget), find_widget, data);
+}
+
+GtkWidget *
+vivi_vivi_docklet_find_widget_by_type (ViviViviDocklet *docklet, GType type)
+{
+  FindData data = { NULL, };
+
+  g_return_val_if_fail (VIVI_IS_VIVI_DOCKLET (docklet), NULL);
+  g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), NULL);
+
+  data.desired_type = type;
+  gtk_container_foreach (GTK_CONTAINER (docklet), find_widget, &data);
+  return data.result;
+}
diff --git a/vivified/ui/vivi_vivi_docklet.h b/vivified/ui/vivi_vivi_docklet.h
index 108b531..8142ae1 100644
--- a/vivified/ui/vivi_vivi_docklet.h
+++ b/vivified/ui/vivi_vivi_docklet.h
@@ -54,6 +54,9 @@ struct _ViviViviDockletClass
 
 GType			vivi_vivi_docklet_get_type   	(void);
 
+GtkWidget *		vivi_vivi_docklet_find_widget_by_type 
+							(ViviViviDocklet *	docklet,
+							 GType			type);
 
 G_END_DECLS
 #endif
diff-tree ab10b3c5c72a4e04b5f27027f90f58023d0a3594 (from abde6f7e4fb033f3c13f204a5de24aeb22f30854)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 12:12:06 2007 +0200

    use the application as default data when connecting signals

diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 1d57fa8..e6fb346 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -71,7 +71,7 @@ setup (const char *filename, const char 
   builder = gtk_builder_new ();
   if (!gtk_builder_add_from_file (builder, "vivi_player.xml", &error))
     g_error ("%s", error->message);
-  gtk_builder_connect_signals (builder, NULL);
+  gtk_builder_connect_signals (builder, app);
 
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size (GTK_WINDOW (window), 400, 450);
diff-tree abde6f7e4fb033f3c13f204a5de24aeb22f30854 (from 7bbd6ebee1796e6d396d5b5dfdb99613124fe05a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 12:03:47 2007 +0200

    make vivified use GtkBuilder for its docklets
    
    contains a port of the player docklet to GtkBuilder

diff --git a/configure.ac b/configure.ac
index 63a0bde..b1e81b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -272,11 +272,12 @@ AC_ARG_ENABLE(vivified,
 if test "$enable_vivi" = "yes"; then
 	AM_PROG_AS
 	MING_REQUIRED=0.4.0.beta5
-	PKG_CHECK_MODULES(VIVI, libming >= $MING_REQUIRED, HAVE_VIVI=yes, HAVE_VIVI=no)
+	VIVI_GTK_REQUIRED=2.11.6
+	PKG_CHECK_MODULES(VIVI, libming >= $MING_REQUIRED gmodule-export-2.0 gtk+-2.0 >= $VIVI_GTK_REQUIRED, HAVE_VIVI=yes, HAVE_VIVI=no)
 	if test "x$HAVE_VIVI" = xyes; then
 	  AC_DEFINE(HAVE_VIVI, 1, [Define if Vivified is enabled])
 	else
-	  AC_MSG_ERROR([Vivified requirements not met. You need at libming >= $MING_REQUIRED.])
+	  AC_MSG_ERROR([Vivified requirements not met. You need libming >= $MING_REQUIRED and Gtk+ >= $VIVI_GTK_REQUIRED.])
 	fi
 else
 	AC_MSG_WARN([*** Vivified was not enabled. ***])
diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index d6dad12..147c0cb 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -1,7 +1,7 @@
 noinst_PROGRAMS = vivified
 
-vivified_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS)
-vivified_LDFLAGS = $(SWFDEC_GTK_LIBS)
+vivified_CFLAGS = $(GLOBAL_CFLAGS) $(VIVI_CFLAGS)
+vivified_LDFLAGS = $(VIVI_LIBS) 
 vivified_LDADD = \
 	$(top_builddir)/vivified/core/libvivified-core.la \
 	$(top_builddir)/vivified/dock/libvivified-dock.la
@@ -16,6 +16,5 @@ vivified_SOURCES = \
 noinst_HEADERS = \
 	vivi_commandline.h \
 	vivi_movie_list.h \
-	vivi_player.h \
 	vivi_vivi_docklet.h
 
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index fe4b35c..1d57fa8 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -26,7 +26,6 @@
 #include "vivified/core/vivified-core.h"
 #include "vivified/dock/vivified-dock.h"
 #include "vivi_commandline.h"
-#include "vivi_player.h"
 
 static void
 try_grab_focus (GtkWidget *widget, gpointer unused)
@@ -62,10 +61,18 @@ setup (const char *filename, const char 
 {
   GtkWidget *window, *box, *widget;
   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))
+    g_error ("%s", error->message);
+  gtk_builder_connect_signals (builder, NULL);
+
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size (GTK_WINDOW (window), 400, 450);
   g_signal_connect_swapped (app, "notify::quit", G_CALLBACK (gtk_widget_destroy), window);
@@ -73,7 +80,8 @@ setup (const char *filename, const char 
   set_title (app, NULL, GTK_WINDOW (window));
   box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
-  widget = vivi_player_new (app);
+  widget = GTK_WIDGET (gtk_builder_get_object (builder, "player"));
+  g_object_set (widget, "application", app, NULL);
   vivi_vdock_add (VIVI_VDOCK (box), widget);
   widget = vivi_command_line_new (app);
   vivi_vdock_add (VIVI_VDOCK (box), widget);
@@ -82,6 +90,7 @@ setup (const char *filename, const char 
   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_player.c b/vivified/ui/vivi_player.c
index 4732d68..876eb77 100644
--- a/vivified/ui/vivi_player.c
+++ b/vivified/ui/vivi_player.c
@@ -21,10 +21,8 @@
 #include "config.h"
 #endif
 
-#include "vivi_player.h"
 #include <libswfdec-gtk/swfdec-gtk.h>
-
-G_DEFINE_TYPE (ViviPlayer, vivi_player, VIVI_TYPE_VIVI_DOCKLET)
+#include "vivi_vivi_docklet.h"
 
 static void
 find_player (GtkWidget *widget, gpointer result)
@@ -48,7 +46,9 @@ vivi_player_notify_app (ViviApplication 
   }
 }
 
-static void
+void
+vivi_player_application_set (ViviViviDocklet *docklet, ViviApplication *app);
+void
 vivi_player_application_set (ViviViviDocklet *docklet, ViviApplication *app)
 {
   SwfdecGtkPlayer *player = NULL;
@@ -60,7 +60,9 @@ vivi_player_application_set (ViviViviDoc
   swfdec_gtk_widget_set_interactive (SWFDEC_GTK_WIDGET (player), !vivi_application_get_interrupted (app));
 }
 
-static void
+void
+vivi_player_application_unset (ViviViviDocklet *docklet, ViviApplication *app);
+void
 vivi_player_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
 {
   SwfdecGtkPlayer *player = NULL;
@@ -70,32 +72,3 @@ vivi_player_application_unset (ViviViviD
   g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, player);
 }
 
-static void
-vivi_player_class_init (ViviPlayerClass *klass)
-{
-  ViviViviDockletClass *vivi_docklet_class = VIVI_VIVI_DOCKLET_CLASS (klass);
-
-  vivi_docklet_class->application_set = vivi_player_application_set;
-  vivi_docklet_class->application_unset = vivi_player_application_unset;
-}
-
-static void
-vivi_player_init (ViviPlayer *player)
-{
-  GtkWidget *box, *widget;
-
-  box = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-  gtk_container_add (GTK_CONTAINER (player), box);
-  /* the player */
-  widget = swfdec_gtk_widget_new (NULL);
-  gtk_container_add (GTK_CONTAINER (box), widget);
-
-  gtk_widget_show_all (box);
-}
-
-GtkWidget *
-vivi_player_new (ViviApplication *app)
-{
-  return g_object_new (VIVI_TYPE_PLAYER, "title", "Player", "application", app, NULL);
-}
-
diff --git a/vivified/ui/vivi_player.h b/vivified/ui/vivi_player.h
deleted file mode 100644
index c2aa1dd..0000000
--- a/vivified/ui/vivi_player.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Vivified
- * 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 _VIVI_PLAYER_H_
-#define _VIVI_PLAYER_H_
-
-#include <vivified/core/vivified-core.h>
-#include <vivified/dock/vivified-dock.h>
-#include <vivified/ui/vivi_vivi_docklet.h>
-
-G_BEGIN_DECLS
-
-
-typedef struct _ViviPlayer ViviPlayer;
-typedef struct _ViviPlayerClass ViviPlayerClass;
-
-#define VIVI_TYPE_PLAYER                    (vivi_player_get_type())
-#define VIVI_IS_PLAYER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_PLAYER))
-#define VIVI_IS_PLAYER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_PLAYER))
-#define VIVI_PLAYER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_PLAYER, ViviPlayer))
-#define VIVI_PLAYER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_PLAYER, ViviPlayerClass))
-#define VIVI_PLAYER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_PLAYER, ViviPlayerClass))
-
-struct _ViviPlayer {
-  ViviViviDocklet     	docklet;
-};
-
-struct _ViviPlayerClass
-{
-  ViviViviDockletClass  docklet_class;
-};
-
-GType			vivi_player_get_type   	(void);
-
-GtkWidget *		vivi_player_new		(ViviApplication *	app);
-
-
-G_END_DECLS
-#endif
diff --git a/vivified/ui/vivi_player.xml b/vivified/ui/vivi_player.xml
new file mode 100644
index 0000000..bb1c630
--- /dev/null
+++ b/vivified/ui/vivi_player.xml
@@ -0,0 +1,17 @@
+<interface>
+  <object class="ViviViviDocklet" id="player">
+    <property name="title">Player</property>
+    <signal name="application-set" handler="vivi_player_application_set" />
+    <signal name="application-unset" handler="vivi_player_application_unset" />
+    <child>
+      <object class="GtkAlignment" id="1">
+	<property name="xscale">0.0</property>
+	<property name="yscale">0.0</property>
+	<child>
+	  <object class="SwfdecGtkWidget" id="2">
+	  </object>
+	</child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/vivified/ui/vivi_vivi_docklet.c b/vivified/ui/vivi_vivi_docklet.c
index ddc9d23..9daba21 100644
--- a/vivified/ui/vivi_vivi_docklet.c
+++ b/vivified/ui/vivi_vivi_docklet.c
@@ -34,7 +34,7 @@ enum {
   LAST_SIGNAL
 };
 
-G_DEFINE_ABSTRACT_TYPE (ViviViviDocklet, vivi_vivi_docklet, VIVI_TYPE_DOCKLET)
+G_DEFINE_TYPE (ViviViviDocklet, vivi_vivi_docklet, VIVI_TYPE_DOCKLET)
 guint signals[LAST_SIGNAL];
 
 static void
diff-tree 7bbd6ebee1796e6d396d5b5dfdb99613124fe05a (from 0b05aebbce303392692d38bd8b6cde457f228a6e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 10:45:48 2007 +0200

    compute player widget dynamically

diff --git a/vivified/ui/vivi_player.c b/vivified/ui/vivi_player.c
index ecff252..4732d68 100644
--- a/vivified/ui/vivi_player.c
+++ b/vivified/ui/vivi_player.c
@@ -27,29 +27,47 @@
 G_DEFINE_TYPE (ViviPlayer, vivi_player, VIVI_TYPE_VIVI_DOCKLET)
 
 static void
-vivi_player_notify_app (ViviApplication *app, GParamSpec *pspec, ViviPlayer *player)
+find_player (GtkWidget *widget, gpointer result)
+{
+  if (SWFDEC_IS_GTK_WIDGET (widget)) {
+    *(gpointer *) result = widget;
+    return;
+  }
+
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget), find_player, result);
+}
+
+static void
+vivi_player_notify_app (ViviApplication *app, GParamSpec *pspec, SwfdecGtkWidget *player)
 {
   if (g_str_equal (pspec->name, "player")) {
-    swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
+    swfdec_gtk_widget_set_player (player, vivi_application_get_player (app));
   } else if (g_str_equal (pspec->name, "interrupted")) {
-    swfdec_gtk_widget_set_interactive (SWFDEC_GTK_WIDGET (player->player), 
-	!vivi_application_get_interrupted (app));
+    swfdec_gtk_widget_set_interactive (player, !vivi_application_get_interrupted (app));
   }
 }
 
 static void
 vivi_player_application_set (ViviViviDocklet *docklet, ViviApplication *app)
 {
-  ViviPlayer *player = VIVI_PLAYER (docklet);
+  SwfdecGtkPlayer *player = NULL;
+
+  find_player (GTK_WIDGET (docklet), &player);
 
   g_signal_connect (app, "notify", G_CALLBACK (vivi_player_notify_app), player);
-  swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
+  swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player), vivi_application_get_player (app));
+  swfdec_gtk_widget_set_interactive (SWFDEC_GTK_WIDGET (player), !vivi_application_get_interrupted (app));
 }
 
 static void
 vivi_player_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
 {
-  g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, docklet);
+  SwfdecGtkPlayer *player = NULL;
+
+  find_player (GTK_WIDGET (docklet), &player);
+
+  g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, player);
 }
 
 static void
@@ -64,13 +82,13 @@ vivi_player_class_init (ViviPlayerClass 
 static void
 vivi_player_init (ViviPlayer *player)
 {
-  GtkWidget *box;
+  GtkWidget *box, *widget;
 
   box = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
   gtk_container_add (GTK_CONTAINER (player), box);
   /* the player */
-  player->player = swfdec_gtk_widget_new (NULL);
-  gtk_container_add (GTK_CONTAINER (box), player->player);
+  widget = swfdec_gtk_widget_new (NULL);
+  gtk_container_add (GTK_CONTAINER (box), widget);
 
   gtk_widget_show_all (box);
 }
diff --git a/vivified/ui/vivi_player.h b/vivified/ui/vivi_player.h
index af3d9dc..c2aa1dd 100644
--- a/vivified/ui/vivi_player.h
+++ b/vivified/ui/vivi_player.h
@@ -39,8 +39,6 @@ typedef struct _ViviPlayerClass ViviPlay
 
 struct _ViviPlayer {
   ViviViviDocklet     	docklet;
-
-  GtkWidget *		player;		/* SwfdecGtkWidget */
 };
 
 struct _ViviPlayerClass
diff-tree 0b05aebbce303392692d38bd8b6cde457f228a6e (from bc5a502e867c9a508fc2cb3795000ccb1298dea0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 10:36:42 2007 +0200

    make application_(un)set signals

diff --git a/vivified/ui/vivi_player.c b/vivified/ui/vivi_player.c
index 0785023..ecff252 100644
--- a/vivified/ui/vivi_player.c
+++ b/vivified/ui/vivi_player.c
@@ -38,7 +38,7 @@ vivi_player_notify_app (ViviApplication 
 }
 
 static void
-vivi_player_set_app (ViviViviDocklet *docklet, ViviApplication *app)
+vivi_player_application_set (ViviViviDocklet *docklet, ViviApplication *app)
 {
   ViviPlayer *player = VIVI_PLAYER (docklet);
 
@@ -47,7 +47,7 @@ vivi_player_set_app (ViviViviDocklet *do
 }
 
 static void
-vivi_player_unset_app (ViviViviDocklet *docklet, ViviApplication *app)
+vivi_player_application_unset (ViviViviDocklet *docklet, ViviApplication *app)
 {
   g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, docklet);
 }
@@ -57,8 +57,8 @@ vivi_player_class_init (ViviPlayerClass 
 {
   ViviViviDockletClass *vivi_docklet_class = VIVI_VIVI_DOCKLET_CLASS (klass);
 
-  vivi_docklet_class->set_app = vivi_player_set_app;
-  vivi_docklet_class->unset_app = vivi_player_unset_app;
+  vivi_docklet_class->application_set = vivi_player_application_set;
+  vivi_docklet_class->application_unset = vivi_player_application_unset;
 }
 
 static void
diff --git a/vivified/ui/vivi_vivi_docklet.c b/vivified/ui/vivi_vivi_docklet.c
index 1670ea6..ddc9d23 100644
--- a/vivified/ui/vivi_vivi_docklet.c
+++ b/vivified/ui/vivi_vivi_docklet.c
@@ -28,7 +28,14 @@ enum {
   PROP_APP
 };
 
+enum {
+  APPLICATION_SET,
+  APPLICATION_UNSET,
+  LAST_SIGNAL
+};
+
 G_DEFINE_ABSTRACT_TYPE (ViviViviDocklet, vivi_vivi_docklet, VIVI_TYPE_DOCKLET)
+guint signals[LAST_SIGNAL];
 
 static void
 vivi_vivi_docklet_get_property (GObject *object, guint param_id, GValue *value, 
@@ -51,14 +58,17 @@ vivi_vivi_docklet_set_property (GObject 
     GParamSpec *pspec)
 {
   ViviViviDocklet *docklet = VIVI_VIVI_DOCKLET (object);
-  ViviViviDockletClass *klass;
 
   switch (param_id) {
     case PROP_APP:
+      if (docklet->app) {
+	g_signal_emit (docklet, signals[APPLICATION_UNSET], 0, docklet->app);
+	g_object_unref (docklet->app);
+      }
       docklet->app = g_value_dup_object (value);
-      klass = VIVI_VIVI_DOCKLET_GET_CLASS (docklet);
-      if (klass->set_app)
-	klass->set_app (docklet, docklet->app);
+      if (docklet->app) {
+	g_signal_emit (docklet, signals[APPLICATION_SET], 0, docklet->app);
+      }
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -70,12 +80,12 @@ static void
 vivi_vivi_docklet_dispose (GObject *object)
 {
   ViviViviDocklet *docklet = VIVI_VIVI_DOCKLET (object);
-  ViviViviDockletClass *klass;
 
-  klass = VIVI_VIVI_DOCKLET_GET_CLASS (docklet);
-  if (klass->unset_app)
-    klass->unset_app (docklet, docklet->app);
-  g_object_unref (docklet->app);
+  if (docklet->app) {
+    g_signal_emit (docklet, signals[APPLICATION_UNSET], 0, docklet->app);
+    g_object_unref (docklet->app);
+    docklet->app = NULL;
+  }
 
   G_OBJECT_CLASS (vivi_vivi_docklet_parent_class)->dispose (object);
 }
@@ -91,7 +101,16 @@ vivi_vivi_docklet_class_init (ViviViviDo
 
   g_object_class_install_property (object_class, PROP_APP,
       g_param_spec_object ("application", "application", "application used by this docklet",
-	  VIVI_TYPE_APPLICATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	  VIVI_TYPE_APPLICATION, G_PARAM_READWRITE));
+
+  signals[APPLICATION_SET] = g_signal_new ("application-set", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ViviViviDockletClass, application_set), 
+      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE, 1, VIVI_TYPE_APPLICATION);
+  signals[APPLICATION_UNSET] = g_signal_new ("application-unset", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ViviViviDockletClass, application_unset), 
+      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE, 1, VIVI_TYPE_APPLICATION);
 }
 
 static void
diff --git a/vivified/ui/vivi_vivi_docklet.h b/vivified/ui/vivi_vivi_docklet.h
index 66b1b14..108b531 100644
--- a/vivified/ui/vivi_vivi_docklet.h
+++ b/vivified/ui/vivi_vivi_docklet.h
@@ -46,9 +46,9 @@ struct _ViviViviDockletClass
 {
   ViviDockletClass    	docklet_class;
 
-  void			(* set_app)			(ViviViviDocklet *	docklet,
+  void			(* application_set)   		(ViviViviDocklet *	docklet,
 							 ViviApplication *	app);
-  void			(* unset_app)			(ViviViviDocklet *	docklet,
+  void			(* application_unset)	      	(ViviViviDocklet *	docklet,
 							 ViviApplication *	app);
 };
 
diff-tree bc5a502e867c9a508fc2cb3795000ccb1298dea0 (from d0b370d01cd37dcaac383206aade7d886cf8f423)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 10:05:45 2007 +0200

    add a ViviViviDocklet class that tracks the application and provides easy vfuncs
    
    This is used to have easy access to the Application setting and getting
    Also port ViviPlayer to it

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 3413b4c..d6dad12 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -10,10 +10,12 @@ vivified_SOURCES = \
 	vivi_commandline.c \
 	vivi_movie_list.c \
 	vivi_player.c \
+	vivi_vivi_docklet.c \
 	main.c
 
 noinst_HEADERS = \
 	vivi_commandline.h \
 	vivi_movie_list.h \
-	vivi_player.h
+	vivi_player.h \
+	vivi_vivi_docklet.h
 
diff --git a/vivified/ui/vivi_player.c b/vivified/ui/vivi_player.c
index f54a935..0785023 100644
--- a/vivified/ui/vivi_player.c
+++ b/vivified/ui/vivi_player.c
@@ -24,7 +24,7 @@
 #include "vivi_player.h"
 #include <libswfdec-gtk/swfdec-gtk.h>
 
-G_DEFINE_TYPE (ViviPlayer, vivi_player, VIVI_TYPE_DOCKLET)
+G_DEFINE_TYPE (ViviPlayer, vivi_player, VIVI_TYPE_VIVI_DOCKLET)
 
 static void
 vivi_player_notify_app (ViviApplication *app, GParamSpec *pspec, ViviPlayer *player)
@@ -38,21 +38,27 @@ vivi_player_notify_app (ViviApplication 
 }
 
 static void
-vivi_player_dispose (GObject *object)
+vivi_player_set_app (ViviViviDocklet *docklet, ViviApplication *app)
 {
-  ViviPlayer *player = VIVI_PLAYER (object);
+  ViviPlayer *player = VIVI_PLAYER (docklet);
 
-  g_signal_handlers_disconnect_by_func (player->app, vivi_player_notify_app, player);
+  g_signal_connect (app, "notify", G_CALLBACK (vivi_player_notify_app), player);
+  swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
+}
 
-  G_OBJECT_CLASS (vivi_player_parent_class)->dispose (object);
+static void
+vivi_player_unset_app (ViviViviDocklet *docklet, ViviApplication *app)
+{
+  g_signal_handlers_disconnect_by_func (app, vivi_player_notify_app, docklet);
 }
 
 static void
 vivi_player_class_init (ViviPlayerClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviViviDockletClass *vivi_docklet_class = VIVI_VIVI_DOCKLET_CLASS (klass);
 
-  object_class->dispose = vivi_player_dispose;
+  vivi_docklet_class->set_app = vivi_player_set_app;
+  vivi_docklet_class->unset_app = vivi_player_unset_app;
 }
 
 static void
@@ -72,12 +78,6 @@ vivi_player_init (ViviPlayer *player)
 GtkWidget *
 vivi_player_new (ViviApplication *app)
 {
-  ViviPlayer *player;
-
-  player = g_object_new (VIVI_TYPE_PLAYER, "title", "Player", NULL);
-  player->app = app;
-  g_signal_connect (player->app, "notify", G_CALLBACK (vivi_player_notify_app), player);
-  swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
-  return GTK_WIDGET (player);
+  return g_object_new (VIVI_TYPE_PLAYER, "title", "Player", "application", app, NULL);
 }
 
diff --git a/vivified/ui/vivi_player.h b/vivified/ui/vivi_player.h
index 9aa9102..af3d9dc 100644
--- a/vivified/ui/vivi_player.h
+++ b/vivified/ui/vivi_player.h
@@ -22,6 +22,7 @@
 
 #include <vivified/core/vivified-core.h>
 #include <vivified/dock/vivified-dock.h>
+#include <vivified/ui/vivi_vivi_docklet.h>
 
 G_BEGIN_DECLS
 
@@ -37,15 +38,14 @@ typedef struct _ViviPlayerClass ViviPlay
 #define VIVI_PLAYER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_PLAYER, ViviPlayerClass))
 
 struct _ViviPlayer {
-  ViviDocklet		docklet;
+  ViviViviDocklet     	docklet;
 
-  ViviApplication *	app;		/* the application we connect to */
   GtkWidget *		player;		/* SwfdecGtkWidget */
 };
 
 struct _ViviPlayerClass
 {
-  ViviDockletClass    	docklet_class;
+  ViviViviDockletClass  docklet_class;
 };
 
 GType			vivi_player_get_type   	(void);
diff --git a/vivified/ui/vivi_vivi_docklet.c b/vivified/ui/vivi_vivi_docklet.c
new file mode 100644
index 0000000..1670ea6
--- /dev/null
+++ b/vivified/ui/vivi_vivi_docklet.c
@@ -0,0 +1,101 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_vivi_docklet.h"
+
+enum {
+  PROP_0,
+  PROP_APP
+};
+
+G_DEFINE_ABSTRACT_TYPE (ViviViviDocklet, vivi_vivi_docklet, VIVI_TYPE_DOCKLET)
+
+static void
+vivi_vivi_docklet_get_property (GObject *object, guint param_id, GValue *value, 
+    GParamSpec * pspec)
+{
+  ViviViviDocklet *docklet = VIVI_VIVI_DOCKLET (object);
+  
+  switch (param_id) {
+    case PROP_APP:
+      g_value_set_object (value, docklet->app);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_vivi_docklet_set_property (GObject *object, guint param_id, const GValue *value,
+    GParamSpec *pspec)
+{
+  ViviViviDocklet *docklet = VIVI_VIVI_DOCKLET (object);
+  ViviViviDockletClass *klass;
+
+  switch (param_id) {
+    case PROP_APP:
+      docklet->app = g_value_dup_object (value);
+      klass = VIVI_VIVI_DOCKLET_GET_CLASS (docklet);
+      if (klass->set_app)
+	klass->set_app (docklet, docklet->app);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_vivi_docklet_dispose (GObject *object)
+{
+  ViviViviDocklet *docklet = VIVI_VIVI_DOCKLET (object);
+  ViviViviDockletClass *klass;
+
+  klass = VIVI_VIVI_DOCKLET_GET_CLASS (docklet);
+  if (klass->unset_app)
+    klass->unset_app (docklet, docklet->app);
+  g_object_unref (docklet->app);
+
+  G_OBJECT_CLASS (vivi_vivi_docklet_parent_class)->dispose (object);
+}
+
+static void
+vivi_vivi_docklet_class_init (ViviViviDockletClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_vivi_docklet_dispose;
+  object_class->get_property = vivi_vivi_docklet_get_property;
+  object_class->set_property = vivi_vivi_docklet_set_property;
+
+  g_object_class_install_property (object_class, PROP_APP,
+      g_param_spec_object ("application", "application", "application used by this docklet",
+	  VIVI_TYPE_APPLICATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+vivi_vivi_docklet_init (ViviViviDocklet *vivi_docklet)
+{
+}
+
diff --git a/vivified/ui/vivi_vivi_docklet.h b/vivified/ui/vivi_vivi_docklet.h
new file mode 100644
index 0000000..66b1b14
--- /dev/null
+++ b/vivified/ui/vivi_vivi_docklet.h
@@ -0,0 +1,59 @@
+/* Vivified
+ * 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 _VIVI_VIVI_DOCKLET_H_
+#define _VIVI_VIVI_DOCKLET_H_
+
+#include <vivified/core/vivified-core.h>
+#include <vivified/dock/vivified-dock.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviViviDocklet ViviViviDocklet;
+typedef struct _ViviViviDockletClass ViviViviDockletClass;
+
+#define VIVI_TYPE_VIVI_DOCKLET                    (vivi_vivi_docklet_get_type())
+#define VIVI_IS_VIVI_DOCKLET(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_VIVI_DOCKLET))
+#define VIVI_IS_VIVI_DOCKLET_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_VIVI_DOCKLET))
+#define VIVI_VIVI_DOCKLET(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_VIVI_DOCKLET, ViviViviDocklet))
+#define VIVI_VIVI_DOCKLET_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_VIVI_DOCKLET, ViviViviDockletClass))
+#define VIVI_VIVI_DOCKLET_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_VIVI_DOCKLET, ViviViviDockletClass))
+
+struct _ViviViviDocklet {
+  ViviDocklet		docklet;
+
+  ViviApplication *	app;			/* the application we connect to */
+};
+
+struct _ViviViviDockletClass
+{
+  ViviDockletClass    	docklet_class;
+
+  void			(* set_app)			(ViviViviDocklet *	docklet,
+							 ViviApplication *	app);
+  void			(* unset_app)			(ViviViviDocklet *	docklet,
+							 ViviApplication *	app);
+};
+
+GType			vivi_vivi_docklet_get_type   	(void);
+
+
+G_END_DECLS
+#endif
diff-tree d0b370d01cd37dcaac383206aade7d886cf8f423 (from 7adaaba7e86f29eb42b555bd61d46fb428cfe9d7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 10:04:33 2007 +0200

    make this work with a ViviApplication

diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
index 7178a32..7a4ddef 100644
--- a/vivified/ui/vivi_movie_list.c
+++ b/vivified/ui/vivi_movie_list.c
@@ -22,7 +22,6 @@
 #endif
 
 #include <gtk/gtk.h>
-#include <libswfdec/swfdec.h>
 #include <libswfdec/swfdec_movie.h>
 #include <libswfdec/swfdec_player_internal.h>
 #include "vivi_movie_list.h"
@@ -273,14 +272,18 @@ vivi_movie_list_get_index (GNode *parent
   return i;
 }
 
-static void
-vivi_movie_list_added (SwfdecPlayer *player, SwfdecMovie *movie, ViviMovieList *movies)
+static gboolean
+vivi_movie_list_added (ViviDebugger *debugger, SwfdecAsObject *object, ViviMovieList *movies)
 {
+  SwfdecMovie *movie;
   GtkTreePath *path;
   GtkTreeIter iter;
   GNode *node, *new;
   int pos;
 
+  if (!SWFDEC_IS_MOVIE (object))
+    return FALSE;
+  movie = SWFDEC_MOVIE (object);
   if (movie->parent) {
     node = g_hash_table_lookup (movies->nodes, movie->parent);
     g_assert (node);
@@ -297,6 +300,7 @@ vivi_movie_list_added (SwfdecPlayer *pla
   path = vivi_movie_list_node_to_path (new);
   gtk_tree_model_row_inserted (GTK_TREE_MODEL (movies), path, &iter);
   gtk_tree_path_free (path);
+  return FALSE;
 }
 
 static void
@@ -318,30 +322,35 @@ vivi_movie_list_movie_notify (SwfdecMovi
   gtk_tree_path_free (path);
 }
 
-static void
-vivi_movie_list_removed (SwfdecPlayer *player, SwfdecMovie *movie, ViviMovieList *movies)
+static gboolean
+vivi_movie_list_removed (ViviDebugger *debugger, SwfdecAsObject *object, ViviMovieList *movies)
 {
   GNode *node;
   GtkTreePath *path;
 
-  node = g_hash_table_lookup (movies->nodes, movie);
-  g_hash_table_remove (movies->nodes, movie);
-  g_signal_handlers_disconnect_by_func (movie, vivi_movie_list_movie_notify, movies);
+  if (!SWFDEC_IS_MOVIE (object))
+    return FALSE;
+  node = g_hash_table_lookup (movies->nodes, object);
+  g_hash_table_remove (movies->nodes, object);
+  g_signal_handlers_disconnect_by_func (object, vivi_movie_list_movie_notify, movies);
   path = vivi_movie_list_node_to_path (node);
   g_assert (g_node_n_children (node) == 0);
   g_node_destroy (node);
   gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);
   gtk_tree_path_free (path);
+  return FALSE;
 }
 
 static void
 vivi_movie_list_dispose (GObject *object)
 {
   ViviMovieList *movies = VIVI_MOVIE_LIST (object);
+  ViviDebugger *debugger;
 
-  g_signal_handlers_disconnect_by_func (movies->player, vivi_movie_list_removed, movies);
-  g_signal_handlers_disconnect_by_func (movies->player, vivi_movie_list_added, movies);
-  g_object_unref (movies->player);
+  debugger = movies->app->debugger;
+  g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_removed, movies);
+  g_signal_handlers_disconnect_by_func (debugger, vivi_movie_list_added, movies);
+  g_object_unref (movies->app);
   g_assert (g_node_n_children (movies->root) == 0);
   g_node_destroy (movies->root);
   g_hash_table_destroy (movies->nodes);
@@ -365,15 +374,17 @@ vivi_movie_list_init (ViviMovieList *mov
 }
 
 ViviMovieList *
-vivi_movie_list_new (SwfdecPlayer *player)
+vivi_movie_list_new (ViviApplication *app)
 {
   ViviMovieList *movies;
+  ViviDebugger *debugger;
 
   movies = g_object_new (VIVI_TYPE_MOVIE_LIST, NULL);
-  movies->player = player;
-  g_object_ref (player);
-  g_signal_connect (player, "movie-added", G_CALLBACK (vivi_movie_list_added), movies);
-  g_signal_connect (player, "movie-removed", G_CALLBACK (vivi_movie_list_removed), movies);
+  g_object_ref (app);
+  movies->app = app;
+  debugger = app->debugger;
+  g_signal_connect (debugger, "add", G_CALLBACK (vivi_movie_list_added), movies);
+  g_signal_connect (debugger, "remove", G_CALLBACK (vivi_movie_list_removed), movies);
   return movies;
 }
 
diff --git a/vivified/ui/vivi_movie_list.h b/vivified/ui/vivi_movie_list.h
index eaa7eb6..ddd4a81 100644
--- a/vivified/ui/vivi_movie_list.h
+++ b/vivified/ui/vivi_movie_list.h
@@ -17,7 +17,7 @@
  * Boston, MA  02110-1301  USA
  */
 
-#include <libswfdec/swfdec.h>
+#include <vivified/core/vivified-core.h>
 
 #ifndef _VIVI_MOVIE_LIST_H_
 #define _VIVI_MOVIE_LIST_H_
@@ -46,7 +46,7 @@ struct _ViviMovieList
 {
   GObject		object;
 
-  SwfdecPlayer *	player;		/* the video we play */
+  ViviApplication *	app;		/* the application we watch */
   GNode *		root;		/* the root node containing all the movies */
   int			stamp;		/* to validate tree iters */
   GHashTable *		nodes;		/* movies => node fast lookup table */
@@ -59,7 +59,7 @@ struct _ViviMovieListClass
 
 GType		vivi_movie_list_get_type		(void);
 
-ViviMovieList *	vivi_movie_list_new			(SwfdecPlayer *		player);
+ViviMovieList *	vivi_movie_list_new			(ViviApplication *	app);
 
 
 G_END_DECLS
diff-tree 7adaaba7e86f29eb42b555bd61d46fb428cfe9d7 (from 04f4684b200ee8e3c102282b56040881d279a39c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 10:03:59 2007 +0200

    implement add and remove vfuncs

diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index a5ae2eb..68a7b89 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -28,6 +28,8 @@
 #include "libswfdec/swfdec_player_internal.h"
 
 enum {
+  ADD,
+  REMOVE,
   STEP,
   START_FRAME,
   FINISH_FRAME,
@@ -87,6 +89,30 @@ vivi_debugger_break (ViviDebugger *debug
 }
 
 static void
+vivi_debugger_add (SwfdecAsDebugger *debugger, SwfdecAsContext *context, 
+    SwfdecAsObject *object)
+{
+  gboolean retval = FALSE;
+
+  g_signal_emit (debugger, signals[ADD], 0, object, &retval);
+
+  if (retval)
+    vivi_debugger_break (VIVI_DEBUGGER (debugger));
+}
+
+static void
+vivi_debugger_remove (SwfdecAsDebugger *debugger, SwfdecAsContext *context, 
+    SwfdecAsObject *object)
+{
+  gboolean retval = FALSE;
+
+  g_signal_emit (debugger, signals[REMOVE], 0, object, &retval);
+
+  if (retval)
+    vivi_debugger_break (VIVI_DEBUGGER (debugger));
+}
+
+static void
 vivi_debugger_step (SwfdecAsDebugger *debugger, SwfdecAsContext *context)
 {
   gboolean retval = FALSE;
@@ -149,6 +175,12 @@ vivi_debugger_class_init (ViviDebuggerCl
 
   object_class->dispose = vivi_debugger_dispose;
 
+  signals[ADD] = g_signal_new ("add", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT,
+      G_TYPE_BOOLEAN, 1, SWFDEC_TYPE_AS_OBJECT);
+  signals[REMOVE] = g_signal_new ("remove", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT,
+      G_TYPE_BOOLEAN, 1, SWFDEC_TYPE_AS_OBJECT);
   signals[STEP] = g_signal_new ("step", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__VOID,
       G_TYPE_BOOLEAN, 0);
@@ -162,6 +194,8 @@ vivi_debugger_class_init (ViviDebuggerCl
       G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT_STRING_POINTER,
       G_TYPE_BOOLEAN, 3, SWFDEC_TYPE_AS_OBJECT, G_TYPE_STRING, G_TYPE_POINTER);
 
+  debugger_class->add = vivi_debugger_add;
+  debugger_class->remove = vivi_debugger_remove;
   debugger_class->step = vivi_debugger_step;
   debugger_class->start_frame = vivi_debugger_start_frame;
   debugger_class->finish_frame = vivi_debugger_finish_frame;
diff-tree 04f4684b200ee8e3c102282b56040881d279a39c (from 10153690d1eafad2f3bdbedda1e00d2d6b1b16dc)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 21 10:03:29 2007 +0200

    emit remove debugger function before collecting the object
    
    Otherwise we end up with a freed object (nice!)

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index a135585..59df631 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -261,12 +261,12 @@ swfdec_as_context_remove_objects (gpoint
     return FALSE;
   } else {
     SWFDEC_LOG ("deleted: %s %p", G_OBJECT_TYPE_NAME (object), object);
-    swfdec_as_object_collect (object);
     if (debugger) {
       SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (debugger);
       if (klass->remove)
 	klass->remove (debugger, object->context, object);
     }
+    swfdec_as_object_collect (object);
     return TRUE;
   }
 }
diff-tree 10153690d1eafad2f3bdbedda1e00d2d6b1b16dc (from a5468cc9ac5545c607021cc89a6f541df3d6c56e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 21:49:21 2007 +0200

    ad functionality to get notified about object add/remove to GC

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 0cb0226..a135585 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -248,7 +248,7 @@ swfdec_as_context_remove_strings (gpoint
 }
 
 static gboolean
-swfdec_as_context_remove_objects (gpointer key, gpointer value, gpointer data)
+swfdec_as_context_remove_objects (gpointer key, gpointer value, gpointer debugger)
 {
   SwfdecAsObject *object;
 
@@ -262,6 +262,11 @@ swfdec_as_context_remove_objects (gpoint
   } else {
     SWFDEC_LOG ("deleted: %s %p", G_OBJECT_TYPE_NAME (object), object);
     swfdec_as_object_collect (object);
+    if (debugger) {
+      SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (debugger);
+      if (klass->remove)
+	klass->remove (debugger, object->context, object);
+    }
     return TRUE;
   }
 }
@@ -274,7 +279,7 @@ swfdec_as_context_collect (SwfdecAsConte
   g_hash_table_foreach_remove (context->strings, 
     swfdec_as_context_remove_strings, context);
   g_hash_table_foreach_remove (context->objects, 
-    swfdec_as_context_remove_objects, context);
+    swfdec_as_context_remove_objects, context->debugger);
   SWFDEC_INFO (">> done collecting garbage");
 }
 
diff --git a/libswfdec/swfdec_as_debugger.h b/libswfdec/swfdec_as_debugger.h
index 4a0f952..61aaae6 100644
--- a/libswfdec/swfdec_as_debugger.h
+++ b/libswfdec/swfdec_as_debugger.h
@@ -43,6 +43,14 @@ struct _SwfdecAsDebugger {
 struct _SwfdecAsDebuggerClass {
   GObjectClass		object_class;
 
+  /* a new object was added to the GC */
+  void			(* add)		(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context,
+					 SwfdecAsObject *	object);
+  /* an object was removed from the GC */
+  void			(* remove)    	(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context,
+					 SwfdecAsObject *	object);
   /* called before executing a bytecode */
   void			(* step)	(SwfdecAsDebugger *	debugger,
 					 SwfdecAsContext *	context);
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index d041803..bd2cf90 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -528,6 +528,11 @@ swfdec_as_object_add (SwfdecAsObject *ob
   klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
   g_return_if_fail (klass->add);
   klass->add (object);
+  if (context->debugger) {
+    SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger);
+    if (dklass->add)
+      dklass->add (context->debugger, context, object);
+  }
 }
 
 void
diff-tree a5468cc9ac5545c607021cc89a6f541df3d6c56e (from 307c09bbe7611bf2b1dae7e59a98d32cf009f595)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 21:36:19 2007 +0200

    remove last remains of SwfdecDebugger
    
    note: I didn't remove the source  files yet, they might be useful for reference
    while implementing Vivified

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 198b805..1e5e8a5 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -60,7 +60,6 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_color.c \
 	swfdec_color_as.c \
 	swfdec_debug.c \
-	swfdec_debugger.c \
 	swfdec_decoder.c \
 	swfdec_edittext.c \
 	swfdec_edittext_movie.c \
@@ -179,7 +178,6 @@ noinst_HEADERS = \
 	swfdec_color.h \
 	swfdec_color_as.h \
 	swfdec_debug.h \
-	swfdec_debugger.h \
 	swfdec_decoder.h \
 	swfdec_edittext.h \
 	swfdec_edittext_movie.h \
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 221e25c..90f3e2a 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -26,7 +26,6 @@
 #include "swfdec_as_context.h"
 #include "swfdec_as_interpret.h"
 #include "swfdec_debug.h"
-#include "swfdec_debugger.h"
 
 /* Define this to get SWFDEC_WARN'd about missing properties of objects.
  * This can be useful to find out about unimplemented native properties,
diff --git a/libswfdec/swfdec_types.h b/libswfdec/swfdec_types.h
index 907ac87..b66ecd9 100644
--- a/libswfdec/swfdec_types.h
+++ b/libswfdec/swfdec_types.h
@@ -37,7 +37,6 @@ typedef struct _SwfdecCacheHandle Swfdec
 typedef struct _SwfdecCharacter SwfdecCharacter;
 typedef struct _SwfdecColorTransform SwfdecColorTransform;
 typedef struct _SwfdecContent SwfdecContent;
-typedef struct _SwfdecDebugger SwfdecDebugger;
 typedef struct _SwfdecDecoder SwfdecDecoder;
 typedef struct _SwfdecEventList SwfdecEventList;
 typedef struct _SwfdecFont SwfdecFont;
diff-tree 307c09bbe7611bf2b1dae7e59a98d32cf009f595 (from e04f9526fa8a613d88219ebcb47ac61addd5bcab)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 21:34:07 2007 +0200

    get rid of debugger bits

diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 243dabc..420c508 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -32,7 +32,6 @@
 #include "swfdec_as_strings.h"
 #include "swfdec_button_movie.h"
 #include "swfdec_debug.h"
-#include "swfdec_debugger.h"
 #include "swfdec_event.h"
 #include "swfdec_graphic.h"
 #include "swfdec_loader_internal.h"
@@ -315,16 +314,8 @@ swfdec_movie_destroy (SwfdecMovie *movie
     swfdec_movie_destroy (movie->list->data);
   }
   if (movie->parent) {
-    if (SWFDEC_IS_DEBUGGER (player) &&
-	g_list_find (movie->parent->list, movie)) {
-      g_signal_emit_by_name (player, "movie-removed", movie);
-    }
     movie->parent->list = g_list_remove (movie->parent->list, movie);
   } else {
-    if (SWFDEC_IS_DEBUGGER (player) &&
-	g_list_find (player->roots, movie)) {
-      g_signal_emit_by_name (player, "movie-removed", movie);
-    }
     player->roots = g_list_remove (player->roots, movie);
   }
   /* FIXME: figure out how to handle destruction pre-init/construct.
@@ -1000,7 +991,6 @@ swfdec_movie_new (SwfdecPlayer *player, 
     size = 0;
   }
   g_object_ref (movie);
-  swfdec_as_object_add (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_CONTEXT (player), size);
   /* set essential properties */
   movie->parent = parent;
   if (parent) {
@@ -1030,9 +1020,8 @@ swfdec_movie_new (SwfdecPlayer *player, 
    * new movies to be created (and added to this list)
    */
   player->movies = g_list_prepend (player->movies, movie);
-  /* emit the new-movie signal */
-  if (SWFDEC_IS_DEBUGGER (player))
-    g_signal_emit_by_name (player, "movie-added", movie);
+  /* only add the movie here, because it needs to be setup for the debugger */
+  swfdec_as_object_add (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_CONTEXT (player), size);
   return movie;
 }
 
diff-tree e04f9526fa8a613d88219ebcb47ac61addd5bcab (from parents)
Merge: 2f123ef946932f1b5e684b90fd27a056c0ea98f6 da9fc3e76d3757cb3a8a4459802c753adbbbcbe7
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 18:17:37 2007 +0200

    Merge branch 'master' into vivi
    
    Conflicts:
    
    	libswfdec/swfdec_as_context.c
    	libswfdec/swfdec_as_interpret.c
    	test/trace/trace.c
    
    Also updated API in vivified code to changed APIs from master

diff --cc libswfdec/swfdec_as_context.c
index b2a74cb,4975822..0cb0226
@@@ -419,7 -419,7 +419,8 @@@
  
  enum {
    PROP_0,
 +  PROP_DEBUGGER,
+   PROP_UNTIL_GC
  };
  
  G_DEFINE_TYPE (SwfdecAsContext, swfdec_as_context, G_TYPE_OBJECT)
@@@ -430,11 -430,11 +431,15 @@@
      GParamSpec * pspec)
  {
    SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
 +
+   
    switch (param_id) {
 +    case PROP_DEBUGGER:
 +      g_value_set_object (value, context->debugger);
 +      break;
+     case PROP_UNTIL_GC:
+       g_value_set_ulong (value, (gulong) context->memory_until_gc);
+       break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        break;
@@@ -446,11 -446,11 +451,15 @@@
      GParamSpec * pspec)
  {
    SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
 +
+   
    switch (param_id) {
 +    case PROP_DEBUGGER:
 +      context->debugger = g_value_dup_object (value);
 +      break;
+     case PROP_UNTIL_GC:
+       context->memory_until_gc = g_value_get_ulong (value);
+       break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        break;
@@@ -489,9 -485,10 +498,13 @@@
    object_class->get_property = swfdec_as_context_get_property;
    object_class->set_property = swfdec_as_context_set_property;
  
 +  g_object_class_install_property (object_class, PROP_DEBUGGER,
 +      g_param_spec_object ("debugger", "debugger", "debugger used in this player",
 +	  SWFDEC_TYPE_AS_DEBUGGER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+   g_object_class_install_property (object_class, PROP_UNTIL_GC,
+       g_param_spec_ulong ("memory-until-gc", "memory until gc", 
+ 	  "amount of bytes that need to be allocated before garbage collection triggers",
+ 	  0, G_MAXULONG, 8 * 1024 * 1024, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
  
    /**
     * SwfdecAsContext::trace:
diff --cc libswfdec/swfdec_as_interpret.c
index 461c875,4a712c2..d08b00a
@@@ -1541,7 -1554,8 +1542,8 @@@
    }
    if (name == NULL)
      name = "unnamed_function";
 -  script = swfdec_script_new (&bits, name, cx->version);
 +  script = swfdec_script_new_from_bits (&bits, name, cx->version);
+   swfdec_buffer_unref (buffer);
    if (script == NULL) {
      SWFDEC_ERROR ("failed to create script");
      g_free (args);
diff --cc libswfdec/swfdec_as_object.c
index 111dbb3,83ad4cf..d041803
@@@ -562,14 -577,8 +577,14 @@@
    g_return_if_fail (variable != NULL);
    g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
  
 +  if (object->context->debugger) {
 +    SwfdecAsDebugger *debugger = object->context->debugger;
 +    SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_GET_CLASS (debugger);
 +    if (dklass->set_variable)
 +      dklass->set_variable (debugger, object->context, object, variable, value);
 +  }
    klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
-   klass->set (object, variable, value);
+   klass->set (object, variable, value, default_flags);
  }
  
  /**
diff --cc test/trace/trace.c
index cc788db,af52ef6..55f1754
@@@ -100,7 -100,8 +100,8 @@@
      goto fail;
    }
    string = g_string_new ("");
 -  player = swfdec_player_new ();
 +  player = swfdec_player_new (NULL);
+   g_object_set (player, "memory-until-gc", (gulong) 0, NULL);
    g_signal_connect (player, "trace", G_CALLBACK (trace_cb), string);
    g_signal_connect (player, "fscommand", G_CALLBACK (fscommand_cb), &quit);
    swfdec_player_set_loader (player, loader);
diff --cc vivified/core/vivi_breakpoint.c
index 15cfc26,0000000..11ae4bf
mode 100644,000000..100644
@@@ -1,236 -1,0 +1,241 @@@
 +/* Vivified
 + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
 + * Boston, MA  02110-1301  USA
 + */
 +
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#include "vivi_breakpoint.h"
 +#include "vivi_application.h"
 +#include "vivi_function.h"
 +#include "vivi_wrap.h"
 +
 +G_DEFINE_TYPE (ViviBreakpoint, vivi_breakpoint, SWFDEC_TYPE_AS_OBJECT)
 +
 +static gboolean
 +vivi_breakpoint_step (ViviDebugger *debugger, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue retval;
 +
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onCommand"), 0, NULL, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static gboolean
 +vivi_breakpoint_start_frame (ViviDebugger *debugger, SwfdecAsFrame *frame, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue val;
 +  SwfdecAsValue retval;
 +
 +  SWFDEC_AS_VALUE_SET_OBJECT (&val, vivi_wrap_object (VIVI_APPLICATION (obj->context), SWFDEC_AS_OBJECT (frame)));
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStartFrame"), 1, &val, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static gboolean
 +vivi_breakpoint_finish_frame (ViviDebugger *debugger, SwfdecAsFrame *frame, const SwfdecAsValue *ret, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue vals[2];
 +  SwfdecAsValue retval;
 +
 +  SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], vivi_wrap_object (VIVI_APPLICATION (obj->context), SWFDEC_AS_OBJECT (frame)));
 +  vivi_wrap_value (VIVI_APPLICATION (obj->context), &vals[1], ret);
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStartFrame"), 2, vals, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static gboolean
 +vivi_breakpoint_set_variable (ViviDebugger *debugger, SwfdecAsObject *object, 
 +    const char *variable, const SwfdecAsValue *value, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue vals[3];
 +  SwfdecAsValue retval;
 +
 +  SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], vivi_wrap_object (VIVI_APPLICATION (obj->context), object));
 +  SWFDEC_AS_VALUE_SET_STRING (&vals[1], swfdec_as_context_get_string (obj->context, variable));
 +  vivi_wrap_value (VIVI_APPLICATION (obj->context), &vals[2], value);
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onSetVariable"), 3, vals, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static const struct {
 +  const char *	event;
 +  const char *	signal;
 +  GCallback	handler;
 +} events[] = {
 +  { NULL, NULL, NULL }, /* invalid */
 +  { "onCommand", "step", G_CALLBACK (vivi_breakpoint_step) },
 +  { "onStartFrame", "start-frame", G_CALLBACK (vivi_breakpoint_start_frame) },
 +  { "onExitFrame", "finish-frame", G_CALLBACK (vivi_breakpoint_finish_frame) },
 +  { "onSetVariable", "set-variable", G_CALLBACK (vivi_breakpoint_set_variable) }
 +};
 +
 +static guint
 +vivi_breakpoint_find_event (const char *name)
 +{
 +  guint i;
 +
 +  for (i = 1; i < G_N_ELEMENTS (events); i++) {
 +    if (g_str_equal (events[i].event, name))
 +      return i;
 +  }
 +  return 0;
 +}
 +
 +static void
 +vivi_breakpoint_add (ViviBreakpoint *breakpoint, guint i)
 +{
 +  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
 +
 +  g_assert (i != 0);
 +  if (breakpoint->active) {
 +    breakpoint->handlers[i] = g_signal_connect (debugger, events[i].signal,
 +	events[i].handler, breakpoint);
 +  } else {
 +    breakpoint->handlers[i] = 1;
 +  }
 +}
 +
 +static void
 +vivi_breakpoint_remove (ViviBreakpoint *breakpoint, guint i)
 +{
 +  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
 +
 +  g_assert (i != 0);
 +  if (breakpoint->active)
 +    g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
 +  breakpoint->handlers[i] = 0;
 +}
 +
 +static void
- vivi_breakpoint_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val)
++vivi_breakpoint_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val, guint flags)
 +{
 +  guint i;
 +
 +  i = vivi_breakpoint_find_event (variable);
 +  if (i) {
 +    ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
 +    if (SWFDEC_AS_VALUE_IS_OBJECT (val) &&
 +	SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (val))) {
 +      if (!breakpoint->handlers[i])
 +	vivi_breakpoint_add (breakpoint, i);
 +    } else {
 +      if (breakpoint->handlers[i])
 +	vivi_breakpoint_remove (breakpoint, i);
 +    }
 +  }
-   SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val);
++  SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val, flags);
 +}
 +
- static gboolean
++static SwfdecAsDeleteReturn
 +vivi_breakpoint_delete (SwfdecAsObject *object, const char *variable)
 +{
 +  ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
 +  guint i;
++  SwfdecAsDeleteReturn ret;
 +
-   i = vivi_breakpoint_find_event (variable);
-   if (i && breakpoint->handlers[i])
-     vivi_breakpoint_remove (breakpoint, i);
++  ret = SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
++
++  if (ret == SWFDEC_AS_DELETE_DELETED) {
++    i = vivi_breakpoint_find_event (variable);
++    if (i && breakpoint->handlers[i])
++      vivi_breakpoint_remove (breakpoint, i);
++  }
 +
-   return SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
++  return ret;
 +}
 +
 +static void
 +vivi_breakpoint_dispose (GObject *object)
 +{
 +  ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
 +
 +  vivi_breakpoint_set_active (breakpoint, FALSE);
 +
 +  G_OBJECT_CLASS (vivi_breakpoint_parent_class)->dispose (object);
 +}
 +
 +static void
 +vivi_breakpoint_class_init (ViviBreakpointClass *klass)
 +{
 +  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 +  SwfdecAsObjectClass *as_object_class = SWFDEC_AS_OBJECT_CLASS (klass);
 +
 +  object_class->dispose = vivi_breakpoint_dispose;
 +
 +  as_object_class->set = vivi_breakpoint_set;
 +  as_object_class->del = vivi_breakpoint_delete;
 +}
 +
 +static void
 +vivi_breakpoint_init (ViviBreakpoint *breakpoint)
 +{
 +  breakpoint->active = TRUE;
 +}
 +
 +void
 +vivi_breakpoint_set_active (ViviBreakpoint *breakpoint, gboolean active)
 +{
 +  guint i;
 +
 +  g_return_if_fail (VIVI_IS_BREAKPOINT (breakpoint));
 +
 +  g_print ("active = %d", active);
 +  if (breakpoint->active == active)
 +    return;
 +  breakpoint->active = !breakpoint->active;
 +  for (i = 1; i < G_N_ELEMENTS (events); i++) {
 +    if (breakpoint->handlers[i] == 0)
 +      continue;
 +    /* FIXME: this is hacky */
 +    breakpoint->active = !breakpoint->active;
 +    vivi_breakpoint_remove (breakpoint, i);
 +    breakpoint->active = !breakpoint->active;
 +    vivi_breakpoint_add (breakpoint, i);
 +  }
 +}
 +
 +/*** AS CODE ***/
 +
 +VIVI_FUNCTION ("breakpoint_active_get", vivi_breakpoint_as_get_active)
 +void
 +vivi_breakpoint_as_get_active (SwfdecAsContext *cx, SwfdecAsObject *this,
 +    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 +{
 +  if (!VIVI_IS_BREAKPOINT (this))
 +    return;
 +
 +  SWFDEC_AS_VALUE_SET_BOOLEAN (retval, VIVI_BREAKPOINT (this)->active);
 +}
 +
 +VIVI_FUNCTION ("breakpoint_active_set", vivi_breakpoint_as_set_active)
 +void
 +vivi_breakpoint_as_set_active (SwfdecAsContext *cx, SwfdecAsObject *this,
 +    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 +{
 +  if (!VIVI_IS_BREAKPOINT (this) ||
 +      argc == 0)
 +    return;
 +  vivi_breakpoint_set_active (VIVI_BREAKPOINT (this), swfdec_as_value_to_boolean (cx, &argv[0]));
 +}
 +
diff --cc vivified/core/vivi_wrap.c
index 66eb3a4,0000000..4be1e76
mode 100644,000000..100644
@@@ -1,113 -1,0 +1,113 @@@
 +/* Vivified
 + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + * 
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + * 
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
 + * Boston, MA  02110-1301  USA
 + */
 +
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
 +#include "vivi_wrap.h"
 +#include "vivi_application.h"
 +
 +G_DEFINE_TYPE (ViviWrap, vivi_wrap, SWFDEC_TYPE_AS_OBJECT)
 +
 +static void
 +vivi_wrap_dispose (GObject *object)
 +{
 +  ViviWrap *wrap = VIVI_WRAP (object);
 +
 +  if (wrap->wrap) {
 +    g_hash_table_remove (VIVI_APPLICATION (SWFDEC_AS_OBJECT (wrap)->context)->wraps, wrap->wrap);
 +    wrap->wrap = NULL;
 +  }
 +
 +  G_OBJECT_CLASS (vivi_wrap_parent_class)->dispose (object);
 +}
 +
 +static void
 +vivi_wrap_class_init (ViviWrapClass *klass)
 +{
 +  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 +
 +  object_class->dispose = vivi_wrap_dispose;
 +}
 +
 +static void
 +vivi_wrap_init (ViviWrap *wrap)
 +{
 +}
 +
 +SwfdecAsObject *
 +vivi_wrap_object (ViviApplication *app, SwfdecAsObject *object)
 +{
 +  const char *name;
 +  SwfdecAsContext *cx;
 +  SwfdecAsObject *wrap;
 +  SwfdecAsValue val;
 +  
 +  wrap = g_hash_table_lookup (app->wraps, object);
 +  if (wrap)
 +    return wrap;
 +
 +  cx = SWFDEC_AS_CONTEXT (app);
 +  if (!swfdec_as_context_use_mem (cx, sizeof (ViviWrap)))
 +    return NULL;
 +  wrap = g_object_new (VIVI_TYPE_WRAP, NULL);
 +  swfdec_as_object_add (wrap, cx, sizeof (ViviWrap));
 +  /* frames are special */
 +  if (SWFDEC_IS_AS_FRAME (object))
 +    name = "Frame";
 +  else
 +    name = "Wrap";
 +  swfdec_as_object_get_variable (cx->global, swfdec_as_context_get_string (cx, name), &val);
 +  if (SWFDEC_AS_VALUE_IS_OBJECT (&val))
-     swfdec_as_object_set_constructor (wrap, SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
++    swfdec_as_object_set_constructor (wrap, SWFDEC_AS_VALUE_GET_OBJECT (&val));
 +  VIVI_WRAP (wrap)->wrap = object;
 +  g_hash_table_insert (app->wraps, object, wrap);
 +  return wrap;
 +}
 +
 +void
 +vivi_wrap_value (ViviApplication *app, SwfdecAsValue *dest, const SwfdecAsValue *src)
 +{
 +  g_return_if_fail (VIVI_IS_APPLICATION (app));
 +  g_return_if_fail (dest != NULL);
 +  g_return_if_fail (SWFDEC_IS_AS_VALUE (src));
 +
 +  switch (src->type) {
 +    case SWFDEC_AS_TYPE_UNDEFINED:
 +    case SWFDEC_AS_TYPE_BOOLEAN:
 +    case SWFDEC_AS_TYPE_NUMBER:
 +    case SWFDEC_AS_TYPE_NULL:
 +      *dest = *src;
 +      break;
 +    case SWFDEC_AS_TYPE_STRING:
 +      SWFDEC_AS_VALUE_SET_STRING (dest,
 +	  swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (app),
 +	    SWFDEC_AS_VALUE_GET_STRING (src)));
 +      break;
 +    case SWFDEC_AS_TYPE_OBJECT:
 +      SWFDEC_AS_VALUE_SET_OBJECT (dest,
 +	  vivi_wrap_object (app, SWFDEC_AS_VALUE_GET_OBJECT (src)));
 +      break;
 +    default:
 +      g_assert_not_reached ();
 +      break;
 +  }
 +}
 +
diff-tree 2f123ef946932f1b5e684b90fd27a056c0ea98f6 (from 3cd1dcc154eab81a8ff46e0ae56a24b1487fe802)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 22:57:40 2007 +0200

    disable build of swfdebug

diff --git a/player/Makefile.am b/player/Makefile.am
index ce3d1fe..53e52c1 100644
--- a/player/Makefile.am
+++ b/player/Makefile.am
@@ -1,31 +1,20 @@
-noinst_PROGRAMS = swfplay swfdebug
+noinst_PROGRAMS = swfplay 
 
 swfplay_SOURCES = \
 	swfdec_slow_loader.c \
 	swfplay.c 
 
-swfdebug_SOURCES = \
-	swfdebug.c \
-	swfdec_debug_movies.c \
-	swfdec_debug_script.c \
-	swfdec_debug_scripts.c \
-	swfdec_debug_stack.c \
-	swfdec_player_manager.c \
-	swfdec_debug_widget.c
+#swfdebug_SOURCES = \
+#	swfdebug.c \
+#	swfdec_debug_script.c \
+#	swfdec_debug_scripts.c \
+#	swfdec_debug_stack.c \
+#	swfdec_player_manager.c \
+#	swfdec_debug_widget.c
 
 noinst_HEADERS = \
-	swfdec_debug_movies.h \
-	swfdec_debug_script.h \
-	swfdec_debug_scripts.h \
-	swfdec_debug_stack.h \
-	swfdec_debug_widget.h \
-	swfdec_player_manager.h \
 	swfdec_slow_loader.h
 
 swfplay_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS)
 swfplay_LDFLAGS = $(SWFDEC_GTK_LIBS) $(GTK_LIBS)
 
-swfdebug_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS) $(SWFDEC_GTK_CFLAGS)
-swfdebug_LDFLAGS = $(SWFDEC_GTK_LIBS) $(GTK_LIBS)
-
-
diff-tree 3cd1dcc154eab81a8ff46e0ae56a24b1487fe802 (from 7c412eac2ef2b94b8419b0002ec5f253f47ba038)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 22:56:17 2007 +0200

    port SwfdecDebugMovies to vivified (doesn't work yet)

diff --git a/player/swfdec_debug_movies.c b/player/swfdec_debug_movies.c
deleted file mode 100644
index 331b4c9..0000000
--- a/player/swfdec_debug_movies.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/* 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, to_string 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 <gtk/gtk.h>
-#include <libswfdec/swfdec_debugger.h>
-#include <libswfdec/swfdec_movie.h>
-#include <libswfdec/swfdec_player_internal.h>
-#include "swfdec_debug_movies.h"
-
-/*** GTK_TREE_MODEL ***/
-
-#if 0
-#  define REPORT g_print ("%s\n", G_STRFUNC)
-#else
-#  define REPORT 
-#endif
-static GtkTreeModelFlags 
-swfdec_debug_movies_get_flags (GtkTreeModel *tree_model)
-{
-  REPORT;
-  return 0;
-}
-
-static gint
-swfdec_debug_movies_get_n_columns (GtkTreeModel *tree_model)
-{
-  REPORT;
-  return SWFDEC_DEBUG_MOVIES_N_COLUMNS;
-}
-
-static GType
-swfdec_debug_movies_get_column_type (GtkTreeModel *tree_model, gint index_)
-{
-  REPORT;
-  switch (index_) {
-    case SWFDEC_DEBUG_MOVIES_COLUMN_MOVIE:
-      return G_TYPE_POINTER;
-    case SWFDEC_DEBUG_MOVIES_COLUMN_NAME:
-      return G_TYPE_STRING;
-    case SWFDEC_DEBUG_MOVIES_COLUMN_DEPTH:
-      return G_TYPE_INT;
-    case SWFDEC_DEBUG_MOVIES_COLUMN_TYPE:
-      return G_TYPE_STRING;
-    default:
-      break;
-  }
-  g_assert_not_reached ();
-  return G_TYPE_NONE;
-}
-
-static gboolean
-swfdec_debug_movies_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
-{
-  SwfdecDebugMovies *movies = SWFDEC_DEBUG_MOVIES (tree_model);
-  GNode *node;
-  guint i, depth;
-  int *indices;
-
-  REPORT;
-  depth = gtk_tree_path_get_depth (path);
-  indices = gtk_tree_path_get_indices (path);
-  if (indices == NULL)
-    return FALSE;
-  node = movies->root;
-  for (i = 0; i < depth; i++) {
-    node = g_node_nth_child (node, indices[i]);
-    if (node == NULL)
-      return FALSE;
-  }
-  iter->user_data = node;
-  iter->stamp = movies->stamp;
-  return TRUE;
-}
-
-static GtkTreePath *
-swfdec_debug_movies_node_to_path (GNode *node)
-{
-  GtkTreePath *path;
-
-  path = gtk_tree_path_new ();
-  while (node->parent != NULL) {
-    gtk_tree_path_prepend_index (path, g_node_child_position (node->parent, node));
-    node = node->parent;
-  }
-  return path;
-}
-
-static GtkTreePath *
-swfdec_debug_movies_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
-  REPORT;
-  return swfdec_debug_movies_node_to_path (iter->user_data);
-}
-
-static void 
-swfdec_debug_movies_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter,
-    gint column, GValue *value)
-{
-  SwfdecMovie *movie = ((GNode *) iter->user_data)->data;
-
-  REPORT;
-  switch (column) {
-    case SWFDEC_DEBUG_MOVIES_COLUMN_MOVIE:
-      g_value_init (value, G_TYPE_POINTER);
-      g_value_set_pointer (value, movie);
-      return;
-    case SWFDEC_DEBUG_MOVIES_COLUMN_NAME:
-      g_value_init (value, G_TYPE_STRING);
-      if (movie->name[0])
-	g_value_set_string (value, movie->name);
-      else
-	g_value_set_string (value, movie->original_name);
-      return;
-    case SWFDEC_DEBUG_MOVIES_COLUMN_DEPTH:
-      g_value_init (value, G_TYPE_INT);
-      g_value_set_int (value, movie->depth);
-      return;
-    case SWFDEC_DEBUG_MOVIES_COLUMN_TYPE:
-      g_value_init (value, G_TYPE_STRING);
-      /* big hack: we skip the "Swfdec" here */
-      g_value_set_string (value, G_OBJECT_TYPE_NAME (movie) + 6);
-      return;
-    default:
-      break;
-  }
-  g_assert_not_reached ();
-}
-
-static gboolean
-swfdec_debug_movies_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
-  GNode *node;
-
-  REPORT;
-  node = iter->user_data;
-  node = node->next;
-  if (node == NULL)
-    return FALSE;
-  iter->user_data = node;
-  return TRUE;
-}
-
-static gboolean
-swfdec_debug_movies_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
-{
-  GNode *node;
-
-  REPORT;
-  if (parent) {
-    node = parent->user_data;
-  } else {
-    node = SWFDEC_DEBUG_MOVIES (tree_model)->root;
-  }
-  if (node->children == NULL)
-    return FALSE;
-  iter->user_data = node->children;
-  return TRUE;
-}
-
-static gboolean
-swfdec_debug_movies_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
-  GtkTreeIter unused;
-
-  REPORT;
-  return swfdec_debug_movies_iter_children (tree_model, &unused, iter);
-}
-
-static gint
-swfdec_debug_movies_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
-{
-  GNode *node;
-
-  REPORT;
-  if (iter) {
-    node = iter->user_data;
-  } else {
-    node = SWFDEC_DEBUG_MOVIES (tree_model)->root;
-  }
-  return g_node_n_children (node);
-}
-
-static gboolean
-swfdec_debug_movies_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter,
-    GtkTreeIter *parent, gint n)
-{
-  GNode *node;
-
-  REPORT;
-  if (parent) {
-    node = parent->user_data;
-  } else {
-    node = SWFDEC_DEBUG_MOVIES (tree_model)->root;
-  }
-  node = g_node_nth_child (node, n);
-  if (node == NULL)
-    return FALSE;
-  iter->user_data = node;
-  return TRUE;
-}
-
-static gboolean
-swfdec_debug_movies_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
-{
-  GNode *node;
-
-  REPORT;
-  node = child->user_data;
-  node = node->parent;
-  if (node->parent == NULL)
-    return FALSE;
-  iter->user_data = node;
-  return TRUE;
-}
-
-static void
-swfdec_debug_movies_tree_model_init (GtkTreeModelIface *iface)
-{
-  iface->get_flags = swfdec_debug_movies_get_flags;
-  iface->get_n_columns = swfdec_debug_movies_get_n_columns;
-  iface->get_column_type = swfdec_debug_movies_get_column_type;
-  iface->get_iter = swfdec_debug_movies_get_iter;
-  iface->get_path = swfdec_debug_movies_get_path;
-  iface->get_value = swfdec_debug_movies_get_value;
-  iface->iter_next = swfdec_debug_movies_iter_next;
-  iface->iter_children = swfdec_debug_movies_iter_children;
-  iface->iter_has_child = swfdec_debug_movies_iter_has_child;
-  iface->iter_n_children = swfdec_debug_movies_iter_n_children;
-  iface->iter_nth_child = swfdec_debug_movies_iter_nth_child;
-  iface->iter_parent = swfdec_debug_movies_iter_parent;
-}
-
-/*** SWFDEC_DEBUG_MOVIES ***/
-
-G_DEFINE_TYPE_WITH_CODE (SwfdecDebugMovies, swfdec_debug_movies, G_TYPE_OBJECT,
-    G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, swfdec_debug_movies_tree_model_init))
-
-static int
-swfdec_debug_movies_get_index (GNode *parent, GNode *new)
-{
-  GNode *walk;
-  int i = 0;
-
-  for (walk = parent->children; walk; walk = walk->next) {
-    if (walk == new)
-      continue;
-    if (swfdec_movie_compare_depths (walk->data, new->data) < 0) {
-      i++;
-      continue;
-    }
-    break;
-  }
-  return i;
-}
-
-static void
-swfdec_debug_movies_added (SwfdecPlayer *player, SwfdecMovie *movie, SwfdecDebugMovies *movies)
-{
-  GtkTreePath *path;
-  GtkTreeIter iter;
-  GNode *node, *new;
-  int pos;
-
-  if (movie->parent) {
-    node = g_hash_table_lookup (movies->nodes, movie->parent);
-    g_assert (node);
-  } else {
-    node = movies->root;
-  }
-  new = g_node_new (movie);
-  g_hash_table_insert (movies->nodes, movie, new);
-  pos = swfdec_debug_movies_get_index (node, new);
-  g_node_insert (node, pos, new);
-  movies->stamp++;
-  iter.stamp = movies->stamp;
-  iter.user_data = new;
-  path = swfdec_debug_movies_node_to_path (new);
-  gtk_tree_model_row_inserted (GTK_TREE_MODEL (movies), path, &iter);
-  gtk_tree_path_free (path);
-}
-
-static void
-swfdec_debug_movies_movie_notify (SwfdecMovie *movie, GParamSpec *pspec, SwfdecDebugMovies *movies)
-{
-  GtkTreeIter iter;
-  GtkTreePath *path;
-  GNode *node;
-
-  node = g_hash_table_lookup (movies->nodes, movie);
-  if (g_str_equal (pspec->name, "depth")) {
-    /* reorder when depth changes */
-    g_printerr ("FIXME: implement depth changes\n");
-  }
-  iter.stamp = movies->stamp;
-  iter.user_data = node;
-  path = swfdec_debug_movies_node_to_path (node);
-  gtk_tree_model_row_changed (GTK_TREE_MODEL (movies), path, &iter);
-  gtk_tree_path_free (path);
-}
-
-static void
-swfdec_debug_movies_removed (SwfdecPlayer *player, SwfdecMovie *movie, SwfdecDebugMovies *movies)
-{
-  GNode *node;
-  GtkTreePath *path;
-
-  node = g_hash_table_lookup (movies->nodes, movie);
-  g_hash_table_remove (movies->nodes, movie);
-  g_signal_handlers_disconnect_by_func (movie, swfdec_debug_movies_movie_notify, movies);
-  path = swfdec_debug_movies_node_to_path (node);
-  g_assert (g_node_n_children (node) == 0);
-  g_node_destroy (node);
-  gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);
-  gtk_tree_path_free (path);
-}
-
-static void
-swfdec_debug_movies_dispose (GObject *object)
-{
-  SwfdecDebugMovies *movies = SWFDEC_DEBUG_MOVIES (object);
-
-  g_signal_handlers_disconnect_by_func (movies->player, swfdec_debug_movies_removed, movies);
-  g_signal_handlers_disconnect_by_func (movies->player, swfdec_debug_movies_added, movies);
-  g_object_unref (movies->player);
-  g_assert (g_node_n_children (movies->root) == 0);
-  g_node_destroy (movies->root);
-  g_hash_table_destroy (movies->nodes);
-
-  G_OBJECT_CLASS (swfdec_debug_movies_parent_class)->dispose (object);
-}
-
-static void
-swfdec_debug_movies_class_init (SwfdecDebugMoviesClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-
-  object_class->dispose = swfdec_debug_movies_dispose;
-}
-
-static void
-swfdec_debug_movies_init (SwfdecDebugMovies *movies)
-{
-  movies->root = g_node_new (NULL);
-  movies->nodes = g_hash_table_new (g_direct_hash, g_direct_equal);
-}
-
-SwfdecDebugMovies *
-swfdec_debug_movies_new (SwfdecPlayer *player)
-{
-  SwfdecDebugMovies *movies;
-
-  movies = g_object_new (SWFDEC_TYPE_DEBUG_MOVIES, NULL);
-  movies->player = player;
-  g_object_ref (player);
-  if (SWFDEC_IS_DEBUGGER (player)) {
-    g_signal_connect (player, "movie-added", G_CALLBACK (swfdec_debug_movies_added), movies);
-    g_signal_connect (player, "movie-removed", G_CALLBACK (swfdec_debug_movies_removed), movies);
-  }
-  return movies;
-}
-
diff --git a/player/swfdec_debug_movies.h b/player/swfdec_debug_movies.h
deleted file mode 100644
index 35e92da..0000000
--- a/player/swfdec_debug_movies.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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_DEBUG_MOVIES_H_
-#define _SWFDEC_DEBUG_MOVIES_H_
-
-#include <libswfdec/swfdec.h>
-
-G_BEGIN_DECLS
-
-enum {
-  SWFDEC_DEBUG_MOVIES_COLUMN_MOVIE,
-  SWFDEC_DEBUG_MOVIES_COLUMN_NAME,
-  SWFDEC_DEBUG_MOVIES_COLUMN_DEPTH,
-  SWFDEC_DEBUG_MOVIES_COLUMN_TYPE,
-  /* add more */
-  SWFDEC_DEBUG_MOVIES_N_COLUMNS
-};
-
-typedef struct _SwfdecDebugMovies SwfdecDebugMovies;
-typedef struct _SwfdecDebugMoviesClass SwfdecDebugMoviesClass;
-
-#define SWFDEC_TYPE_DEBUG_MOVIES                    (swfdec_debug_movies_get_type())
-#define SWFDEC_IS_DEBUG_MOVIES(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_DEBUG_MOVIES))
-#define SWFDEC_IS_DEBUG_MOVIES_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_DEBUG_MOVIES))
-#define SWFDEC_DEBUG_MOVIES(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_DEBUG_MOVIES, SwfdecDebugMovies))
-#define SWFDEC_DEBUG_MOVIES_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_DEBUG_MOVIES, SwfdecDebugMoviesClass))
-
-struct _SwfdecDebugMovies
-{
-  GObject		object;
-
-  SwfdecPlayer *	player;		/* the video we play */
-  GNode *		root;		/* the root node containing all the movies */
-  int			stamp;		/* to validate tree iters */
-  GHashTable *		nodes;		/* movies => node fast lookup table */
-};
-
-struct _SwfdecDebugMoviesClass
-{
-  GObjectClass		object_class;
-};
-
-GType		swfdec_debug_movies_get_type		(void);
-
-SwfdecDebugMovies *
-		swfdec_debug_movies_new			(SwfdecPlayer *		player);
-
-
-G_END_DECLS
-#endif
diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 2a8ed4a..3413b4c 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -8,10 +8,12 @@ vivified_LDADD = \
 
 vivified_SOURCES = \
 	vivi_commandline.c \
+	vivi_movie_list.c \
 	vivi_player.c \
 	main.c
 
 noinst_HEADERS = \
 	vivi_commandline.h \
+	vivi_movie_list.h \
 	vivi_player.h
 
diff --git a/vivified/ui/vivi_movie_list.c b/vivified/ui/vivi_movie_list.c
new file mode 100644
index 0000000..7178a32
--- /dev/null
+++ b/vivified/ui/vivi_movie_list.c
@@ -0,0 +1,379 @@
+/* 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, to_string 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 <gtk/gtk.h>
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_movie.h>
+#include <libswfdec/swfdec_player_internal.h>
+#include "vivi_movie_list.h"
+
+/*** GTK_TREE_MODEL ***/
+
+#if 0
+#  define REPORT g_print ("%s\n", G_STRFUNC)
+#else
+#  define REPORT 
+#endif
+static GtkTreeModelFlags 
+vivi_movie_list_get_flags (GtkTreeModel *tree_model)
+{
+  REPORT;
+  return 0;
+}
+
+static gint
+vivi_movie_list_get_n_columns (GtkTreeModel *tree_model)
+{
+  REPORT;
+  return VIVI_MOVIE_LIST_N_COLUMNS;
+}
+
+static GType
+vivi_movie_list_get_column_type (GtkTreeModel *tree_model, gint index_)
+{
+  REPORT;
+  switch (index_) {
+    case VIVI_MOVIE_LIST_COLUMN_MOVIE:
+      return G_TYPE_POINTER;
+    case VIVI_MOVIE_LIST_COLUMN_NAME:
+      return G_TYPE_STRING;
+    case VIVI_MOVIE_LIST_COLUMN_DEPTH:
+      return G_TYPE_INT;
+    case VIVI_MOVIE_LIST_COLUMN_TYPE:
+      return G_TYPE_STRING;
+    default:
+      break;
+  }
+  g_assert_not_reached ();
+  return G_TYPE_NONE;
+}
+
+static gboolean
+vivi_movie_list_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
+{
+  ViviMovieList *movies = VIVI_MOVIE_LIST (tree_model);
+  GNode *node;
+  guint i, depth;
+  int *indices;
+
+  REPORT;
+  depth = gtk_tree_path_get_depth (path);
+  indices = gtk_tree_path_get_indices (path);
+  if (indices == NULL)
+    return FALSE;
+  node = movies->root;
+  for (i = 0; i < depth; i++) {
+    node = g_node_nth_child (node, indices[i]);
+    if (node == NULL)
+      return FALSE;
+  }
+  iter->user_data = node;
+  iter->stamp = movies->stamp;
+  return TRUE;
+}
+
+static GtkTreePath *
+vivi_movie_list_node_to_path (GNode *node)
+{
+  GtkTreePath *path;
+
+  path = gtk_tree_path_new ();
+  while (node->parent != NULL) {
+    gtk_tree_path_prepend_index (path, g_node_child_position (node->parent, node));
+    node = node->parent;
+  }
+  return path;
+}
+
+static GtkTreePath *
+vivi_movie_list_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  REPORT;
+  return vivi_movie_list_node_to_path (iter->user_data);
+}
+
+static void 
+vivi_movie_list_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter,
+    gint column, GValue *value)
+{
+  SwfdecMovie *movie = ((GNode *) iter->user_data)->data;
+
+  REPORT;
+  switch (column) {
+    case VIVI_MOVIE_LIST_COLUMN_MOVIE:
+      g_value_init (value, G_TYPE_POINTER);
+      g_value_set_pointer (value, movie);
+      return;
+    case VIVI_MOVIE_LIST_COLUMN_NAME:
+      g_value_init (value, G_TYPE_STRING);
+      if (movie->name[0])
+	g_value_set_string (value, movie->name);
+      else
+	g_value_set_string (value, movie->original_name);
+      return;
+    case VIVI_MOVIE_LIST_COLUMN_DEPTH:
+      g_value_init (value, G_TYPE_INT);
+      g_value_set_int (value, movie->depth);
+      return;
+    case VIVI_MOVIE_LIST_COLUMN_TYPE:
+      g_value_init (value, G_TYPE_STRING);
+      /* big hack: we skip the "Swfdec" here */
+      g_value_set_string (value, G_OBJECT_TYPE_NAME (movie) + 6);
+      return;
+    default:
+      break;
+  }
+  g_assert_not_reached ();
+}
+
+static gboolean
+vivi_movie_list_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  GNode *node;
+
+  REPORT;
+  node = iter->user_data;
+  node = node->next;
+  if (node == NULL)
+    return FALSE;
+  iter->user_data = node;
+  return TRUE;
+}
+
+static gboolean
+vivi_movie_list_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
+{
+  GNode *node;
+
+  REPORT;
+  if (parent) {
+    node = parent->user_data;
+  } else {
+    node = VIVI_MOVIE_LIST (tree_model)->root;
+  }
+  if (node->children == NULL)
+    return FALSE;
+  iter->user_data = node->children;
+  return TRUE;
+}
+
+static gboolean
+vivi_movie_list_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  GtkTreeIter unused;
+
+  REPORT;
+  return vivi_movie_list_iter_children (tree_model, &unused, iter);
+}
+
+static gint
+vivi_movie_list_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+  GNode *node;
+
+  REPORT;
+  if (iter) {
+    node = iter->user_data;
+  } else {
+    node = VIVI_MOVIE_LIST (tree_model)->root;
+  }
+  return g_node_n_children (node);
+}
+
+static gboolean
+vivi_movie_list_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter,
+    GtkTreeIter *parent, gint n)
+{
+  GNode *node;
+
+  REPORT;
+  if (parent) {
+    node = parent->user_data;
+  } else {
+    node = VIVI_MOVIE_LIST (tree_model)->root;
+  }
+  node = g_node_nth_child (node, n);
+  if (node == NULL)
+    return FALSE;
+  iter->user_data = node;
+  return TRUE;
+}
+
+static gboolean
+vivi_movie_list_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
+{
+  GNode *node;
+
+  REPORT;
+  node = child->user_data;
+  node = node->parent;
+  if (node->parent == NULL)
+    return FALSE;
+  iter->user_data = node;
+  return TRUE;
+}
+
+static void
+vivi_movie_list_tree_model_init (GtkTreeModelIface *iface)
+{
+  iface->get_flags = vivi_movie_list_get_flags;
+  iface->get_n_columns = vivi_movie_list_get_n_columns;
+  iface->get_column_type = vivi_movie_list_get_column_type;
+  iface->get_iter = vivi_movie_list_get_iter;
+  iface->get_path = vivi_movie_list_get_path;
+  iface->get_value = vivi_movie_list_get_value;
+  iface->iter_next = vivi_movie_list_iter_next;
+  iface->iter_children = vivi_movie_list_iter_children;
+  iface->iter_has_child = vivi_movie_list_iter_has_child;
+  iface->iter_n_children = vivi_movie_list_iter_n_children;
+  iface->iter_nth_child = vivi_movie_list_iter_nth_child;
+  iface->iter_parent = vivi_movie_list_iter_parent;
+}
+
+/*** VIVI_MOVIE_LIST ***/
+
+G_DEFINE_TYPE_WITH_CODE (ViviMovieList, vivi_movie_list, G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, vivi_movie_list_tree_model_init))
+
+static int
+vivi_movie_list_get_index (GNode *parent, GNode *new)
+{
+  GNode *walk;
+  int i = 0;
+
+  for (walk = parent->children; walk; walk = walk->next) {
+    if (walk == new)
+      continue;
+    if (swfdec_movie_compare_depths (walk->data, new->data) < 0) {
+      i++;
+      continue;
+    }
+    break;
+  }
+  return i;
+}
+
+static void
+vivi_movie_list_added (SwfdecPlayer *player, SwfdecMovie *movie, ViviMovieList *movies)
+{
+  GtkTreePath *path;
+  GtkTreeIter iter;
+  GNode *node, *new;
+  int pos;
+
+  if (movie->parent) {
+    node = g_hash_table_lookup (movies->nodes, movie->parent);
+    g_assert (node);
+  } else {
+    node = movies->root;
+  }
+  new = g_node_new (movie);
+  g_hash_table_insert (movies->nodes, movie, new);
+  pos = vivi_movie_list_get_index (node, new);
+  g_node_insert (node, pos, new);
+  movies->stamp++;
+  iter.stamp = movies->stamp;
+  iter.user_data = new;
+  path = vivi_movie_list_node_to_path (new);
+  gtk_tree_model_row_inserted (GTK_TREE_MODEL (movies), path, &iter);
+  gtk_tree_path_free (path);
+}
+
+static void
+vivi_movie_list_movie_notify (SwfdecMovie *movie, GParamSpec *pspec, ViviMovieList *movies)
+{
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  GNode *node;
+
+  node = g_hash_table_lookup (movies->nodes, movie);
+  if (g_str_equal (pspec->name, "depth")) {
+    /* reorder when depth changes */
+    g_printerr ("FIXME: implement depth changes\n");
+  }
+  iter.stamp = movies->stamp;
+  iter.user_data = node;
+  path = vivi_movie_list_node_to_path (node);
+  gtk_tree_model_row_changed (GTK_TREE_MODEL (movies), path, &iter);
+  gtk_tree_path_free (path);
+}
+
+static void
+vivi_movie_list_removed (SwfdecPlayer *player, SwfdecMovie *movie, ViviMovieList *movies)
+{
+  GNode *node;
+  GtkTreePath *path;
+
+  node = g_hash_table_lookup (movies->nodes, movie);
+  g_hash_table_remove (movies->nodes, movie);
+  g_signal_handlers_disconnect_by_func (movie, vivi_movie_list_movie_notify, movies);
+  path = vivi_movie_list_node_to_path (node);
+  g_assert (g_node_n_children (node) == 0);
+  g_node_destroy (node);
+  gtk_tree_model_row_deleted (GTK_TREE_MODEL (movies), path);
+  gtk_tree_path_free (path);
+}
+
+static void
+vivi_movie_list_dispose (GObject *object)
+{
+  ViviMovieList *movies = VIVI_MOVIE_LIST (object);
+
+  g_signal_handlers_disconnect_by_func (movies->player, vivi_movie_list_removed, movies);
+  g_signal_handlers_disconnect_by_func (movies->player, vivi_movie_list_added, movies);
+  g_object_unref (movies->player);
+  g_assert (g_node_n_children (movies->root) == 0);
+  g_node_destroy (movies->root);
+  g_hash_table_destroy (movies->nodes);
+
+  G_OBJECT_CLASS (vivi_movie_list_parent_class)->dispose (object);
+}
+
+static void
+vivi_movie_list_class_init (ViviMovieListClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->dispose = vivi_movie_list_dispose;
+}
+
+static void
+vivi_movie_list_init (ViviMovieList *movies)
+{
+  movies->root = g_node_new (NULL);
+  movies->nodes = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+ViviMovieList *
+vivi_movie_list_new (SwfdecPlayer *player)
+{
+  ViviMovieList *movies;
+
+  movies = g_object_new (VIVI_TYPE_MOVIE_LIST, NULL);
+  movies->player = player;
+  g_object_ref (player);
+  g_signal_connect (player, "movie-added", G_CALLBACK (vivi_movie_list_added), movies);
+  g_signal_connect (player, "movie-removed", G_CALLBACK (vivi_movie_list_removed), movies);
+  return movies;
+}
+
diff --git a/vivified/ui/vivi_movie_list.h b/vivified/ui/vivi_movie_list.h
new file mode 100644
index 0000000..eaa7eb6
--- /dev/null
+++ b/vivified/ui/vivi_movie_list.h
@@ -0,0 +1,66 @@
+/* Vivi
+ * 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
+ */
+
+#include <libswfdec/swfdec.h>
+
+#ifndef _VIVI_MOVIE_LIST_H_
+#define _VIVI_MOVIE_LIST_H_
+
+G_BEGIN_DECLS
+
+enum {
+  VIVI_MOVIE_LIST_COLUMN_MOVIE,
+  VIVI_MOVIE_LIST_COLUMN_NAME,
+  VIVI_MOVIE_LIST_COLUMN_DEPTH,
+  VIVI_MOVIE_LIST_COLUMN_TYPE,
+  /* add more */
+  VIVI_MOVIE_LIST_N_COLUMNS
+};
+
+typedef struct _ViviMovieList ViviMovieList;
+typedef struct _ViviMovieListClass ViviMovieListClass;
+
+#define VIVI_TYPE_MOVIE_LIST                    (vivi_movie_list_get_type())
+#define VIVI_IS_MOVIE_LIST(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_MOVIE_LIST))
+#define VIVI_IS_MOVIE_LIST_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_MOVIE_LIST))
+#define VIVI_MOVIE_LIST(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_MOVIE_LIST, ViviMovieList))
+#define VIVI_MOVIE_LIST_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_MOVIE_LIST, ViviMovieListClass))
+
+struct _ViviMovieList
+{
+  GObject		object;
+
+  SwfdecPlayer *	player;		/* the video we play */
+  GNode *		root;		/* the root node containing all the movies */
+  int			stamp;		/* to validate tree iters */
+  GHashTable *		nodes;		/* movies => node fast lookup table */
+};
+
+struct _ViviMovieListClass
+{
+  GObjectClass		object_class;
+};
+
+GType		vivi_movie_list_get_type		(void);
+
+ViviMovieList *	vivi_movie_list_new			(SwfdecPlayer *		player);
+
+
+G_END_DECLS
+#endif
diff-tree 7c412eac2ef2b94b8419b0002ec5f253f47ba038 (from 85702bb6de0af42a70cd4dccda70c5f4d6cd33fc)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 21:24:45 2007 +0200

    add toString () for breakpoints

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 93c1ecf..964f5b3 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -37,6 +37,9 @@ Breakpoint = function () extends Native.
 };
 Breakpoint.list = new Array ();
 Breakpoint.prototype.addProperty ("active", Native.breakpoint_active_get, Native.breakpoint_active_set);
+Breakpoint.prototype.toString = function () {
+  return "user-defined breakpoint";
+};
 
 /*** information about the player ***/
 
diff-tree 85702bb6de0af42a70cd4dccda70c5f4d6cd33fc (from 91daf3604631f9c33d289a176e9e3ec5adf4732a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 19:51:23 2007 +0200

    implement watch command

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 65f51d1..93c1ecf 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -115,3 +115,38 @@ Commands.where = function () {
 };
 Commands.backtrace = Commands.where;
 Commands.bt = Commands.where;
+Commands.watch = function () {
+  var object;
+  var name;
+  if (arguments.length == 1) {
+    name = arguments[0];
+  } else if (arguments.length == 2) {
+    object = arguments[0];
+    name = arguments[1];
+  } else {
+    Commands.error ("usage: watch [object] name");
+    return;
+  }
+  var ret = new Breakpoint ();
+  ret.onSetVariable = function (o, variable, value) {
+    if (object && o != object)
+      return false;
+    if (variable != name)
+      return;
+
+    if (object) {
+      Commands.print ("Breakpoint: variable " + name + " on " + object);
+    } else {
+      Commands.print ("Breakpoint: variable " + name);
+    }
+    Commands.print ("  " + Player.frame);
+    return true;
+  };
+  ret.toString = function () {
+    var s = "watch " + name;
+    if (object)
+      s += " on " + object;
+    return s;
+  };
+  return ret;
+};
diff-tree 91daf3604631f9c33d289a176e9e3ec5adf4732a (from 571b80372d3a7c4e2970a408f482c926f48f588a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 19:41:41 2007 +0200

    we have a handler more now...

diff --git a/vivified/core/vivi_breakpoint.h b/vivified/core/vivi_breakpoint.h
index 87b2220..35a8d28 100644
--- a/vivified/core/vivi_breakpoint.h
+++ b/vivified/core/vivi_breakpoint.h
@@ -41,7 +41,7 @@ struct _ViviBreakpoint
   SwfdecAsObject	object;
 
   gboolean		active;		/* only active breakpoints receive events */
-  gulong		handlers[4];	/* handlers for every signal of the debugger or 0 */
+  gulong		handlers[5];	/* handlers for every signal of the debugger or 0 */
 };
 
 struct _ViviBreakpointClass
diff-tree 571b80372d3a7c4e2970a408f482c926f48f588a (from 3589dfbffcdca650ce957c86ccbe0ce96078a24c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 19:22:52 2007 +0200

    change function creation procedure
    
    This is supposed to make every function a proper object when it can be passed
    to a breakpoint the first time. Especially all members are supposed to be
    set already.

diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 3e9b6dd..879ed9d 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -67,40 +67,31 @@ swfdec_as_function_init (SwfdecAsFunctio
 }
 
 /**
- * swfdec_as_function_create:
- * @context: a #SwfdecAsFunction
- * @type: the type of function to create
- * @size: size of @type
+ * swfdec_as_function_set_constructor:
+ * @fun: a #SwfdecAsFunction
  *
- * Creates a new function. The function will be of @type. It will be added to
- * @context and its prototype and constructor object will be set correctly.
- *
- * Returns: a new object of @type or %NULL on OOM
+ * Sets the constructor and prototype of @fun. This is a shortcut for calling
+ * swfdec_as_object_set_constructor() with the right arguments.
  **/
-SwfdecAsFunction *
-swfdec_as_function_create (SwfdecAsContext *context, GType type, guint size)
+void
+swfdec_as_function_set_constructor (SwfdecAsFunction *fun)
 {
+  SwfdecAsContext *context;
+  SwfdecAsObject *object;
   SwfdecAsValue val;
-  SwfdecAsObject *fun;
 
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
-  g_return_val_if_fail (g_type_is_a (type, SWFDEC_TYPE_AS_FUNCTION), NULL);
-  g_return_val_if_fail (size >= sizeof (SwfdecAsFunction), NULL);
-
-  if (!swfdec_as_context_use_mem (context, size))
-    return NULL;
-  fun = g_object_new (type, NULL);
-  swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, size);
+  g_return_if_fail (SWFDEC_IS_AS_FUNCTION (fun));
+
+  object = SWFDEC_AS_OBJECT (fun);
+  context = object->context;
   if (context->Function) {
     SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
-    swfdec_as_object_set_variable (fun, SWFDEC_AS_STR_constructor, &val);
+    swfdec_as_object_set_variable (object, SWFDEC_AS_STR_constructor, &val);
   }
   if (context->Function_prototype) {
     SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function_prototype);
-    swfdec_as_object_set_variable (fun, SWFDEC_AS_STR___proto__, &val);
+    swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
   }
-
-  return SWFDEC_AS_FUNCTION (fun);
 }
 
 /**
diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h
index ae3103a..534aad5 100644
--- a/libswfdec/swfdec_as_function.h
+++ b/libswfdec/swfdec_as_function.h
@@ -50,10 +50,6 @@ struct _SwfdecAsFunctionClass {
 
 GType			swfdec_as_function_get_type	(void);
 
-SwfdecAsFunction *	swfdec_as_function_create	(SwfdecAsContext *	context, 
-							 GType			type,
-							 guint			size);
-
 void			swfdec_as_function_call		(SwfdecAsFunction *	function,
 							 SwfdecAsObject *	thisp,
 							 guint			n_args,
diff --git a/libswfdec/swfdec_as_internal.h b/libswfdec/swfdec_as_internal.h
index 5906ef4..69db628 100644
--- a/libswfdec/swfdec_as_internal.h
+++ b/libswfdec/swfdec_as_internal.h
@@ -33,7 +33,8 @@ G_BEGIN_DECLS
 void	      	swfdec_as_array_init_context	(SwfdecAsContext *	context,
 					      	 guint			version);
 
-/* swfdec_as_function.c */
+
+void		swfdec_as_function_set_constructor (SwfdecAsFunction *	fun);
 void		swfdec_as_function_init_context (SwfdecAsContext *	context,
 						 guint			version);
 
@@ -53,5 +54,6 @@ void		swfdec_as_object_foreach_rename	(S
 void		swfdec_as_object_init_context	(SwfdecAsContext *	context,
 					      	 guint			version);
 
+
 G_END_DECLS
 #endif
diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c
index 59cd182..9e92e1f 100644
--- a/libswfdec/swfdec_as_native_function.c
+++ b/libswfdec/swfdec_as_native_function.c
@@ -24,6 +24,7 @@
 #include "swfdec_as_native_function.h"
 #include "swfdec_as_context.h"
 #include "swfdec_as_frame_internal.h"
+#include "swfdec_as_internal.h"
 #include "swfdec_as_stack.h"
 #include "swfdec_debug.h"
 
@@ -122,22 +123,23 @@ SwfdecAsFunction *
 swfdec_as_native_function_new (SwfdecAsContext *context, const char *name,
     SwfdecAsNative native, guint min_args)
 {
-  SwfdecAsNativeFunction *nfun;
-  SwfdecAsFunction *fun;
+  SwfdecAsNativeFunction *fun;
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
   g_return_val_if_fail (native != NULL, NULL);
 
-  fun = swfdec_as_function_create (context, SWFDEC_TYPE_AS_NATIVE_FUNCTION,
-      sizeof (SwfdecAsNativeFunction));
+  if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsNativeFunction)))
+    return NULL;
+  fun = g_object_new (SWFDEC_TYPE_AS_NATIVE_FUNCTION, NULL);
   if (fun == NULL)
     return NULL;
-  nfun = SWFDEC_AS_NATIVE_FUNCTION (fun);
-  nfun->native = native;
-  nfun->min_args = min_args;
-  nfun->name = g_strdup (name);
+  fun->native = native;
+  fun->min_args = min_args;
+  fun->name = g_strdup (name);
+  swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsNativeFunction));
+  swfdec_as_function_set_constructor (SWFDEC_AS_FUNCTION (fun));
 
-  return fun;
+  return SWFDEC_AS_FUNCTION (fun);
 }
 
 /**
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 10a553a..7623b7e 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -24,6 +24,7 @@
 #include "swfdec_as_script_function.h"
 #include "swfdec_as_context.h"
 #include "swfdec_as_frame_internal.h"
+#include "swfdec_as_internal.h"
 #include "swfdec_as_stack.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
@@ -114,20 +115,26 @@ SwfdecAsFunction *
 swfdec_as_script_function_new (SwfdecAsScope *scope, SwfdecAsObject *target, SwfdecScript *script)
 {
   SwfdecAsValue val;
-  SwfdecAsFunction *fun;
+  SwfdecAsScriptFunction *fun;
   SwfdecAsObject *proto;
+  SwfdecAsContext *context;
 
   g_return_val_if_fail (SWFDEC_IS_AS_SCOPE (scope), NULL);
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (target), NULL);
   g_return_val_if_fail (script != NULL, NULL);
 
-  fun = swfdec_as_function_create (SWFDEC_AS_OBJECT (scope)->context, 
-      SWFDEC_TYPE_AS_SCRIPT_FUNCTION, sizeof (SwfdecAsScriptFunction));
+  context = target->context;
+  if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsScriptFunction)))
+    return NULL;
+  fun = g_object_new (SWFDEC_TYPE_AS_SCRIPT_FUNCTION, NULL);
   if (fun == NULL)
     return NULL;
-  SWFDEC_AS_SCRIPT_FUNCTION (fun)->scope = scope;
-  SWFDEC_AS_SCRIPT_FUNCTION (fun)->script = script;
-  SWFDEC_AS_SCRIPT_FUNCTION (fun)->target = target;
+  fun->scope = scope;
+  fun->script = script;
+  fun->target = target;
+  swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsScriptFunction));
+  swfdec_as_function_set_constructor (SWFDEC_AS_FUNCTION (fun));
+  /* set prototype */
   proto = swfdec_as_object_new (SWFDEC_AS_OBJECT (scope)->context);
   if (proto == NULL)
     return NULL;
@@ -136,6 +143,6 @@ swfdec_as_script_function_new (SwfdecAsS
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val);
 
-  return fun;
+  return SWFDEC_AS_FUNCTION (fun);
 }
 
diff-tree 3589dfbffcdca650ce957c86ccbe0ce96078a24c (from 7f63d1408763835caedad52650757c8482ec0c46)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 19:03:23 2007 +0200

    require passing the script to swfdec_as_script_function_new()
    
    also refactor code to make use of this

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 7b5d231..461c875 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1484,18 +1484,6 @@ swfdec_action_define_function (SwfdecAsC
     SWFDEC_ERROR ("could not parse function name");
     return;
   }
-  /* see function-scope tests */
-  if (cx->version > 5) {
-    /* FIXME: or original target? */
-    fun = swfdec_as_script_function_new (frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame), frame->target);
-  } else {
-    SwfdecAsScope *scope = frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame);
-    while (scope->next)
-      scope = scope->next;
-    fun = swfdec_as_script_function_new (scope, frame->target);
-  }
-  if (fun == NULL)
-    return;
   n_args = swfdec_bits_get_u16 (&bits);
   if (v2) {
     n_registers = swfdec_bits_get_u8 (&bits);
@@ -1565,7 +1553,18 @@ swfdec_action_define_function (SwfdecAsC
   script->n_registers = n_registers;
   script->n_arguments = n_args;
   script->arguments = args;
-  SWFDEC_AS_SCRIPT_FUNCTION (fun)->script = script;
+  /* see function-scope tests */
+  if (cx->version > 5) {
+    /* FIXME: or original target? */
+    fun = swfdec_as_script_function_new (frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame), frame->target, script);
+  } else {
+    SwfdecAsScope *scope = frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame);
+    while (scope->next)
+      scope = scope->next;
+    fun = swfdec_as_script_function_new (scope, frame->target, script);
+  }
+  if (fun == NULL)
+    return;
   /* attach the function */
   if (*function_name == '\0') {
     swfdec_as_stack_ensure_free (cx, 1);
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 3ab7064..10a553a 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -111,7 +111,7 @@ swfdec_as_script_function_init (SwfdecAs
 }
 
 SwfdecAsFunction *
-swfdec_as_script_function_new (SwfdecAsScope *scope, SwfdecAsObject *target)
+swfdec_as_script_function_new (SwfdecAsScope *scope, SwfdecAsObject *target, SwfdecScript *script)
 {
   SwfdecAsValue val;
   SwfdecAsFunction *fun;
@@ -119,12 +119,14 @@ swfdec_as_script_function_new (SwfdecAsS
 
   g_return_val_if_fail (SWFDEC_IS_AS_SCOPE (scope), NULL);
   g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (target), NULL);
+  g_return_val_if_fail (script != NULL, NULL);
 
   fun = swfdec_as_function_create (SWFDEC_AS_OBJECT (scope)->context, 
       SWFDEC_TYPE_AS_SCRIPT_FUNCTION, sizeof (SwfdecAsScriptFunction));
   if (fun == NULL)
     return NULL;
   SWFDEC_AS_SCRIPT_FUNCTION (fun)->scope = scope;
+  SWFDEC_AS_SCRIPT_FUNCTION (fun)->script = script;
   SWFDEC_AS_SCRIPT_FUNCTION (fun)->target = target;
   proto = swfdec_as_object_new (SWFDEC_AS_OBJECT (scope)->context);
   if (proto == NULL)
diff --git a/libswfdec/swfdec_as_script_function.h b/libswfdec/swfdec_as_script_function.h
index 9f47919..69f3481 100644
--- a/libswfdec/swfdec_as_script_function.h
+++ b/libswfdec/swfdec_as_script_function.h
@@ -53,7 +53,8 @@ struct _SwfdecAsScriptFunctionClass {
 GType			swfdec_as_script_function_get_type	(void);
 
 SwfdecAsFunction *	swfdec_as_script_function_new		(SwfdecAsScope *	scope,
-								 SwfdecAsObject *	target);
+								 SwfdecAsObject *	target,
+								 SwfdecScript *		script);
 
 
 G_END_DECLS
diff-tree 7f63d1408763835caedad52650757c8482ec0c46 (from parents)
Merge: c168f4149f139c40bd7556f3baa4af67c969c32e afdf9987d560b315469d8747f56916dcd3235ecb
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:43:45 2007 +0200

    Merge branch 'master' into vivi

diff-tree c168f4149f139c40bd7556f3baa4af67c969c32e (from 6878ba31199421d00813814f6822b3d30e2e3884)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:35:29 2007 +0200

    set a somewhat sane default size

diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 617e317..fe4b35c 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -67,6 +67,7 @@ setup (const char *filename, const char 
   vivi_application_set_filename (app, filename);
   vivi_application_set_variables (app, variables);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_default_size (GTK_WINDOW (window), 400, 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));
diff-tree 6878ba31199421d00813814f6822b3d30e2e3884 (from f781524c4f4ad87e3e277417b6e29df6d9d1a7a5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:35:07 2007 +0200

    add test for registers

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 45b56a8..124ea62 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -245,6 +245,15 @@ EXTRA_DIST = \
 	definefunction2-overwrite.swf \
 	definefunction2-overwrite.swf.trace \
 	definefunction2-overwrite.xml \
+	definefunction2-registers.xml \
+	definefunction2-registers-5.swf \
+	definefunction2-registers-5.swf.trace \
+	definefunction2-registers-6.swf \
+	definefunction2-registers-6.swf.trace \
+	definefunction2-registers-7.swf \
+	definefunction2-registers-7.swf.trace \
+	definefunction2-registers-8.swf \
+	definefunction2-registers-8.swf.trace \
 	definefunction2-this.swf \
 	definefunction2-this.swf.trace \
 	definefunction2-this.xml \
diff --git a/test/trace/definefunction2-registers-5.swf b/test/trace/definefunction2-registers-5.swf
new file mode 100644
index 0000000..6d1adce
Binary files /dev/null and b/test/trace/definefunction2-registers-5.swf differ
diff --git a/test/trace/definefunction2-registers-5.swf.trace b/test/trace/definefunction2-registers-5.swf.trace
new file mode 100644
index 0000000..fe4c04b
--- /dev/null
+++ b/test/trace/definefunction2-registers-5.swf.trace
@@ -0,0 +1,67 @@
+Check how DefineFunction2 handles register counts
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
diff --git a/test/trace/definefunction2-registers-6.swf b/test/trace/definefunction2-registers-6.swf
new file mode 100644
index 0000000..e7a5958
Binary files /dev/null and b/test/trace/definefunction2-registers-6.swf differ
diff --git a/test/trace/definefunction2-registers-6.swf.trace b/test/trace/definefunction2-registers-6.swf.trace
new file mode 100644
index 0000000..fe4c04b
--- /dev/null
+++ b/test/trace/definefunction2-registers-6.swf.trace
@@ -0,0 +1,67 @@
+Check how DefineFunction2 handles register counts
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
diff --git a/test/trace/definefunction2-registers-7.swf b/test/trace/definefunction2-registers-7.swf
new file mode 100644
index 0000000..7abb8c1
Binary files /dev/null and b/test/trace/definefunction2-registers-7.swf differ
diff --git a/test/trace/definefunction2-registers-7.swf.trace b/test/trace/definefunction2-registers-7.swf.trace
new file mode 100644
index 0000000..fe4c04b
--- /dev/null
+++ b/test/trace/definefunction2-registers-7.swf.trace
@@ -0,0 +1,67 @@
+Check how DefineFunction2 handles register counts
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
diff --git a/test/trace/definefunction2-registers-8.swf b/test/trace/definefunction2-registers-8.swf
new file mode 100644
index 0000000..917dfc6
Binary files /dev/null and b/test/trace/definefunction2-registers-8.swf differ
diff --git a/test/trace/definefunction2-registers-8.swf.trace b/test/trace/definefunction2-registers-8.swf.trace
new file mode 100644
index 0000000..fe4c04b
--- /dev/null
+++ b/test/trace/definefunction2-registers-8.swf.trace
@@ -0,0 +1,67 @@
+Check how DefineFunction2 handles register counts
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
+hi
+hi
+hi
+hi
+hi
+undefined
+undefined
+undefined
+undefined
+undefined
+hi
diff --git a/test/trace/definefunction2-registers.xml b/test/trace/definefunction2-registers.xml
new file mode 100644
index 0000000..00f53c3
--- /dev/null
+++ b/test/trace/definefunction2-registers.xml
@@ -0,0 +1,336 @@
+<?xml version="1.0"?>
+<swf version="5" compressed="1">
+  <!-- swfmill xml2swf definefunction2-registers.xml definefunction2-registers.swf -->
+  <Header framerate="25" frames="1">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <DoAction>
+	<actions>
+	  <PushData>
+	    <items>
+	      <StackString value="Check how DefineFunction2 handles register counts"/>
+	    </items>
+	  </PushData>
+	  <Trace/>
+	  <DeclareFunction2 name="foo" argc="0" regc="0">
+            <actions>
+	      <PushData>
+		<items>
+                  <StackString value="hi"/>
+		</items>
+	      </PushData>
+	      <StoreRegister reg="0"/>
+	      <StoreRegister reg="1"/>
+	      <StoreRegister reg="2"/>
+	      <StoreRegister reg="3"/>
+	      <StoreRegister reg="4"/>
+	      <StoreRegister reg="5"/>
+	      <StoreRegister reg="6"/>
+	      <StoreRegister reg="7"/>
+	      <StoreRegister reg="8"/>
+	      <StoreRegister reg="9"/>
+	      <PushData>
+		<items>
+                  <StackRegister reg="9"/>
+                  <StackRegister reg="8"/>
+                  <StackRegister reg="7"/>
+                  <StackRegister reg="6"/>
+                  <StackRegister reg="5"/>
+                  <StackRegister reg="4"/>
+                  <StackRegister reg="3"/>
+                  <StackRegister reg="2"/>
+                  <StackRegister reg="1"/>
+                  <StackRegister reg="0"/>
+		</items>
+	      </PushData>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	    </actions>
+	  </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackString value="foo"/>
+            </items>
+          </PushData>
+	  <CallFunction/>
+	  <Pop/>
+	  <DeclareFunction2 name="foo" argc="0" regc="1">
+            <actions>
+	      <PushData>
+		<items>
+                  <StackString value="hi"/>
+		</items>
+	      </PushData>
+	      <StoreRegister reg="0"/>
+	      <StoreRegister reg="1"/>
+	      <StoreRegister reg="2"/>
+	      <StoreRegister reg="3"/>
+	      <StoreRegister reg="4"/>
+	      <StoreRegister reg="5"/>
+	      <StoreRegister reg="6"/>
+	      <StoreRegister reg="7"/>
+	      <StoreRegister reg="8"/>
+	      <StoreRegister reg="9"/>
+	      <PushData>
+		<items>
+                  <StackRegister reg="9"/>
+                  <StackRegister reg="8"/>
+                  <StackRegister reg="7"/>
+                  <StackRegister reg="6"/>
+                  <StackRegister reg="5"/>
+                  <StackRegister reg="4"/>
+                  <StackRegister reg="3"/>
+                  <StackRegister reg="2"/>
+                  <StackRegister reg="1"/>
+                  <StackRegister reg="0"/>
+		</items>
+	      </PushData>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	    </actions>
+	  </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackString value="foo"/>
+            </items>
+          </PushData>
+	  <CallFunction/>
+	  <Pop/>
+	  <DeclareFunction2 name="foo" argc="0" regc="2">
+            <actions>
+	      <PushData>
+		<items>
+                  <StackString value="hi"/>
+		</items>
+	      </PushData>
+	      <StoreRegister reg="0"/>
+	      <StoreRegister reg="1"/>
+	      <StoreRegister reg="2"/>
+	      <StoreRegister reg="3"/>
+	      <StoreRegister reg="4"/>
+	      <StoreRegister reg="5"/>
+	      <StoreRegister reg="6"/>
+	      <StoreRegister reg="7"/>
+	      <StoreRegister reg="8"/>
+	      <StoreRegister reg="9"/>
+	      <PushData>
+		<items>
+                  <StackRegister reg="9"/>
+                  <StackRegister reg="8"/>
+                  <StackRegister reg="7"/>
+                  <StackRegister reg="6"/>
+                  <StackRegister reg="5"/>
+                  <StackRegister reg="4"/>
+                  <StackRegister reg="3"/>
+                  <StackRegister reg="2"/>
+                  <StackRegister reg="1"/>
+                  <StackRegister reg="0"/>
+		</items>
+	      </PushData>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	    </actions>
+	  </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackString value="foo"/>
+            </items>
+          </PushData>
+	  <CallFunction/>
+	  <Pop/>
+	  <DeclareFunction2 name="foo" argc="0" regc="3">
+            <actions>
+	      <PushData>
+		<items>
+                  <StackString value="hi"/>
+		</items>
+	      </PushData>
+	      <StoreRegister reg="0"/>
+	      <StoreRegister reg="1"/>
+	      <StoreRegister reg="2"/>
+	      <StoreRegister reg="3"/>
+	      <StoreRegister reg="4"/>
+	      <StoreRegister reg="5"/>
+	      <StoreRegister reg="6"/>
+	      <StoreRegister reg="7"/>
+	      <StoreRegister reg="8"/>
+	      <StoreRegister reg="9"/>
+	      <PushData>
+		<items>
+                  <StackRegister reg="9"/>
+                  <StackRegister reg="8"/>
+                  <StackRegister reg="7"/>
+                  <StackRegister reg="6"/>
+                  <StackRegister reg="5"/>
+                  <StackRegister reg="4"/>
+                  <StackRegister reg="3"/>
+                  <StackRegister reg="2"/>
+                  <StackRegister reg="1"/>
+                  <StackRegister reg="0"/>
+		</items>
+	      </PushData>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	    </actions>
+	  </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackString value="foo"/>
+            </items>
+          </PushData>
+	  <CallFunction/>
+	  <Pop/>
+	  <DeclareFunction2 name="foo" argc="0" regc="4">
+            <actions>
+	      <PushData>
+		<items>
+                  <StackString value="hi"/>
+		</items>
+	      </PushData>
+	      <StoreRegister reg="0"/>
+	      <StoreRegister reg="1"/>
+	      <StoreRegister reg="2"/>
+	      <StoreRegister reg="3"/>
+	      <StoreRegister reg="4"/>
+	      <StoreRegister reg="5"/>
+	      <StoreRegister reg="6"/>
+	      <StoreRegister reg="7"/>
+	      <StoreRegister reg="8"/>
+	      <StoreRegister reg="9"/>
+	      <PushData>
+		<items>
+                  <StackRegister reg="9"/>
+                  <StackRegister reg="8"/>
+                  <StackRegister reg="7"/>
+                  <StackRegister reg="6"/>
+                  <StackRegister reg="5"/>
+                  <StackRegister reg="4"/>
+                  <StackRegister reg="3"/>
+                  <StackRegister reg="2"/>
+                  <StackRegister reg="1"/>
+                  <StackRegister reg="0"/>
+		</items>
+	      </PushData>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	    </actions>
+	  </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackString value="foo"/>
+            </items>
+          </PushData>
+	  <CallFunction/>
+	  <Pop/>
+	  <DeclareFunction2 name="foo" argc="0" regc="5">
+            <actions>
+	      <PushData>
+		<items>
+                  <StackString value="hi"/>
+		</items>
+	      </PushData>
+	      <StoreRegister reg="0"/>
+	      <StoreRegister reg="1"/>
+	      <StoreRegister reg="2"/>
+	      <StoreRegister reg="3"/>
+	      <StoreRegister reg="4"/>
+	      <StoreRegister reg="5"/>
+	      <StoreRegister reg="6"/>
+	      <StoreRegister reg="7"/>
+	      <StoreRegister reg="8"/>
+	      <StoreRegister reg="9"/>
+	      <PushData>
+		<items>
+                  <StackRegister reg="9"/>
+                  <StackRegister reg="8"/>
+                  <StackRegister reg="7"/>
+                  <StackRegister reg="6"/>
+                  <StackRegister reg="5"/>
+                  <StackRegister reg="4"/>
+                  <StackRegister reg="3"/>
+                  <StackRegister reg="2"/>
+                  <StackRegister reg="1"/>
+                  <StackRegister reg="0"/>
+		</items>
+	      </PushData>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	      <Trace/>
+	    </actions>
+	  </DeclareFunction2>
+          <PushData>
+            <items>
+              <StackInteger value="0"/>
+              <StackString value="foo"/>
+            </items>
+          </PushData>
+	  <CallFunction/>
+	  <Pop/>
+	  <GetURL url="fscommand:quit" target=""/>
+	</actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
diff-tree f781524c4f4ad87e3e277417b6e29df6d9d1a7a5 (from 8c9b43ea93defc0eb2fd8b36f5b59fe0d2e1693a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:33:47 2007 +0200

    fix warnings

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 99d6a5a..cc788db 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -248,7 +248,7 @@ main (int argc, char **argv)
       Test *test = walk->data;
       
       run_test (test, NULL);
-      g_print (test->output);
+      g_print ("%s", test->output);
       if (!test->success) {
 	failures++;
 	g_string_append_printf (failed_tests, 
@@ -276,7 +276,7 @@ main (int argc, char **argv)
       Test *test = walk->data;
       while (test->output == NULL)
 	g_cond_wait (cond, mutex);
-      g_print (test->output);
+      g_print ("%s", test->output);
       if (!test->success) {
 	failures++;
 	g_string_append_printf (failed_tests, 
diff-tree 8c9b43ea93defc0eb2fd8b36f5b59fe0d2e1693a (from 766540d421a3bfc96ca32b66dedb9f96b49682d0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:33:29 2007 +0200

    define scope and target earlier

diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index f8b6ad2..3ab7064 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -124,6 +124,8 @@ swfdec_as_script_function_new (SwfdecAsS
       SWFDEC_TYPE_AS_SCRIPT_FUNCTION, sizeof (SwfdecAsScriptFunction));
   if (fun == NULL)
     return NULL;
+  SWFDEC_AS_SCRIPT_FUNCTION (fun)->scope = scope;
+  SWFDEC_AS_SCRIPT_FUNCTION (fun)->target = target;
   proto = swfdec_as_object_new (SWFDEC_AS_OBJECT (scope)->context);
   if (proto == NULL)
     return NULL;
@@ -131,8 +133,6 @@ swfdec_as_script_function_new (SwfdecAsS
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val);
-  SWFDEC_AS_SCRIPT_FUNCTION (fun)->scope = scope;
-  SWFDEC_AS_SCRIPT_FUNCTION (fun)->target = target;
 
   return fun;
 }
diff-tree 766540d421a3bfc96ca32b66dedb9f96b49682d0 (from dbc065c9730a6dc69caca57bb5509cf356e5cd51)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:32:34 2007 +0200

    just use a higher version interpreter for a bytecode if the vurrent version doesn't know it

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 96c23e4..b2a74cb 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -682,6 +682,7 @@ swfdec_as_context_run (SwfdecAsContext *
   SwfdecAsFrame *frame, *last_frame;
   SwfdecScript *script;
   const SwfdecActionSpec *spec;
+  SwfdecActionExec exec;
   guint8 *startpc, *pc, *endpc, *nextpc;
 #ifndef G_DISABLE_ASSERT
   SwfdecAsValue *check;
@@ -813,12 +814,22 @@ start:
       nextpc = pc + 1;
     }
     /* check action is valid */
-    if (spec->exec[version] == NULL) {
-      SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, skipping it", action,
-	  action, spec->name ? spec->name : "Unknown", script->version);
-      frame->pc = pc = nextpc;
-      check_scope = TRUE;
-      continue;
+    exec = spec->exec[version];
+    if (!exec) {
+      guint real_version;
+      for (real_version = version + 1; !exec && real_version <= SWFDEC_AS_MAX_SCRIPT_VERSION; real_version++) {
+	exec = spec->exec[real_version];
+      }
+      if (!exec) {
+	SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, skipping it", action,
+	    action, spec->name ? spec->name : "Unknown", script->version);
+	frame->pc = pc = nextpc;
+	check_scope = TRUE;
+	continue;
+      }
+      SWFDEC_WARNING ("cannot interpret action %3u 0x%02X %s for version %u, using version %u instead", 
+	  action, action, spec->name ? spec->name : "Unknown", script->version, 
+	  script->version + real_version - version);
     }
     if (spec->remove > 0) {
       if (spec->add > spec->remove)
@@ -836,7 +847,7 @@ start:
     check = (spec->add >= 0 && spec->remove >= 0) ? context->cur + spec->add - spec->remove : NULL;
 #endif
     /* execute action */
-    spec->exec[version] (context, action, data, len);
+    exec (context, action, data, len);
     /* adapt the pc if the action did not, otherwise, leave it alone */
     /* FIXME: do this via flag? */
     if (frame->pc == pc) {
diff-tree dbc065c9730a6dc69caca57bb5509cf356e5cd51 (from 4c21f27a1d0da5548142668069eecf835fadd541)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 17:31:44 2007 +0200

    0 registers means 4 registers

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 73907ee..7b5d231 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1499,6 +1499,8 @@ swfdec_action_define_function (SwfdecAsC
   n_args = swfdec_bits_get_u16 (&bits);
   if (v2) {
     n_registers = swfdec_bits_get_u8 (&bits);
+    if (n_registers == 0)
+      n_registers = 4;
     flags = swfdec_bits_get_u16 (&bits);
   } else {
     n_registers = 5;
diff-tree 4c21f27a1d0da5548142668069eecf835fadd541 (from 30dee9addcb7b3da9dbf00e260662acd648df851)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 13:11:50 2007 +0200

    implement Breakpoint.onSetVariable breakpoint

diff --git a/vivified/core/vivi_breakpoint.c b/vivified/core/vivi_breakpoint.c
index 506ee08..15cfc26 100644
--- a/vivified/core/vivi_breakpoint.c
+++ b/vivified/core/vivi_breakpoint.c
@@ -63,6 +63,21 @@ vivi_breakpoint_finish_frame (ViviDebugg
   return swfdec_as_value_to_boolean (obj->context, &retval);
 }
 
+static gboolean
+vivi_breakpoint_set_variable (ViviDebugger *debugger, SwfdecAsObject *object, 
+    const char *variable, const SwfdecAsValue *value, ViviBreakpoint *breakpoint)
+{
+  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
+  SwfdecAsValue vals[3];
+  SwfdecAsValue retval;
+
+  SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], vivi_wrap_object (VIVI_APPLICATION (obj->context), object));
+  SWFDEC_AS_VALUE_SET_STRING (&vals[1], swfdec_as_context_get_string (obj->context, variable));
+  vivi_wrap_value (VIVI_APPLICATION (obj->context), &vals[2], value);
+  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onSetVariable"), 3, vals, &retval);
+  return swfdec_as_value_to_boolean (obj->context, &retval);
+}
+
 static const struct {
   const char *	event;
   const char *	signal;
@@ -71,7 +86,8 @@ static const struct {
   { NULL, NULL, NULL }, /* invalid */
   { "onCommand", "step", G_CALLBACK (vivi_breakpoint_step) },
   { "onStartFrame", "start-frame", G_CALLBACK (vivi_breakpoint_start_frame) },
-  { "onExitFrame", "finish-frame", G_CALLBACK (vivi_breakpoint_finish_frame) }
+  { "onExitFrame", "finish-frame", G_CALLBACK (vivi_breakpoint_finish_frame) },
+  { "onSetVariable", "set-variable", G_CALLBACK (vivi_breakpoint_set_variable) }
 };
 
 static guint
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index c8c76a8..a5ae2eb 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -31,6 +31,7 @@ enum {
   STEP,
   START_FRAME,
   FINISH_FRAME,
+  SET_VARIABLE,
   LAST_SIGNAL
 };
 
@@ -129,6 +130,18 @@ vivi_debugger_finish_frame (SwfdecAsDebu
 }
 
 static void
+vivi_debugger_set_variable (SwfdecAsDebugger *debugger, SwfdecAsContext *context, 
+    SwfdecAsObject *object, const char *variable, const SwfdecAsValue *value)
+{
+  gboolean retval = FALSE;
+
+  g_signal_emit (debugger, signals[SET_VARIABLE], 0, object, variable, value, &retval);
+
+  if (retval)
+    vivi_debugger_break (VIVI_DEBUGGER (debugger));
+}
+
+static void
 vivi_debugger_class_init (ViviDebuggerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -145,10 +158,14 @@ vivi_debugger_class_init (ViviDebuggerCl
   signals[FINISH_FRAME] = g_signal_new ("finish-frame", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT_POINTER,
       G_TYPE_BOOLEAN, 2, SWFDEC_TYPE_AS_FRAME, G_TYPE_POINTER);
+  signals[SET_VARIABLE] = g_signal_new ("set-variable", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT_STRING_POINTER,
+      G_TYPE_BOOLEAN, 3, SWFDEC_TYPE_AS_OBJECT, G_TYPE_STRING, G_TYPE_POINTER);
 
   debugger_class->step = vivi_debugger_step;
   debugger_class->start_frame = vivi_debugger_start_frame;
   debugger_class->finish_frame = vivi_debugger_finish_frame;
+  debugger_class->set_variable = vivi_debugger_set_variable;
 }
 
 static void
diff --git a/vivified/core/vivi_marshal.list b/vivified/core/vivi_marshal.list
index 7dce98e..e28004f 100644
--- a/vivified/core/vivi_marshal.list
+++ b/vivified/core/vivi_marshal.list
@@ -1,3 +1,4 @@
 BOOLEAN:OBJECT
 BOOLEAN:OBJECT,POINTER
+BOOLEAN:OBJECT,STRING,POINTER
 BOOLEAN:VOID
diff-tree 30dee9addcb7b3da9dbf00e260662acd648df851 (from 66ab735ff2220bb72c978d827978edda1b215fe9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 13:11:02 2007 +0200

    allow getting the global variable of the player

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 16384fd..65f51d1 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -41,8 +41,9 @@ Breakpoint.prototype.addProperty ("activ
 /*** information about the player ***/
 
 Player = {};
-Player.addProperty ("frame", Native.player_frame_get, null);
 Player.addProperty ("filename", Native.player_filename_get, Native.player_filename_set);
+Player.addProperty ("frame", Native.player_frame_get, null);
+Player.addProperty ("global", Native.player_global_get, null);
 Player.addProperty ("variables", Native.player_variables_get, Native.player_variables_set);
 
 /*** commands available for debugging ***/
diff --git a/vivified/core/vivi_player_as.c b/vivified/core/vivi_player_as.c
index 01eb69a..c7e36ad 100644
--- a/vivified/core/vivi_player_as.c
+++ b/vivified/core/vivi_player_as.c
@@ -92,3 +92,16 @@ vivi_player_as_variables_set (SwfdecAsCo
   vivi_application_set_variables (app, s);
 }
 
+VIVI_FUNCTION ("player_global_get", vivi_player_as_global_get)
+void
+vivi_player_as_global_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  
+  if (SWFDEC_AS_CONTEXT (app->player)->global) {
+    SWFDEC_AS_VALUE_SET_OBJECT (retval, vivi_wrap_object (app, 
+	  SWFDEC_AS_CONTEXT (app->player)->global));
+  }
+}
+
diff-tree 66ab735ff2220bb72c978d827978edda1b215fe9 (from f7aaf7413c4306caf1f870a7606fbbe86540f16e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 13:10:28 2007 +0200

    handle stepping outside of breakpoints correctly

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index cc1d4c2..b7f3b9f 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -257,9 +257,18 @@ vivi_application_step_forward (gpointer 
   ViviApplication *app = appp;
   guint next_event;
 
+  app->step_source = 0;
+  if (app->loop != NULL ||
+      app->playback_state != VIVI_APPLICATION_STEPPING)
+    return FALSE;
+
+  app->playback_count--;
+  if (app->playback_count == 0)
+    app->playback_state = VIVI_APPLICATION_STOPPED;
   next_event = swfdec_player_get_next_event (app->player);
   swfdec_player_advance (app->player, next_event);
 
+  vivi_application_check (app);
   return FALSE;
 }
 
@@ -281,9 +290,8 @@ vivi_application_check (ViviApplication 
     case VIVI_APPLICATION_PLAYING:
       break;
     case VIVI_APPLICATION_STEPPING:
-      if (!is_breakpoint) {
-	/* FIXME: sanely handle this */
-	g_idle_add_full (-100, vivi_application_step_forward, app, NULL);
+      if (!is_breakpoint && app->step_source == 0) {
+	app->step_source = g_idle_add_full (-100, vivi_application_step_forward, app, NULL);
       }
       break;
     default:
@@ -391,6 +399,12 @@ vivi_application_quit (ViviApplication *
     return;
   app->playback_state = VIVI_APPLICATION_EXITING;
   app->playback_count = 1;
+  if (app->step_source) {
+    if (!g_source_remove (app->step_source)) {
+      g_assert_not_reached ();
+    } 
+    app->step_source = 0;
+  }
   g_object_notify (G_OBJECT (app), "quit");
   vivi_application_check (app);
 }
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 33694bf..1a8c68a 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -62,6 +62,7 @@ struct _ViviApplication
   ViviApplicationPlayback playback_state;	/* (running, stepping or stopped) */
   guint			playback_count;	/* how often to just restart this on breakpoints */
   GMainLoop *		loop;		/* the breakpoint main loop */
+  guint			step_source;	/* source for stepping forward */
 
   GHashTable *		wraps;		/* all wrapped objects from @player */
 };
diff-tree f7aaf7413c4306caf1f870a7606fbbe86540f16e (from 308d22cae15ac29dd9e7914ec9d3151639a7f529)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 13:09:51 2007 +0200

    make that breakpoint work and not crash

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 4dbcb1d..111dbb3 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -564,7 +564,7 @@ swfdec_as_object_set_variable (SwfdecAsO
 
   if (object->context->debugger) {
     SwfdecAsDebugger *debugger = object->context->debugger;
-    SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_CLASS (klass);
+    SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_GET_CLASS (debugger);
     if (dklass->set_variable)
       dklass->set_variable (debugger, object->context, object, variable, value);
   }
diff-tree 308d22cae15ac29dd9e7914ec9d3151639a7f529 (from 76ee7efbfdf7f2c77b52784a9f6e118fe20f8044)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 10:07:16 2007 +0200

    add set_variable entry point for debugger
    
    includes a constness fix

diff --git a/libswfdec/swfdec_as_debugger.h b/libswfdec/swfdec_as_debugger.h
index fdd2a76..4a0f952 100644
--- a/libswfdec/swfdec_as_debugger.h
+++ b/libswfdec/swfdec_as_debugger.h
@@ -54,7 +54,13 @@ struct _SwfdecAsDebuggerClass {
   void			(* finish_frame)(SwfdecAsDebugger *	debugger,
 					 SwfdecAsContext *	context,
 					 SwfdecAsFrame *	frame,
-					 SwfdecAsValue *	return_value);
+					 const SwfdecAsValue *	return_value);
+  /* called before setting a variable */
+  void			(* set_variable)(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context,
+					 SwfdecAsObject *	object,
+					 const char *		variable,
+					 const SwfdecAsValue *	value);
 };
 
 GType		swfdec_as_debugger_get_type	(void);
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index ee112db..4dbcb1d 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -562,6 +562,12 @@ swfdec_as_object_set_variable (SwfdecAsO
   g_return_if_fail (variable != NULL);
   g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
 
+  if (object->context->debugger) {
+    SwfdecAsDebugger *debugger = object->context->debugger;
+    SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_CLASS (klass);
+    if (dklass->set_variable)
+      dklass->set_variable (debugger, object->context, object, variable, value);
+  }
   klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
   klass->set (object, variable, value);
 }
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index 670daff..c8c76a8 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -117,7 +117,8 @@ vivi_debugger_start_frame (SwfdecAsDebug
 }
 
 static void
-vivi_debugger_finish_frame (SwfdecAsDebugger *debugger, SwfdecAsContext *context, SwfdecAsFrame *frame, SwfdecAsValue *ret)
+vivi_debugger_finish_frame (SwfdecAsDebugger *debugger, SwfdecAsContext *context, 
+    SwfdecAsFrame *frame, const SwfdecAsValue *ret)
 {
   gboolean retval = FALSE;
 
diff-tree 76ee7efbfdf7f2c77b52784a9f6e118fe20f8044 (from 9ed5469d665215b4a46f2f7de2628a4347cf8378)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 09:56:43 2007 +0200

    allow changing filename and variables

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index bf6ed76..16384fd 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -42,6 +42,8 @@ Breakpoint.prototype.addProperty ("activ
 
 Player = {};
 Player.addProperty ("frame", Native.player_frame_get, null);
+Player.addProperty ("filename", Native.player_filename_get, Native.player_filename_set);
+Player.addProperty ("variables", Native.player_variables_get, Native.player_variables_set);
 
 /*** commands available for debugging ***/
 
diff --git a/vivified/core/vivi_player_as.c b/vivified/core/vivi_player_as.c
index ab8c4de..01eb69a 100644
--- a/vivified/core/vivi_player_as.c
+++ b/vivified/core/vivi_player_as.c
@@ -38,3 +38,57 @@ vivi_player_as_frame_get (SwfdecAsContex
     SWFDEC_AS_VALUE_SET_OBJECT (retval, vivi_wrap_object (app, obj));
 }
 
+VIVI_FUNCTION ("player_filename_get", vivi_player_as_filename_get)
+void
+vivi_player_as_filename_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  const char *s = vivi_application_get_filename (app);
+
+  if (s)
+    SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_get_string (cx, s));
+}
+
+VIVI_FUNCTION ("player_filename_set", vivi_player_as_filename_set)
+void
+vivi_player_as_filename_set (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  const char *s;
+  
+  if (argc == 0)
+    return;
+  s = swfdec_as_value_to_string (cx, &argv[0]);
+  
+  vivi_application_set_filename (app, s);
+}
+
+VIVI_FUNCTION ("player_variables_get", vivi_player_as_variables_get)
+void
+vivi_player_as_variables_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  const char *s = vivi_application_get_variables (app);
+
+  if (s)
+    SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_get_string (cx, s));
+}
+
+VIVI_FUNCTION ("player_variables_set", vivi_player_as_variables_set)
+void
+vivi_player_as_variables_set (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  const char *s;
+  
+  if (argc == 0)
+    return;
+  s = swfdec_as_value_to_string (cx, &argv[0]);
+  
+  vivi_application_set_variables (app, s);
+}
+
diff-tree 9ed5469d665215b4a46f2f7de2628a4347cf8378 (from be3bc1a6cd88c0f2294b4f6059898c3989f172eb)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 09:55:42 2007 +0200

    don't connect the signal swapped
    
    copy/paste error

diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 13d03ab..617e317 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -68,7 +68,7 @@ setup (const char *filename, const char 
   vivi_application_set_variables (app, variables);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect_swapped (app, "notify::quit", G_CALLBACK (gtk_widget_destroy), window);
-  g_signal_connect_swapped (app, "notify::filename", G_CALLBACK (set_title), window);
+  g_signal_connect (app, "notify::filename", G_CALLBACK (set_title), window);
   set_title (app, NULL, GTK_WINDOW (window));
   box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
diff-tree be3bc1a6cd88c0f2294b4f6059898c3989f172eb (from da8a9e9b145d5cb1aebc04764e9ed66856a31c9b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:42:39 2007 +0200

    Set the title correctly

diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index df123a9..13d03ab 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -48,6 +48,16 @@ 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, *widget;
@@ -58,6 +68,8 @@ setup (const char *filename, const char 
   vivi_application_set_variables (app, variables);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect_swapped (app, "notify::quit", G_CALLBACK (gtk_widget_destroy), window);
+  g_signal_connect_swapped (app, "notify::filename", G_CALLBACK (set_title), window);
+  set_title (app, NULL, GTK_WINDOW (window));
   box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
   widget = vivi_player_new (app);
diff-tree da8a9e9b145d5cb1aebc04764e9ed66856a31c9b (from f0776fdc6d6e96c49e4daaa9d512c813b59b39df)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:31:25 2007 +0200

    make backtrace function actually work

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 7b6fdc6..bf6ed76 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -101,11 +101,12 @@ Commands.delete = Commands.del;
 Commands.where = function () {
   var frame = Player.frame;
   if (frame == undefined) {
-    print ("---");
+    Commands.print ("---");
     return;
   }
+  var i = 0;
   while (frame) {
-    print (frame);
+    Commands.print (i++ + ": " + frame);
     frame = frame.next;
   }
 };
diff-tree f0776fdc6d6e96c49e4daaa9d512c813b59b39df (from 46e54f2e89bcf81b9137cdba219d7322ee7055ad)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:26:41 2007 +0200

    debugging g_print() ...

diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index 53ea0ea..670daff 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -76,9 +76,7 @@ vivi_debugger_break (ViviDebugger *debug
   g_object_notify (G_OBJECT (app), "interrupted");
   vivi_application_check (app);
 
-  g_print (">>>\n");
   g_main_loop_run (app->loop);
-  g_print ("<<<\n");
 
   g_main_loop_unref (app->loop);
   app->loop = NULL;
diff-tree 46e54f2e89bcf81b9137cdba219d7322ee7055ad (from 19febb579adabc379bbb078c28d1afabf217dd38)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:26:20 2007 +0200

    add backtrace function

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 4751870..7b6fdc6 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -98,3 +98,16 @@ Commands.del = function (id) {
   b.active = false;
 };
 Commands.delete = Commands.del;
+Commands.where = function () {
+  var frame = Player.frame;
+  if (frame == undefined) {
+    print ("---");
+    return;
+  }
+  while (frame) {
+    print (frame);
+    frame = frame.next;
+  }
+};
+Commands.backtrace = Commands.where;
+Commands.bt = Commands.where;
diff-tree 19febb579adabc379bbb078c28d1afabf217dd38 (from 9201f46e7c8502e949f1ab9608cdb6073aa3e15d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:26:06 2007 +0200

    return the breakpoint that was added from Commands.add()

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index e654e74..4751870 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -78,6 +78,7 @@ Commands.add = function (name) {
   ret.toString = function () {
     return "function call " + name;
   };
+  return ret;
 };
 Commands.list = function () {
   var a = Breakpoint.list;
diff-tree 9201f46e7c8502e949f1ab9608cdb6073aa3e15d (from e1b2e3c7a87d7f31d97553e9cc844afca9b8dd1d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:23:47 2007 +0200

    implement Player object and Player.frame for the current frame

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 9403543..13411ef 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -14,6 +14,7 @@ libvivified_core_la_SOURCES = \
 	vivi_initialize.s \
 	vivi_marshal.c \
 	vivi_ming.c \
+	vivi_player_as.c \
 	vivi_wrap.c \
 	vivi_wrap_as.c
 
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 7686c8b..e654e74 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -38,6 +38,11 @@ Breakpoint = function () extends Native.
 Breakpoint.list = new Array ();
 Breakpoint.prototype.addProperty ("active", Native.breakpoint_active_get, Native.breakpoint_active_set);
 
+/*** information about the player ***/
+
+Player = {};
+Player.addProperty ("frame", Native.player_frame_get, null);
+
 /*** commands available for debugging ***/
 
 Commands = new Object ();
diff --git a/vivified/core/vivi_player_as.c b/vivified/core/vivi_player_as.c
new file mode 100644
index 0000000..ab8c4de
--- /dev/null
+++ b/vivified/core/vivi_player_as.c
@@ -0,0 +1,40 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_wrap.h"
+#include "vivi_application.h"
+#include "vivi_function.h"
+
+VIVI_FUNCTION ("player_frame_get", vivi_player_as_frame_get)
+void
+vivi_player_as_frame_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  SwfdecAsObject *obj;
+
+  obj = SWFDEC_AS_OBJECT (swfdec_as_context_get_frame (SWFDEC_AS_CONTEXT (app->player)));
+  if (obj)
+    SWFDEC_AS_VALUE_SET_OBJECT (retval, vivi_wrap_object (app, obj));
+}
+
diff-tree e1b2e3c7a87d7f31d97553e9cc844afca9b8dd1d (from 45a3be6f561a80d6e7ef749e0fd5ad7cf1d43ce5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 21:23:24 2007 +0200

    make swfdec_as_stack_iterator_init_arguments() work with every frame,
    not just with the first frame on the stack

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 17f88cb..5369dca 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -79,21 +79,29 @@ swfdec_as_stack_iterator_init_arguments 
 
   g_return_val_if_fail (iter != NULL, NULL);
   g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
-  /* FIXME! */
-  context = SWFDEC_AS_OBJECT (frame)->context;
-  g_return_val_if_fail (context->frame == frame, NULL);
 
+  if (frame->argc == 0) {
+    iter->current = NULL;
+    return NULL;
+  }
+  context = SWFDEC_AS_OBJECT (frame)->context;
   if (frame->argv) {
     iter->stack = NULL;
     iter->current = (SwfdecAsValue *) frame->argv;
   } else {
-    iter->stack = context->stack;
+    SwfdecAsStack *stack = context->stack;
+    SwfdecAsValue *end;
     iter->current = frame->stack_begin - 1;
+    end = context->cur;
+    while (iter->current < stack->elements ||
+	iter->current > end) {
+      stack = stack->next;
+      end = &stack->elements[stack->used_elements];
+    }
+    iter->stack = stack;
   }
   iter->i = 0;
   iter->n = frame->argc;
-  if (frame->argc == 0)
-    iter->current = NULL;
   return iter->current;
 }
 
diff-tree 45a3be6f561a80d6e7ef749e0fd5ad7cf1d43ce5 (from b199888c9610670fe2e47791fe529156f11a3733)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 20:27:33 2007 +0200

    reorder

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 5e1edac..7686c8b 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -17,12 +17,7 @@
  * Boston, MA  02110-1301  USA
  */
 
-Breakpoint = function () extends Native.Breakpoint {
-  super ();
-  Breakpoint.list.push (this);
-};
-Breakpoint.list = new Array ();
-Breakpoint.prototype.addProperty ("active", Native.breakpoint_active_get, Native.breakpoint_active_set);
+/*** general objects ***/
 
 Wrap = function () {};
 Wrap.prototype = {};
@@ -34,6 +29,15 @@ Frame.prototype.addProperty ("code", Nat
 Frame.prototype.addProperty ("name", Native.frame_name_get, null);
 Frame.prototype.addProperty ("next", Native.frame_next_get, null);
 
+/*** breakpoints ***/
+
+Breakpoint = function () extends Native.Breakpoint {
+  super ();
+  Breakpoint.list.push (this);
+};
+Breakpoint.list = new Array ();
+Breakpoint.prototype.addProperty ("active", Native.breakpoint_active_get, Native.breakpoint_active_set);
+
 /*** commands available for debugging ***/
 
 Commands = new Object ();
diff-tree b199888c9610670fe2e47791fe529156f11a3733 (from ee2cce889a2f70f535dec00093090836f13a1efd)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 20:11:25 2007 +0200

    implement Frame.next property

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index f86991f..5e1edac 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -30,8 +30,9 @@ Wrap.prototype.toString = Native.wrap_to
 
 Frame = function () extends Wrap {};
 Frame.prototype = new Wrap ();
-Frame.prototype.addProperty ("name", Native.frame_name_get, null);
 Frame.prototype.addProperty ("code", Native.frame_code_get, null);
+Frame.prototype.addProperty ("name", Native.frame_name_get, null);
+Frame.prototype.addProperty ("next", Native.frame_next_get, null);
 
 /*** commands available for debugging ***/
 
diff --git a/vivified/core/vivi_wrap_as.c b/vivified/core/vivi_wrap_as.c
index 0f4f3e6..c905f34 100644
--- a/vivified/core/vivi_wrap_as.c
+++ b/vivified/core/vivi_wrap_as.c
@@ -86,5 +86,24 @@ vivi_wrap_code_get (SwfdecAsContext *cx,
     SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE);
 }
 
+VIVI_FUNCTION ("frame_next_get", vivi_wrap_next_get)
+void
+vivi_wrap_next_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviWrap *wrap;
+  SwfdecAsObject *obj;
+
+  if (!VIVI_IS_WRAP (this))
+    return;
+  
+  wrap = VIVI_WRAP (this);
+  if (!SWFDEC_IS_AS_FRAME (wrap->wrap))
+    return;
+  
+  obj = SWFDEC_AS_OBJECT (swfdec_as_frame_get_next (SWFDEC_AS_FRAME (wrap->wrap)));
+  if (obj)
+    SWFDEC_AS_VALUE_SET_OBJECT (retval, vivi_wrap_object (VIVI_APPLICATION (cx), obj));
+}
 
 
diff-tree ee2cce889a2f70f535dec00093090836f13a1efd (from f469392f783d10984d4d6dc36ac03d41b3730bec)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 19:46:24 2007 +0200

    don't use parameters as format strings

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 1a311e9..96c23e4 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -169,7 +169,7 @@ swfdec_as_context_abort (SwfdecAsContext
 {
   g_return_if_fail (context);
 
-  SWFDEC_ERROR (reason);
+  SWFDEC_ERROR ("%s", reason);
   context->state = SWFDEC_AS_CONTEXT_ABORTED;
 }
 
diff-tree f469392f783d10984d4d6dc36ac03d41b3730bec (from 52bba717bd060881a2f47b202c129017a86bc955)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 19:46:12 2007 +0200

    in SWFDEC_AS_OBJECT() only reference the object once

diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 54189d8..8da685d 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -104,9 +104,10 @@ struct _SwfdecAsValue {
 #define SWFDEC_AS_VALUE_GET_OBJECT(val) ((val)->value.object)
 #define SWFDEC_AS_VALUE_SET_OBJECT(val,o) G_STMT_START { \
   SwfdecAsValue *__val = (val); \
-  g_assert (o != NULL); \
+  SwfdecAsObject *__o = (o); \
+  g_assert (__o != NULL); \
   (__val)->type = SWFDEC_AS_TYPE_OBJECT; \
-  (__val)->value.object = o; \
+  (__val)->value.object = __o; \
 } G_STMT_END
 
 /* value conversion functions */
diff-tree 52bba717bd060881a2f47b202c129017a86bc955 (from 85ec6f14038b68f557c37a8ad23095dca8a9af1f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 17:32:59 2007 +0200

    support reset() in breakpoints (hopefully)

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 79b350d..cc1d4c2 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -181,7 +181,8 @@ vivi_application_reset (ViviApplication 
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
-  g_assert (app->loop == NULL); /* FIXME: what do we do if we're inside a breakpoint? */
+  if (app->loop != NULL)
+    g_main_loop_quit (app->loop);
   g_object_unref (app->player);
   app->player = swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app->debugger));
   app->player_inited = FALSE;
@@ -262,42 +263,25 @@ vivi_application_step_forward (gpointer 
   return FALSE;
 }
 
-static void
+void
 vivi_application_check (ViviApplication *app)
 {
-  gboolean is_playing, is_breakpoint;
+  gboolean is_breakpoint;
 
   /* if we're inside some script code, don't do anything */
   if (swfdec_as_context_get_frame (SWFDEC_AS_CONTEXT (app)))
     return;
 
-  is_playing = swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (app->player));
   is_breakpoint = app->loop != NULL;
   swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (app));
 
   switch (app->playback_state) {
     case VIVI_APPLICATION_EXITING:
-      if (is_playing)
-	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
-      if (is_breakpoint)
-	g_main_loop_quit (app->loop);
-      break;
     case VIVI_APPLICATION_STOPPED:
-      if (is_playing)
-	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
-      break;
     case VIVI_APPLICATION_PLAYING:
-      if (!is_playing)
-	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), TRUE);
-      if (is_breakpoint)
-	g_main_loop_quit (app->loop);
       break;
     case VIVI_APPLICATION_STEPPING:
-      if (is_playing)
-	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
-      if (is_breakpoint) {
-	g_main_loop_quit (app->loop);
-      } else {
+      if (!is_breakpoint) {
 	/* FIXME: sanely handle this */
 	g_idle_add_full (-100, vivi_application_step_forward, app, NULL);
       }
@@ -306,6 +290,14 @@ vivi_application_check (ViviApplication 
       g_assert_not_reached ();
       break;
   }
+
+  /* only play when not in breakpoints and only when really playing */
+  swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), !is_breakpoint && 
+      app->playback_state == VIVI_APPLICATION_PLAYING);
+
+  /* leave breakpoint unless stopped */
+  if (is_breakpoint && app->playback_state != VIVI_APPLICATION_STOPPED)
+    g_main_loop_quit (app->loop);
 }
 
 void
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 7f66487..33694bf 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -75,6 +75,8 @@ GType			vivi_application_get_type   	(vo
 
 ViviApplication *	vivi_application_new		(void);
 
+void			vivi_application_check		(ViviApplication *	app);
+
 void			vivi_application_send_message	(ViviApplication *	app,
 							 ViviMessageType	type,
 							 const char *		format, 
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index 915dff0..53ea0ea 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -58,6 +58,7 @@ static void
 vivi_debugger_break (ViviDebugger *debugger)
 {
   ViviApplication *app = debugger->app;
+  SwfdecPlayer *player = app->player;
 
   g_assert (app);
   if (app->playback_state == VIVI_APPLICATION_EXITING)
@@ -67,19 +68,23 @@ vivi_debugger_break (ViviDebugger *debug
     if (app->playback_count > 0)
       return;
   }
-  swfdec_player_unlock_soft (app->player);
+  swfdec_player_unlock_soft (player);
 
   app->playback_state = 0;
   app->playback_count = 0;
   app->loop = g_main_loop_new (NULL, FALSE);
   g_object_notify (G_OBJECT (app), "interrupted");
+  vivi_application_check (app);
 
+  g_print (">>>\n");
   g_main_loop_run (app->loop);
+  g_print ("<<<\n");
 
   g_main_loop_unref (app->loop);
   app->loop = NULL;
   g_object_notify (G_OBJECT (app), "interrupted");
-  swfdec_player_lock_soft (app->player);
+  vivi_application_check (app);
+  swfdec_player_lock_soft (player);
 }
 
 static void
diff-tree 85ec6f14038b68f557c37a8ad23095dca8a9af1f (from f848345a3768d3029d5135db1556f9f0f8a7061f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 17:32:31 2007 +0200

    add a reference to the player when locking

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 2bb0264..e9a8010 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1060,6 +1060,7 @@ swfdec_player_lock (SwfdecPlayer *player
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
   g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);
 
+  g_object_ref (player);
   swfdec_player_lock_soft (player);
 }
 
@@ -1083,6 +1084,7 @@ swfdec_player_unlock (SwfdecPlayer *play
 
   swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (player));
   swfdec_player_unlock_soft (player);
+  g_object_unref (player);
 }
 
 static gboolean
diff-tree f848345a3768d3029d5135db1556f9f0f8a7061f (from 71440c71a145eb098445126cf0031f4a700df56f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 15:42:10 2007 +0200

    add the possibility to set variables to be used with the player
    
    Variables can be specified as second command line argument now.

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 3a2de0a..79b350d 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -35,6 +35,7 @@ enum {
 enum {
   PROP_0,
   PROP_FILENAME,
+  PROP_VARIABLES,
   PROP_PLAYER,
   PROP_INTERRUPTED,
   PROP_QUIT
@@ -53,6 +54,9 @@ vivi_application_get_property (GObject *
     case PROP_FILENAME:
       g_value_set_string (value, app->filename);
       break;
+    case PROP_VARIABLES:
+      g_value_set_string (value, app->variables);
+      break;
     case PROP_PLAYER:
       g_value_set_object (value, app->player);
       break;
@@ -78,6 +82,9 @@ vivi_application_set_property (GObject *
     case PROP_FILENAME:
       vivi_application_set_filename (app, g_value_get_string (value));
       break;
+    case PROP_VARIABLES:
+      vivi_application_set_variables (app, g_value_get_string (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -110,6 +117,9 @@ vivi_application_class_init (ViviApplica
   g_object_class_install_property (object_class, PROP_FILENAME,
       g_param_spec_string ("filename", "filename", "name of file to play",
 	  NULL, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_FILENAME,
+      g_param_spec_string ("variables", "variables", "variables to pass to the file",
+	  NULL, G_PARAM_READWRITE));
   g_object_class_install_property (object_class, PROP_PLAYER,
       g_param_spec_object ("player", "player", "Flash player in use",
 	  SWFDEC_TYPE_PLAYER, G_PARAM_READABLE));
@@ -162,7 +172,7 @@ vivi_application_init_player (ViviApplic
   }
 
   loader = swfdec_file_loader_new (app->filename);
-  swfdec_player_set_loader (app->player, loader);
+  swfdec_player_set_loader_with_variables (app->player, loader, app->variables);
   app->player_inited = TRUE;
 }
 
@@ -198,6 +208,24 @@ vivi_application_get_filename (ViviAppli
   return app->filename;
 }
 
+void
+vivi_application_set_variables (ViviApplication *app, const char *variables)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  g_free (app->variables);
+  app->variables = g_strdup (variables);
+  g_object_notify (G_OBJECT (app), "variables");
+}
+
+const char *
+vivi_application_get_variables (ViviApplication *app)
+{
+  g_return_val_if_fail (VIVI_IS_APPLICATION (app), NULL);
+
+  return app->variables;
+}
+
 SwfdecPlayer *
 vivi_application_get_player (ViviApplication *app)
 {
@@ -294,7 +322,7 @@ vivi_application_execute (ViviApplicatio
   vivi_application_input (app, "%s", command);
   script = vivi_ming_compile (command, &error);
   if (script == NULL) {
-    vivi_application_error (app, error);
+    vivi_application_error (app, "%s", error);
     g_free (error);
     return;
   }
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 812b304..7f66487 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -55,6 +55,7 @@ struct _ViviApplication
   SwfdecAsContext	context;
 
   char *		filename;	/* name of the file we play back or NULL if none set yet */
+  char *		variables;	/* variables to pass to player or NULL if none set */
   SwfdecPlayer *	player;		/* the current player */
   ViviDebugger *	debugger;	/* the debugger used in player */
   gboolean		player_inited;	/* if the player is inited already */
@@ -88,6 +89,9 @@ void			vivi_application_send_message	(Vi
 void			vivi_application_set_filename	(ViviApplication *	app,
 							 const char *		filename);
 const char *		vivi_application_get_filename	(ViviApplication *	app);
+void			vivi_application_set_variables	(ViviApplication *	app,
+							 const char *		filename);
+const char *		vivi_application_get_variables	(ViviApplication *	app);
 SwfdecPlayer *	      	vivi_application_get_player	(ViviApplication *	app);
 gboolean	      	vivi_application_get_interrupted(ViviApplication *	app);
 gboolean	      	vivi_application_is_quit	(ViviApplication *	app);
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 3f96021..df123a9 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -48,13 +48,14 @@ delete_event (GtkWidget *widget, GdkEven
 }
 
 static void
-setup (const char *filename)
+setup (const char *filename, const char *variables)
 {
   GtkWidget *window, *box, *widget;
   ViviApplication *app;
 
   app = vivi_application_new ();
   vivi_application_set_filename (app, filename);
+  vivi_application_set_variables (app, variables);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   g_signal_connect_swapped (app, "notify::quit", G_CALLBACK (gtk_widget_destroy), window);
   box = vivi_vdock_new ();
@@ -75,12 +76,12 @@ main (int argc, char **argv)
 {
   gtk_init (&argc, &argv);
 
-  if (argc != 2) {
-    g_print ("usage: %s FILE\n", argv[0]);
+  if (argc < 2) {
+    g_print ("usage: %s FILE [VARIABLES]\n", argv[0]);
     return 0;
   }
 
-  setup (argv[1]);
+  setup (argv[1], argc > 2 ? argv[2] : NULL);
   gtk_main ();
 
   return 0;
diff-tree 71440c71a145eb098445126cf0031f4a700df56f (from 5e6e05624c6c7cd7ecc9d8ea90a5ad4b4b04c542)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 14:48:32 2007 +0200

    add Frame.code property

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 51ce35d..f86991f 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -31,6 +31,7 @@ Wrap.prototype.toString = Native.wrap_to
 Frame = function () extends Wrap {};
 Frame.prototype = new Wrap ();
 Frame.prototype.addProperty ("name", Native.frame_name_get, null);
+Frame.prototype.addProperty ("code", Native.frame_code_get, null);
 
 /*** commands available for debugging ***/
 
diff --git a/vivified/core/vivi_wrap_as.c b/vivified/core/vivi_wrap_as.c
index cf9e4a8..0f4f3e6 100644
--- a/vivified/core/vivi_wrap_as.c
+++ b/vivified/core/vivi_wrap_as.c
@@ -65,4 +65,26 @@ vivi_wrap_name_get (SwfdecAsContext *cx,
   SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_get_string (cx, s));
 }
 
+VIVI_FUNCTION ("frame_code_get", vivi_wrap_code_get)
+void
+vivi_wrap_code_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviWrap *wrap;
+  SwfdecScript *script;
+
+  if (!VIVI_IS_WRAP (this))
+    return;
+  
+  wrap = VIVI_WRAP (this);
+  if (!SWFDEC_IS_AS_FRAME (wrap->wrap))
+    return;
+  
+  script = swfdec_as_frame_get_script (SWFDEC_AS_FRAME (wrap->wrap));
+  /* FIXME: wrap scripts */
+  if (script)
+    SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE);
+}
+
+
 
diff-tree 5e6e05624c6c7cd7ecc9d8ea90a5ad4b4b04c542 (from ecd3760b86ee8bc6d839b80303264d396131b60b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 14:48:14 2007 +0200

    don't use the input string as a format string

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 624c911..3a2de0a 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -291,7 +291,7 @@ vivi_application_execute (ViviApplicatio
   g_return_if_fail (VIVI_IS_APPLICATION (app));
   g_return_if_fail (command != NULL);
 
-  vivi_application_input (app, command);
+  vivi_application_input (app, "%s", command);
   script = vivi_ming_compile (command, &error);
   if (script == NULL) {
     vivi_application_error (app, error);
diff-tree ecd3760b86ee8bc6d839b80303264d396131b60b (from 32955946fda66c445e1e3de12629890a8e2f354a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 14:47:25 2007 +0200

    add some printf warning flags

diff --git a/configure.ac b/configure.ac
index 1303884..63a0bde 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ dnl if we support them, we set them unco
 AS_COMPILER_FLAG(-Wall, GLOBAL_CFLAGS="-Wall", GLOBAL_CFLAGS="")
 dnl I want this but stupid headers don't let me
 dnl AS_COMPILER_FLAG(-Wshadow, GLOBAL_CFLAGS="$GLOBAL_CFLAGS -Wshadow")
-AS_COMPILER_FLAG(-Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wold-style-definition -Wdeclaration-after-statement -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Winline, GLOBAL_CFLAGS="$GLOBAL_CFLAGS -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wold-style-definition -Wdeclaration-after-statement -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Winline")
+AS_COMPILER_FLAG(-Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wold-style-definition -Wdeclaration-after-statement -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wformat-nonliteral -Wformat-security, GLOBAL_CFLAGS="$GLOBAL_CFLAGS -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wold-style-definition -Wdeclaration-after-statement -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wformat-nonliteral -Wformat-security")
 dnl if we're in nano >= 1, add -Werror if supported
 if test x$SWFDEC_CVS = xyes ; then
   AS_COMPILER_FLAG(-Werror, GLOBAL_CFLAGS="$GLOBAL_CFLAGS -Werror")
diff-tree 32955946fda66c445e1e3de12629890a8e2f354a (from c7d4ebd5b036b286a32706e74315c376553fb36d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 14:00:15 2007 +0200

    add swfdec_as_frame_get_script ()

diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index cf0e5b1..c5f9076 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -374,6 +374,7 @@ SWFDEC_TYPE_AS_NATIVE_FUNCTION
 SwfdecAsFrame
 swfdec_as_frame_get_next
 swfdec_as_frame_get_function_name
+swfdec_as_frame_get_script
 SwfdecAsStackIterator
 swfdec_as_stack_iterator_init
 swfdec_as_stack_iterator_init_arguments
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 0721022..17f88cb 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -760,3 +760,20 @@ swfdec_as_frame_get_function_name (Swfde
   g_assert (frame->function_name);
   return frame->function_name;
 }
+
+/**
+ * swfdec_as_frame_get_script:
+ * @frame: a #SwfdecAsFrame
+ *
+ * Gets the script associated with the given @frame. If the frame references
+ * a native function, there will be no script and this function returns %NULL.
+ *
+ * Returns: The script executed by this frame or %NULL
+ **/
+SwfdecScript *
+swfdec_as_frame_get_script (SwfdecAsFrame *frame)
+{
+  g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
+
+  return frame->script;
+}
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 183f55d..8157858 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -48,6 +48,7 @@ GType		swfdec_as_frame_get_type	(void);
 
 SwfdecAsFrame *	swfdec_as_frame_get_next	(SwfdecAsFrame *		frame);
 const char *	swfdec_as_frame_get_function_name (SwfdecAsFrame *		frame);
+SwfdecScript *	swfdec_as_frame_get_script	(SwfdecAsFrame *		frame);
 
 SwfdecAsValue *	swfdec_as_stack_iterator_init	(SwfdecAsStackIterator *	iter,
 						 SwfdecAsFrame *		frame);
diff-tree c7d4ebd5b036b286a32706e74315c376553fb36d (from 6e6a99cc02d9399a08398cdcffe0599bc724fe1a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 13:34:44 2007 +0200

    add ability to deactivate breakpoints
    
    use this to implement a "delete" command

diff --git a/vivified/core/vivi_breakpoint.c b/vivified/core/vivi_breakpoint.c
index 94922d4..506ee08 100644
--- a/vivified/core/vivi_breakpoint.c
+++ b/vivified/core/vivi_breakpoint.c
@@ -87,6 +87,31 @@ vivi_breakpoint_find_event (const char *
 }
 
 static void
+vivi_breakpoint_add (ViviBreakpoint *breakpoint, guint i)
+{
+  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
+
+  g_assert (i != 0);
+  if (breakpoint->active) {
+    breakpoint->handlers[i] = g_signal_connect (debugger, events[i].signal,
+	events[i].handler, breakpoint);
+  } else {
+    breakpoint->handlers[i] = 1;
+  }
+}
+
+static void
+vivi_breakpoint_remove (ViviBreakpoint *breakpoint, guint i)
+{
+  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
+
+  g_assert (i != 0);
+  if (breakpoint->active)
+    g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
+  breakpoint->handlers[i] = 0;
+}
+
+static void
 vivi_breakpoint_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val)
 {
   guint i;
@@ -94,17 +119,13 @@ vivi_breakpoint_set (SwfdecAsObject *obj
   i = vivi_breakpoint_find_event (variable);
   if (i) {
     ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
-    ViviDebugger *debugger = VIVI_APPLICATION (object->context)->debugger;
     if (SWFDEC_AS_VALUE_IS_OBJECT (val) &&
 	SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (val))) {
       if (!breakpoint->handlers[i])
-	breakpoint->handlers[i] = g_signal_connect (debugger, events[i].signal,
-	    events[i].handler, object);
+	vivi_breakpoint_add (breakpoint, i);
     } else {
-      if (breakpoint->handlers[i]) {
-	g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
-	breakpoint->handlers[i] = 0;
-      }
+      if (breakpoint->handlers[i])
+	vivi_breakpoint_remove (breakpoint, i);
     }
   }
   SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val);
@@ -117,11 +138,8 @@ vivi_breakpoint_delete (SwfdecAsObject *
   guint i;
 
   i = vivi_breakpoint_find_event (variable);
-  if (i && breakpoint->handlers[i]) {
-    ViviDebugger *debugger = VIVI_APPLICATION (object->context)->debugger;
-    g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
-    breakpoint->handlers[i] = 0;
-  }
+  if (i && breakpoint->handlers[i])
+    vivi_breakpoint_remove (breakpoint, i);
 
   return SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
 }
@@ -130,13 +148,9 @@ static void
 vivi_breakpoint_dispose (GObject *object)
 {
   ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
-  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
-  guint i;
 
-  for (i = 0; i < G_N_ELEMENTS (events); i++) {
-    if (breakpoint->handlers[i])
-      g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
-  }
+  vivi_breakpoint_set_active (breakpoint, FALSE);
+
   G_OBJECT_CLASS (vivi_breakpoint_parent_class)->dispose (object);
 }
 
@@ -155,7 +169,52 @@ vivi_breakpoint_class_init (ViviBreakpoi
 static void
 vivi_breakpoint_init (ViviBreakpoint *breakpoint)
 {
+  breakpoint->active = TRUE;
+}
+
+void
+vivi_breakpoint_set_active (ViviBreakpoint *breakpoint, gboolean active)
+{
+  guint i;
+
+  g_return_if_fail (VIVI_IS_BREAKPOINT (breakpoint));
+
+  g_print ("active = %d", active);
+  if (breakpoint->active == active)
+    return;
+  breakpoint->active = !breakpoint->active;
+  for (i = 1; i < G_N_ELEMENTS (events); i++) {
+    if (breakpoint->handlers[i] == 0)
+      continue;
+    /* FIXME: this is hacky */
+    breakpoint->active = !breakpoint->active;
+    vivi_breakpoint_remove (breakpoint, i);
+    breakpoint->active = !breakpoint->active;
+    vivi_breakpoint_add (breakpoint, i);
+  }
 }
 
 /*** AS CODE ***/
 
+VIVI_FUNCTION ("breakpoint_active_get", vivi_breakpoint_as_get_active)
+void
+vivi_breakpoint_as_get_active (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  if (!VIVI_IS_BREAKPOINT (this))
+    return;
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (retval, VIVI_BREAKPOINT (this)->active);
+}
+
+VIVI_FUNCTION ("breakpoint_active_set", vivi_breakpoint_as_set_active)
+void
+vivi_breakpoint_as_set_active (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  if (!VIVI_IS_BREAKPOINT (this) ||
+      argc == 0)
+    return;
+  vivi_breakpoint_set_active (VIVI_BREAKPOINT (this), swfdec_as_value_to_boolean (cx, &argv[0]));
+}
+
diff --git a/vivified/core/vivi_breakpoint.h b/vivified/core/vivi_breakpoint.h
index 5925ec9..87b2220 100644
--- a/vivified/core/vivi_breakpoint.h
+++ b/vivified/core/vivi_breakpoint.h
@@ -40,6 +40,7 @@ struct _ViviBreakpoint
 {
   SwfdecAsObject	object;
 
+  gboolean		active;		/* only active breakpoints receive events */
   gulong		handlers[4];	/* handlers for every signal of the debugger or 0 */
 };
 
@@ -50,6 +51,8 @@ struct _ViviBreakpointClass
 
 GType			vivi_breakpoint_get_type   	(void);
 
+void			vivi_breakpoint_set_active	(ViviBreakpoint *	breakpoint,
+							 gboolean		active);
 
 G_END_DECLS
 #endif
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 430110d..51ce35d 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -22,6 +22,7 @@ Breakpoint = function () extends Native.
   Breakpoint.list.push (this);
 };
 Breakpoint.list = new Array ();
+Breakpoint.prototype.addProperty ("active", Native.breakpoint_active_get, Native.breakpoint_active_set);
 
 Wrap = function () {};
 Wrap.prototype = {};
@@ -74,3 +75,14 @@ Commands.list = function () {
     Commands.print (i + ": " + a[i]);
   }
 };
+Commands.del = function (id) {
+  var a = Breakpoint.list;
+  if (id == undefined) {
+    while (a[0])
+      Commands.del (0);
+  }
+  var b = a[id];
+  a.splice (id, 1);
+  b.active = false;
+};
+Commands.delete = Commands.del;
diff-tree 6e6a99cc02d9399a08398cdcffe0599bc724fe1a (from 380e971ad1cbc7ebf9e8bea743d47cf70072d6c7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 13:09:31 2007 +0200

    debugging g_print removal #3423

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 803d82f..ee112db 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -897,7 +897,6 @@ swfdec_as_object_create (SwfdecAsFunctio
       if (native->construct_size) {
 	type = native->construct_type;
 	size = native->construct_size;
-	g_print ("type is %s\n", g_type_name (type));
 	break;
       }
     }
@@ -908,7 +907,6 @@ swfdec_as_object_create (SwfdecAsFunctio
       if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
 	cur = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val);
 	if (SWFDEC_IS_AS_FUNCTION (cur)) {
-	  g_print ("found one!\n");
 	  continue;
 	}
       }
diff-tree 380e971ad1cbc7ebf9e8bea743d47cf70072d6c7 (from 670335c62948358e9126c86478752e20eee5d20f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 13:09:05 2007 +0200

    don't mess with the prototype anymore, swfdec handles it now

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 6c8640b..430110d 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -22,7 +22,6 @@ Breakpoint = function () extends Native.
   Breakpoint.list.push (this);
 };
 Breakpoint.list = new Array ();
-Breakpoint.prototype = new Object ();
 
 Wrap = function () {};
 Wrap.prototype = {};
diff-tree 670335c62948358e9126c86478752e20eee5d20f (from ab94c6f2d440cd05cf4363a717769aa7886a7587)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 13:08:44 2007 +0200

    walk the inheritance chain to find an objects type

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index b5dcd25..803d82f 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -883,6 +883,7 @@ swfdec_as_object_create (SwfdecAsFunctio
   SwfdecAsObject *new;
   SwfdecAsContext *context;
   SwfdecAsFunction *cur;
+  SwfdecAsValue val;
   guint size;
   GType type = 0;
 
@@ -890,29 +891,30 @@ swfdec_as_object_create (SwfdecAsFunctio
 
   context = SWFDEC_AS_OBJECT (fun)->context;
   cur = fun;
-  while (type == 0 && cur != NULL) {
+  do {
     if (SWFDEC_IS_AS_NATIVE_FUNCTION (cur)) {
       SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (cur);
       if (native->construct_size) {
 	type = native->construct_type;
 	size = native->construct_size;
+	g_print ("type is %s\n", g_type_name (type));
 	break;
       }
     }
-#if 0
-    This doesn't work. It's supposed to figure out the last native object in the inheritance chain.
-    swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), SWFDEC_AS_STR___constructor__, &val);
+    swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), SWFDEC_AS_STR_prototype, &val);
     if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
-      cur = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val);
-      if (!SWFDEC_IS_AS_FUNCTION (cur))
-	cur = NULL;
-    } else {
-      cur = NULL;
+      SwfdecAsObject *proto = SWFDEC_AS_VALUE_GET_OBJECT (&val);
+      swfdec_as_object_get_variable (proto, SWFDEC_AS_STR___constructor__, &val);
+      if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
+	cur = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val);
+	if (SWFDEC_IS_AS_FUNCTION (cur)) {
+	  g_print ("found one!\n");
+	  continue;
+	}
+      }
     }
-#else
     cur = NULL;
-#endif
-  }
+  } while (type == 0 && cur != NULL);
   if (type == 0) {
     type = SWFDEC_TYPE_AS_OBJECT;
     size = sizeof (SwfdecAsObject);
diff-tree ab94c6f2d440cd05cf4363a717769aa7886a7587 (from 9792ce9e8ae0793131e59008f15c2d47e69dd2b5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 13:08:17 2007 +0200

    breakpoints are objects

diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
index 4c2608c..686862a 100644
--- a/vivified/core/vivi_function.c
+++ b/vivified/core/vivi_function.c
@@ -76,6 +76,12 @@ vivi_function_init_context (ViviApplicat
     0, functions[i].fun, 0);
   swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (fun),
       VIVI_TYPE_BREAKPOINT);
+  obj = swfdec_as_object_new (cx);
+  if (obj == NULL)
+    return;
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, obj);
+  swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (fun), 
+      swfdec_as_context_get_string (cx, "prototype"), &val);
 
   g_signal_connect (app, "message", G_CALLBACK (vivi_function_not_reached), NULL);
   vivi_application_execute (app, vivi_initialize);
diff-tree 9792ce9e8ae0793131e59008f15c2d47e69dd2b5 (from 567ee69db12396392b896a06868c6c27edcc6a90)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:54:24 2007 +0200

    add a list command to list all breakpoints

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index a754cb2..6c8640b 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -17,7 +17,12 @@
  * Boston, MA  02110-1301  USA
  */
 
-Breakpoint = Native.Breakpoint;
+Breakpoint = function () extends Native.Breakpoint {
+  super ();
+  Breakpoint.list.push (this);
+};
+Breakpoint.list = new Array ();
+Breakpoint.prototype = new Object ();
 
 Wrap = function () {};
 Wrap.prototype = {};
@@ -59,5 +64,14 @@ Commands.add = function (name) {
     Commands.print ("  " + frame);
     return true;
   };
+  ret.toString = function () {
+    return "function call " + name;
+  };
+};
+Commands.list = function () {
+  var a = Breakpoint.list;
+  var i;
+  for (i = 0; i < a.length; i++) {
+    Commands.print (i + ": " + a[i]);
+  }
 };
-
diff-tree 567ee69db12396392b896a06868c6c27edcc6a90 (from 2101df59fadb5037503673f1ce712ecb1a3dff19)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:35:25 2007 +0200

    new "add" function to add breakpoints

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 281faba..a754cb2 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -44,3 +44,20 @@ Commands.restart = function () {
   Commands.run ();
 };
 Commands.quit = Native.quit;
+/* can't use "break" as a function name, it's a keyword in JS */
+Commands.add = function (name) {
+  if (name == undefined) {
+    Commands.error ("add command requires a function name");
+    return undefined;
+  }
+  var ret = new Breakpoint ();
+  ret.onStartFrame = function (frame) {
+    if (frame.name != name)
+      return false;
+
+    Commands.print ("Breakpoint: function " + name + " called");
+    Commands.print ("  " + frame);
+    return true;
+  };
+};
+
diff-tree 2101df59fadb5037503673f1ce712ecb1a3dff19 (from 97c4c386c1da957a75e2b41fecac9a2253515211)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:33:01 2007 +0200

    restructure and add error function

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 4852d82..281faba 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -17,8 +17,21 @@
  * Boston, MA  02110-1301  USA
  */
 
+Breakpoint = Native.Breakpoint;
+
+Wrap = function () {};
+Wrap.prototype = {};
+Wrap.prototype.toString = Native.wrap_toString;
+
+Frame = function () extends Wrap {};
+Frame.prototype = new Wrap ();
+Frame.prototype.addProperty ("name", Native.frame_name_get, null);
+
+/*** commands available for debugging ***/
+
 Commands = new Object ();
 Commands.print = Native.print;
+Commands.error = Native.error;
 Commands.r = Native.run;
 Commands.run = Native.run;
 Commands.halt = Native.stop;
@@ -31,14 +44,3 @@ Commands.restart = function () {
   Commands.run ();
 };
 Commands.quit = Native.quit;
-
-Breakpoint = Native.Breakpoint;
-
-Wrap = function () {};
-Wrap.prototype = {};
-Wrap.prototype.toString = Native.wrap_toString;
-
-Frame = function () extends Wrap {};
-Frame.prototype = new Wrap ();
-Frame.prototype.addProperty ("name", Native.frame_name_get, null);
-
diff-tree 97c4c386c1da957a75e2b41fecac9a2253515211 (from ece89b8a8842215f3e1e68a09181e1b6ebadf8e3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:32:20 2007 +0200

    clean up the vdock, so it properly shuts down

diff --git a/vivified/dock/vivi_vdock.c b/vivified/dock/vivi_vdock.c
index d37d563..f79cb2d 100644
--- a/vivified/dock/vivi_vdock.c
+++ b/vivified/dock/vivi_vdock.c
@@ -28,14 +28,14 @@
 G_DEFINE_TYPE (ViviVDock, vivi_vdock, GTK_TYPE_BIN)
 
 static void
-vivi_vdock_dispose (GObject *object)
+vivi_vdock_destroy (GtkObject *object)
 {
   ViviVDock *vdock = VIVI_VDOCK (object);
 
+  GTK_OBJECT_CLASS (vivi_vdock_parent_class)->destroy (object);
+
   g_list_free (vdock->docklets);
   vdock->docklets = NULL;
-
-  G_OBJECT_CLASS (vivi_vdock_parent_class)->dispose (object);
 }
 
 static void
@@ -62,18 +62,20 @@ vivi_vdock_size_allocate (GtkWidget *wid
   }
 }
 
-static void
-vivi_vdock_add (GtkContainer *container, GtkWidget *widget)
+void
+vivi_vdock_add (ViviVDock *vdock, GtkWidget *widget)
 {
-  ViviVDock *vdock = VIVI_VDOCK (container);
   GtkWidget *docker;
   
+  g_return_if_fail (VIVI_IS_VDOCK (vdock));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
   docker = vivi_docker_new (VIVI_DOCKLET (widget));
   gtk_widget_show (docker);
 
   g_object_ref (widget);
   if (vdock->docklets == NULL) {
-    GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->add (container, docker);
+    gtk_container_add (GTK_CONTAINER (vdock), docker);
   } else {
     /* docklet is in docker, so we need to use parent */
     GtkWidget *last = gtk_widget_get_parent (vdock->docklets->data);
@@ -81,18 +83,14 @@ vivi_vdock_add (GtkContainer *container,
     GtkWidget *paned;
 
     g_object_ref (last);
-    if (parent == (GtkWidget *) container) {
-      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, last);
-    } else {
-      gtk_container_remove (GTK_CONTAINER (parent), last);
-    }
+    gtk_container_remove (GTK_CONTAINER (parent), last);
     paned = gtk_vpaned_new ();
     gtk_paned_pack1 (GTK_PANED (paned), last, TRUE, FALSE);
     gtk_paned_pack2 (GTK_PANED (paned), docker, TRUE, FALSE);
     g_object_unref (last);
     gtk_widget_show (paned);
-    if (parent == (GtkWidget *) container) {
-      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->add (container, paned);
+    if (parent == (GtkWidget *) vdock) {
+      gtk_container_add (GTK_CONTAINER (vdock), paned);
     } else {
       gtk_paned_pack1 (GTK_PANED (parent), paned, TRUE, FALSE);
     }
@@ -100,18 +98,17 @@ vivi_vdock_add (GtkContainer *container,
   vdock->docklets = g_list_prepend (vdock->docklets, widget);
 }
 
-static void
-vivi_vdock_remove (GtkContainer *container, GtkWidget *widget)
+void
+vivi_vdock_remove (ViviVDock *vdock, GtkWidget *widget)
 {
-  ViviVDock *vdock = VIVI_VDOCK (container);
   GtkWidget *docker, *parent;
 
   g_return_if_fail (g_list_find (vdock->docklets, widget));
 
   docker = gtk_widget_get_parent (widget);
   parent = gtk_widget_get_parent (docker);
-  if (parent == (GtkWidget *) container) {
-    GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, docker);
+  if (parent == (GtkWidget *) vdock) {
+    gtk_container_remove (GTK_CONTAINER (vdock), docker);
   } else {
     GtkWidget *other;
     GtkWidget *paned_parent;
@@ -123,9 +120,9 @@ vivi_vdock_remove (GtkContainer *contain
     g_object_ref (other);
     gtk_container_remove (GTK_CONTAINER (parent), docker);
     gtk_container_remove (GTK_CONTAINER (parent), other);
-    if (paned_parent == (GtkWidget *) container) {
-      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, parent);
-      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, other);
+    if (paned_parent == (GtkWidget *) vdock) {
+      gtk_container_remove (GTK_CONTAINER (vdock), parent);
+      gtk_container_add (GTK_CONTAINER (vdock), other);
     } else {
       gtk_container_remove (GTK_CONTAINER (paned_parent), parent);
       gtk_paned_pack1 (GTK_PANED (parent), other, TRUE, FALSE);
@@ -136,44 +133,16 @@ vivi_vdock_remove (GtkContainer *contain
   g_object_unref (widget);
 }
 
-static GType
-vivi_vdock_child_type (GtkContainer *container)
-{
-  return VIVI_TYPE_DOCKLET;
-}
-
-static void
-vivi_vdock_forall (GtkContainer *container, gboolean include_internals,
-    GtkCallback callback, gpointer callback_data)
-{
-  if (include_internals) {
-    GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->forall (container, include_internals, 
-	callback, callback_data);
-  } else {
-    GList *walk;
-
-    for (walk = VIVI_VDOCK (container)->docklets; walk; walk = walk->next) {
-      callback (walk->data, callback_data);
-    }
-  }
-}
-
 static void
 vivi_vdock_class_init (ViviVDockClass *klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
 
-  object_class->dispose = vivi_vdock_dispose;
+  object_class->destroy = vivi_vdock_destroy;
 
   widget_class->size_request = vivi_vdock_size_request;
   widget_class->size_allocate = vivi_vdock_size_allocate;
-
-  container_class->add = vivi_vdock_add;
-  container_class->remove = vivi_vdock_remove;
-  container_class->child_type = vivi_vdock_child_type;
-  container_class->forall = vivi_vdock_forall;
 }
 
 static void
diff --git a/vivified/dock/vivi_vdock.h b/vivified/dock/vivi_vdock.h
index ec3527f..7b0f61f 100644
--- a/vivified/dock/vivi_vdock.h
+++ b/vivified/dock/vivi_vdock.h
@@ -50,5 +50,11 @@ GType			vivi_vdock_get_type   	(void);
 
 GtkWidget *		vivi_vdock_new		(void);
 
+void			vivi_vdock_add		(ViviVDock *	vdock, 
+						 GtkWidget *	widget);
+void			vivi_vdock_remove	(ViviVDock *	vdock,
+						 GtkWidget *	widget);
+
+
 G_END_DECLS
 #endif
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 399483f..3f96021 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -37,6 +37,16 @@ try_grab_focus (GtkWidget *widget, gpoin
     gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
 }
 
+static gboolean
+delete_event (GtkWidget *widget, GdkEvent *event, ViviApplication *app)
+{
+  if (!vivi_application_is_quit (app)) {
+    vivi_application_quit (app);
+    return TRUE;
+  }
+  return FALSE;
+}
+
 static void
 setup (const char *filename)
 {
@@ -46,15 +56,17 @@ setup (const char *filename)
   app = vivi_application_new ();
   vivi_application_set_filename (app, filename);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  g_signal_connect_swapped (app, "notify::quit", G_CALLBACK (gtk_widget_destroy), window);
   box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
   widget = vivi_player_new (app);
-  gtk_container_add (GTK_CONTAINER (box), widget);
+  vivi_vdock_add (VIVI_VDOCK (box), widget);
   widget = vivi_command_line_new (app);
-  gtk_container_add (GTK_CONTAINER (box), widget);
+  vivi_vdock_add (VIVI_VDOCK (box), widget);
   gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
 
-  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+  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);
 }
 
diff-tree ece89b8a8842215f3e1e68a09181e1b6ebadf8e3 (from 49807e47ac5b6560070a29a2d041df5ae57a2e88)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:31:51 2007 +0200

    listen to the app's interrupted state and disable mouse and keyboard input on breakpoints

diff --git a/vivified/ui/vivi_player.c b/vivified/ui/vivi_player.c
index 657d169..f54a935 100644
--- a/vivified/ui/vivi_player.c
+++ b/vivified/ui/vivi_player.c
@@ -31,6 +31,9 @@ vivi_player_notify_app (ViviApplication 
 {
   if (g_str_equal (pspec->name, "player")) {
     swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
+  } else if (g_str_equal (pspec->name, "interrupted")) {
+    swfdec_gtk_widget_set_interactive (SWFDEC_GTK_WIDGET (player->player), 
+	!vivi_application_get_interrupted (app));
   }
 }
 
diff-tree 49807e47ac5b6560070a29a2d041df5ae57a2e88 (from dfa2a625eb1c2f036a30220c4606a8c010786272)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:31:10 2007 +0200

    notify when the application is interrupted

diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index 44149cc..915dff0 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -72,11 +72,13 @@ vivi_debugger_break (ViviDebugger *debug
   app->playback_state = 0;
   app->playback_count = 0;
   app->loop = g_main_loop_new (NULL, FALSE);
+  g_object_notify (G_OBJECT (app), "interrupted");
 
   g_main_loop_run (app->loop);
 
   g_main_loop_unref (app->loop);
   app->loop = NULL;
+  g_object_notify (G_OBJECT (app), "interrupted");
   swfdec_player_lock_soft (app->player);
 }
 
diff-tree dfa2a625eb1c2f036a30220c4606a8c010786272 (from af9936023a852946d0c23048d7d3195b757a7cdb)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 12:30:45 2007 +0200

    add "interrupted" and "quit" property
    
    ALso improve quitting to work as expected

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index e8f489f..624c911 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -35,7 +35,9 @@ enum {
 enum {
   PROP_0,
   PROP_FILENAME,
-  PROP_PLAYER
+  PROP_PLAYER,
+  PROP_INTERRUPTED,
+  PROP_QUIT
 };
 
 G_DEFINE_TYPE (ViviApplication, vivi_application, SWFDEC_TYPE_AS_CONTEXT)
@@ -54,6 +56,12 @@ vivi_application_get_property (GObject *
     case PROP_PLAYER:
       g_value_set_object (value, app->player);
       break;
+    case PROP_INTERRUPTED:
+      g_value_set_boolean (value, app->loop != NULL);
+      break;
+    case PROP_QUIT:
+      g_value_set_boolean (value, app->playback_state == VIVI_APPLICATION_EXITING);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
       break;
@@ -81,6 +89,9 @@ vivi_application_dispose (GObject *objec
 {
   ViviApplication *app = VIVI_APPLICATION (object);
 
+  if (app->playback_state != VIVI_APPLICATION_EXITING)
+    vivi_application_quit (app);
+
   g_object_unref (app->player);
   g_hash_table_destroy (app->wraps);
 
@@ -102,6 +113,12 @@ vivi_application_class_init (ViviApplica
   g_object_class_install_property (object_class, PROP_PLAYER,
       g_param_spec_object ("player", "player", "Flash player in use",
 	  SWFDEC_TYPE_PLAYER, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_INTERRUPTED,
+      g_param_spec_boolean ("interrupted", "interrupted", "TRUE if handling a breakpoint",
+	  FALSE, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_QUIT,
+      g_param_spec_boolean ("quit", "quit", "TRUE if application has been quit (no breakpoints will happen)",
+	  FALSE, G_PARAM_READABLE));
 
   signals[MESSAGE] = g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT_POINTER, /* FIXME */
@@ -189,6 +206,22 @@ vivi_application_get_player (ViviApplica
   return app->player;
 }
 
+gboolean
+vivi_application_get_interrupted (ViviApplication *app)
+{
+  g_return_val_if_fail (VIVI_IS_APPLICATION (app), FALSE);
+
+  return app->loop != NULL;
+}
+
+gboolean
+vivi_application_is_quit (ViviApplication *app)
+{
+  g_return_val_if_fail (VIVI_IS_APPLICATION (app), FALSE);
+
+  return app->playback_state == VIVI_APPLICATION_EXITING;
+}
+
 static gboolean
 vivi_application_step_forward (gpointer appp)
 {
@@ -204,9 +237,14 @@ vivi_application_step_forward (gpointer 
 static void
 vivi_application_check (ViviApplication *app)
 {
-  gboolean is_playing = swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (app->player));
-  gboolean is_breakpoint = app->loop != NULL;
+  gboolean is_playing, is_breakpoint;
 
+  /* if we're inside some script code, don't do anything */
+  if (swfdec_as_context_get_frame (SWFDEC_AS_CONTEXT (app)))
+    return;
+
+  is_playing = swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (app->player));
+  is_breakpoint = app->loop != NULL;
   swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (app));
 
   switch (app->playback_state) {
@@ -293,8 +331,11 @@ vivi_application_play (ViviApplication *
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
+  if (app->playback_state == VIVI_APPLICATION_EXITING)
+    return;
   app->playback_state = VIVI_APPLICATION_PLAYING;
   app->playback_count = 1;
+  vivi_application_check (app);
 }
 
 void
@@ -302,8 +343,11 @@ vivi_application_stop (ViviApplication *
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
+  if (app->playback_state == VIVI_APPLICATION_EXITING)
+    return;
   app->playback_state = VIVI_APPLICATION_STOPPED;
   app->playback_count = 0;
+  vivi_application_check (app);
 }
 
 void
@@ -311,8 +355,11 @@ vivi_application_step (ViviApplication *
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
+  if (app->playback_state == VIVI_APPLICATION_EXITING)
+    return;
   app->playback_state = VIVI_APPLICATION_STEPPING;
   app->playback_count = n_times;
+  vivi_application_check (app);
 }
 
 void
@@ -320,8 +367,11 @@ vivi_application_quit (ViviApplication *
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
+  if (app->playback_state == VIVI_APPLICATION_EXITING)
+    return;
   app->playback_state = VIVI_APPLICATION_EXITING;
   app->playback_count = 1;
-  gtk_main_quit ();
+  g_object_notify (G_OBJECT (app), "quit");
+  vivi_application_check (app);
 }
 
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 2636453..812b304 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -89,6 +89,8 @@ void			vivi_application_set_filename	(Vi
 							 const char *		filename);
 const char *		vivi_application_get_filename	(ViviApplication *	app);
 SwfdecPlayer *	      	vivi_application_get_player	(ViviApplication *	app);
+gboolean	      	vivi_application_get_interrupted(ViviApplication *	app);
+gboolean	      	vivi_application_is_quit	(ViviApplication *	app);
 
 void			vivi_application_init_player	(ViviApplication *	app);
 void			vivi_application_reset		(ViviApplication *	app);
diff-tree af9936023a852946d0c23048d7d3195b757a7cdb (from 400039ceb439cbeb5938dac445ca5995eb0fce9d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 16 09:32:39 2007 +0200

    add an error function for printing errors

diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index a637428..6e2c011 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -89,6 +89,21 @@ vivi_application_as_print (SwfdecAsConte
   vivi_application_output (app, "%s", s);
 }
 
+VIVI_FUNCTION ("error", vivi_application_as_error)
+void
+vivi_application_as_error (SwfdecAsContext *cx, SwfdecAsObject *this, 
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  const char *s;
+
+  if (argc == 0)
+    return;
+
+  s = swfdec_as_value_to_string (cx, &argv[0]);
+  vivi_application_error (app, "%s", s);
+}
+
 VIVI_FUNCTION ("quit", vivi_application_as_quit)
 void
 vivi_application_as_quit (SwfdecAsContext *cx, SwfdecAsObject *this, 
diff-tree 400039ceb439cbeb5938dac445ca5995eb0fce9d (from parents)
Merge: 82cbf15d290ca8584505fd0c1970fa976de545dc bf81efebf34c71944530945a70c24532de6ea111
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 23:17:16 2007 +0200

    Merge branch 'master' into vivi

diff-tree 82cbf15d290ca8584505fd0c1970fa976de545dc (from a3c5a9238df3924961d13599cbdad970f79ddede)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 12:50:18 2007 +0200

    get rid of debugging prints

diff --git a/vivified/core/vivi_wrap_as.c b/vivified/core/vivi_wrap_as.c
index 9cc9b5d..cf9e4a8 100644
--- a/vivified/core/vivi_wrap_as.c
+++ b/vivified/core/vivi_wrap_as.c
@@ -54,16 +54,13 @@ vivi_wrap_name_get (SwfdecAsContext *cx,
   ViviWrap *wrap;
   const char *s;
 
-  g_print ("1\n");
   if (!VIVI_IS_WRAP (this))
     return;
   
-  g_print ("2\n");
   wrap = VIVI_WRAP (this);
   if (!SWFDEC_IS_AS_FRAME (wrap->wrap))
     return;
   
-  g_print ("3\n");
   s = swfdec_as_frame_get_function_name (SWFDEC_AS_FRAME (wrap->wrap));
   SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_get_string (cx, s));
 }
diff-tree a3c5a9238df3924961d13599cbdad970f79ddede (from e2df3bc346bf44ba07d4a6c62876d1d96279412e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 12:49:48 2007 +0200

    add support for having Frame and Wrap objects

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index e535481..9403543 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -14,7 +14,8 @@ libvivified_core_la_SOURCES = \
 	vivi_initialize.s \
 	vivi_marshal.c \
 	vivi_ming.c \
-	vivi_wrap.c
+	vivi_wrap.c \
+	vivi_wrap_as.c
 
 vivi_initialize.lo: vivi_initialize.s vivi_initialize.as
 	$(LTCCASCOMPILE) -c -o $@ vivi_initialize.s
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index 4d81c45..44149cc 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -88,7 +88,7 @@ vivi_debugger_step (SwfdecAsDebugger *de
   g_signal_emit (debugger, signals[STEP], 0, &retval);
 
   if (!retval) {
-    ViviApplication *app = VIVI_APPLICATION (context);
+    ViviApplication *app = VIVI_DEBUGGER (debugger)->app;
 
     if (app->playback_state == VIVI_APPLICATION_STEPPING) {
       app->playback_count--;
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 376e594..4852d82 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -33,3 +33,12 @@ Commands.restart = function () {
 Commands.quit = Native.quit;
 
 Breakpoint = Native.Breakpoint;
+
+Wrap = function () {};
+Wrap.prototype = {};
+Wrap.prototype.toString = Native.wrap_toString;
+
+Frame = function () extends Wrap {};
+Frame.prototype = new Wrap ();
+Frame.prototype.addProperty ("name", Native.frame_name_get, null);
+
diff --git a/vivified/core/vivi_wrap_as.c b/vivified/core/vivi_wrap_as.c
new file mode 100644
index 0000000..9cc9b5d
--- /dev/null
+++ b/vivified/core/vivi_wrap_as.c
@@ -0,0 +1,71 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_wrap.h"
+#include "vivi_application.h"
+#include "vivi_function.h"
+
+VIVI_FUNCTION ("wrap_toString", vivi_wrap_toString)
+void
+vivi_wrap_toString (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviWrap *wrap;
+  char *s;
+
+  if (!VIVI_IS_WRAP (this))
+    return;
+  
+  wrap = VIVI_WRAP (this);
+  if (wrap->wrap == NULL)
+    return;
+  
+  s = swfdec_as_object_get_debug (wrap->wrap);
+  SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_give_string (cx, s));
+}
+
+/*** FRAME specific code ***/
+
+VIVI_FUNCTION ("frame_name_get", vivi_wrap_name_get)
+void
+vivi_wrap_name_get (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviWrap *wrap;
+  const char *s;
+
+  g_print ("1\n");
+  if (!VIVI_IS_WRAP (this))
+    return;
+  
+  g_print ("2\n");
+  wrap = VIVI_WRAP (this);
+  if (!SWFDEC_IS_AS_FRAME (wrap->wrap))
+    return;
+  
+  g_print ("3\n");
+  s = swfdec_as_frame_get_function_name (SWFDEC_AS_FRAME (wrap->wrap));
+  SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_get_string (cx, s));
+}
+
+
diff-tree e2df3bc346bf44ba07d4a6c62876d1d96279412e (from a4cedb3d624ef14126d783967a564d0c572040b2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:57:21 2007 +0200

    add swfdec_as_frame_get_function_name() function

diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index 69d7785..cf0e5b1 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -373,6 +373,7 @@ SWFDEC_TYPE_AS_NATIVE_FUNCTION
 <TITLE>SwfdecAsFrame</TITLE>
 SwfdecAsFrame
 swfdec_as_frame_get_next
+swfdec_as_frame_get_function_name
 SwfdecAsStackIterator
 swfdec_as_stack_iterator_init
 swfdec_as_stack_iterator_init_arguments
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 3a08819..0721022 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -743,3 +743,20 @@ swfdec_as_frame_get_next (SwfdecAsFrame 
   return frame->next;
 }
 
+/**
+ * swfdec_as_frame_get_function_name:
+ * @frame: a #SwfdecAsFrame
+ *
+ * Gets the name of the function that is currently executing. This function is
+ * intended for debugging purposes.
+ *
+ * Returns: a string. Do not free.
+ **/
+const char *
+swfdec_as_frame_get_function_name (SwfdecAsFrame *frame)
+{
+  g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), NULL);
+
+  g_assert (frame->function_name);
+  return frame->function_name;
+}
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 17fdccf..183f55d 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -47,6 +47,7 @@ struct _SwfdecAsStackIterator {
 GType		swfdec_as_frame_get_type	(void);
 
 SwfdecAsFrame *	swfdec_as_frame_get_next	(SwfdecAsFrame *		frame);
+const char *	swfdec_as_frame_get_function_name (SwfdecAsFrame *		frame);
 
 SwfdecAsValue *	swfdec_as_stack_iterator_init	(SwfdecAsStackIterator *	iter,
 						 SwfdecAsFrame *		frame);
diff-tree a4cedb3d624ef14126d783967a564d0c572040b2 (from faabbdf9705060fdf574260e3e0cea87261ebeb1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:43:20 2007 +0200

    implement onStartFrame and onExitFrame breakpoint callbacks

diff --git a/vivified/core/vivi_breakpoint.c b/vivified/core/vivi_breakpoint.c
index 19a1f22..94922d4 100644
--- a/vivified/core/vivi_breakpoint.c
+++ b/vivified/core/vivi_breakpoint.c
@@ -24,6 +24,7 @@
 #include "vivi_breakpoint.h"
 #include "vivi_application.h"
 #include "vivi_function.h"
+#include "vivi_wrap.h"
 
 G_DEFINE_TYPE (ViviBreakpoint, vivi_breakpoint, SWFDEC_TYPE_AS_OBJECT)
 
@@ -31,10 +32,35 @@ static gboolean
 vivi_breakpoint_step (ViviDebugger *debugger, ViviBreakpoint *breakpoint)
 {
   SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
+  SwfdecAsValue retval;
+
+  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onCommand"), 0, NULL, &retval);
+  return swfdec_as_value_to_boolean (obj->context, &retval);
+}
+
+static gboolean
+vivi_breakpoint_start_frame (ViviDebugger *debugger, SwfdecAsFrame *frame, ViviBreakpoint *breakpoint)
+{
+  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
   SwfdecAsValue val;
+  SwfdecAsValue retval;
+
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, vivi_wrap_object (VIVI_APPLICATION (obj->context), SWFDEC_AS_OBJECT (frame)));
+  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStartFrame"), 1, &val, &retval);
+  return swfdec_as_value_to_boolean (obj->context, &retval);
+}
+
+static gboolean
+vivi_breakpoint_finish_frame (ViviDebugger *debugger, SwfdecAsFrame *frame, const SwfdecAsValue *ret, ViviBreakpoint *breakpoint)
+{
+  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
+  SwfdecAsValue vals[2];
+  SwfdecAsValue retval;
 
-  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStep"), 0, NULL, &val);
-  return swfdec_as_value_to_boolean (obj->context, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], vivi_wrap_object (VIVI_APPLICATION (obj->context), SWFDEC_AS_OBJECT (frame)));
+  vivi_wrap_value (VIVI_APPLICATION (obj->context), &vals[1], ret);
+  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStartFrame"), 2, vals, &retval);
+  return swfdec_as_value_to_boolean (obj->context, &retval);
 }
 
 static const struct {
@@ -43,7 +69,9 @@ static const struct {
   GCallback	handler;
 } events[] = {
   { NULL, NULL, NULL }, /* invalid */
-  { "onStep", "step", G_CALLBACK (vivi_breakpoint_step) }
+  { "onCommand", "step", G_CALLBACK (vivi_breakpoint_step) },
+  { "onStartFrame", "start-frame", G_CALLBACK (vivi_breakpoint_start_frame) },
+  { "onExitFrame", "finish-frame", G_CALLBACK (vivi_breakpoint_finish_frame) }
 };
 
 static guint
diff --git a/vivified/core/vivi_breakpoint.h b/vivified/core/vivi_breakpoint.h
index 084cc8f..5925ec9 100644
--- a/vivified/core/vivi_breakpoint.h
+++ b/vivified/core/vivi_breakpoint.h
@@ -40,7 +40,7 @@ struct _ViviBreakpoint
 {
   SwfdecAsObject	object;
 
-  gulong		handlers[2];	/* handlers for every signal of the debugger or 0 */
+  gulong		handlers[4];	/* handlers for every signal of the debugger or 0 */
 };
 
 struct _ViviBreakpointClass
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index fcd8ef1..4d81c45 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -29,6 +29,8 @@
 
 enum {
   STEP,
+  START_FRAME,
+  FINISH_FRAME,
   LAST_SIGNAL
 };
 
@@ -99,6 +101,28 @@ vivi_debugger_step (SwfdecAsDebugger *de
 }
 
 static void
+vivi_debugger_start_frame (SwfdecAsDebugger *debugger, SwfdecAsContext *context, SwfdecAsFrame *frame)
+{
+  gboolean retval = FALSE;
+
+  g_signal_emit (debugger, signals[START_FRAME], 0, frame, &retval);
+
+  if (retval)
+    vivi_debugger_break (VIVI_DEBUGGER (debugger));
+}
+
+static void
+vivi_debugger_finish_frame (SwfdecAsDebugger *debugger, SwfdecAsContext *context, SwfdecAsFrame *frame, SwfdecAsValue *ret)
+{
+  gboolean retval = FALSE;
+
+  g_signal_emit (debugger, signals[FINISH_FRAME], 0, frame, ret, &retval);
+
+  if (retval)
+    vivi_debugger_break (VIVI_DEBUGGER (debugger));
+}
+
+static void
 vivi_debugger_class_init (ViviDebuggerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -109,8 +133,16 @@ vivi_debugger_class_init (ViviDebuggerCl
   signals[STEP] = g_signal_new ("step", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__VOID,
       G_TYPE_BOOLEAN, 0);
+  signals[START_FRAME] = g_signal_new ("start-frame", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT,
+      G_TYPE_BOOLEAN, 1, SWFDEC_TYPE_AS_FRAME);
+  signals[FINISH_FRAME] = g_signal_new ("finish-frame", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__OBJECT_POINTER,
+      G_TYPE_BOOLEAN, 2, SWFDEC_TYPE_AS_FRAME, G_TYPE_POINTER);
 
   debugger_class->step = vivi_debugger_step;
+  debugger_class->start_frame = vivi_debugger_start_frame;
+  debugger_class->finish_frame = vivi_debugger_finish_frame;
 }
 
 static void
diff --git a/vivified/core/vivi_marshal.list b/vivified/core/vivi_marshal.list
index 6ff7797..7dce98e 100644
--- a/vivified/core/vivi_marshal.list
+++ b/vivified/core/vivi_marshal.list
@@ -1 +1,3 @@
+BOOLEAN:OBJECT
+BOOLEAN:OBJECT,POINTER
 BOOLEAN:VOID
diff-tree faabbdf9705060fdf574260e3e0cea87261ebeb1 (from b0e4a32fae4e15452d78f6175dc3f6959435e4cd)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:41:34 2007 +0200

    frames are special

diff --git a/vivified/core/vivi_wrap.c b/vivified/core/vivi_wrap.c
index 9329d93..66eb3a4 100644
--- a/vivified/core/vivi_wrap.c
+++ b/vivified/core/vivi_wrap.c
@@ -55,6 +55,7 @@ vivi_wrap_init (ViviWrap *wrap)
 SwfdecAsObject *
 vivi_wrap_object (ViviApplication *app, SwfdecAsObject *object)
 {
+  const char *name;
   SwfdecAsContext *cx;
   SwfdecAsObject *wrap;
   SwfdecAsValue val;
@@ -68,7 +69,12 @@ vivi_wrap_object (ViviApplication *app, 
     return NULL;
   wrap = g_object_new (VIVI_TYPE_WRAP, NULL);
   swfdec_as_object_add (wrap, cx, sizeof (ViviWrap));
-  swfdec_as_object_get_variable (cx->global, swfdec_as_context_get_string (cx, "Wrap"), &val);
+  /* frames are special */
+  if (SWFDEC_IS_AS_FRAME (object))
+    name = "Frame";
+  else
+    name = "Wrap";
+  swfdec_as_object_get_variable (cx->global, swfdec_as_context_get_string (cx, name), &val);
   if (SWFDEC_AS_VALUE_IS_OBJECT (&val))
     swfdec_as_object_set_constructor (wrap, SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
   VIVI_WRAP (wrap)->wrap = object;
diff-tree b0e4a32fae4e15452d78f6175dc3f6959435e4cd (from 9bbbf2efb2a6f96c6c9c3c236072c0608464fa2b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:27:33 2007 +0200

    hoour even more playback state

diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index cd8e949..fcd8ef1 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -60,6 +60,11 @@ vivi_debugger_break (ViviDebugger *debug
   g_assert (app);
   if (app->playback_state == VIVI_APPLICATION_EXITING)
     return;
+  if (app->playback_state == VIVI_APPLICATION_PLAYING) {
+    app->playback_count--;
+    if (app->playback_count > 0)
+      return;
+  }
   swfdec_player_unlock_soft (app->player);
 
   app->playback_state = 0;
diff-tree 9bbbf2efb2a6f96c6c9c3c236072c0608464fa2b (from 1cdf11f6d70a3275a8ae01a8a1a25eba685a2de7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:26:07 2007 +0200

    honour playback state in debugger

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 51ac709..e8f489f 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -27,13 +27,6 @@
 #include "vivi_function.h"
 #include "vivi_ming.h"
 
-typedef enum {
-  VIVI_APPLICATION_STOPPED,
-  VIVI_APPLICATION_PLAYING,
-  VIVI_APPLICATION_STEPPING,
-  VIVI_APPLICATION_EXITING,
-} ViviApplicationPlayback;
-
 enum {
   MESSAGE,
   LAST_SIGNAL
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index d691f81..2636453 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -31,6 +31,13 @@ typedef struct _ViviApplicationClass Viv
 typedef struct _ViviDebugger ViviDebugger;
 
 typedef enum {
+  VIVI_APPLICATION_STOPPED,
+  VIVI_APPLICATION_PLAYING,
+  VIVI_APPLICATION_STEPPING,
+  VIVI_APPLICATION_EXITING,
+} ViviApplicationPlayback;
+
+typedef enum {
   VIVI_MESSAGE_INPUT,
   VIVI_MESSAGE_OUTPUT,
   VIVI_MESSAGE_ERROR
@@ -51,7 +58,7 @@ struct _ViviApplication
   SwfdecPlayer *	player;		/* the current player */
   ViviDebugger *	debugger;	/* the debugger used in player */
   gboolean		player_inited;	/* if the player is inited already */
-  guint			playback_state;	/* (running, stepping or stopped) */
+  ViviApplicationPlayback playback_state;	/* (running, stepping or stopped) */
   guint			playback_count;	/* how often to just restart this on breakpoints */
   GMainLoop *		loop;		/* the breakpoint main loop */
 
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index 70c71b3..cd8e949 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -58,6 +58,8 @@ vivi_debugger_break (ViviDebugger *debug
   ViviApplication *app = debugger->app;
 
   g_assert (app);
+  if (app->playback_state == VIVI_APPLICATION_EXITING)
+    return;
   swfdec_player_unlock_soft (app->player);
 
   app->playback_state = 0;
@@ -78,6 +80,15 @@ vivi_debugger_step (SwfdecAsDebugger *de
 
   g_signal_emit (debugger, signals[STEP], 0, &retval);
 
+  if (!retval) {
+    ViviApplication *app = VIVI_APPLICATION (context);
+
+    if (app->playback_state == VIVI_APPLICATION_STEPPING) {
+      app->playback_count--;
+      if (app->playback_count == 0)
+	retval = TRUE;
+    }
+  }
   if (retval)
     vivi_debugger_break (VIVI_DEBUGGER (debugger));
 }
diff-tree 1cdf11f6d70a3275a8ae01a8a1a25eba685a2de7 (from 5c7937ed5b7d16814cf95d45c77bccaf1c9814f0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:21:46 2007 +0200

    allow referencing values in the debugged context
    
    Everything but objects can be translated literally. Objects need to be wrapped.
    The ViviWrap object does exactly this.

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 28916c3..e535481 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -13,7 +13,8 @@ libvivified_core_la_SOURCES = \
 	vivi_initialize.as \
 	vivi_initialize.s \
 	vivi_marshal.c \
-	vivi_ming.c
+	vivi_ming.c \
+	vivi_wrap.c
 
 vivi_initialize.lo: vivi_initialize.s vivi_initialize.as
 	$(LTCCASCOMPILE) -c -o $@ vivi_initialize.s
@@ -26,6 +27,7 @@ noinst_HEADERS = \
 	vivi_function_list.h \
 	vivi_marshal.h \
 	vivi_ming.h \
+	vivi_wrap.h \
 	vivified-core.h
 
 BUILT_SOURCES = \
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 318630f..51ac709 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -89,6 +89,7 @@ vivi_application_dispose (GObject *objec
   ViviApplication *app = VIVI_APPLICATION (object);
 
   g_object_unref (app->player);
+  g_hash_table_destroy (app->wraps);
 
   G_OBJECT_CLASS (vivi_application_parent_class)->dispose (object);
 }
@@ -120,6 +121,8 @@ vivi_application_init (ViviApplication *
   app->debugger = g_object_new (VIVI_TYPE_DEBUGGER, NULL);
   app->debugger->app = app;
   app->player = swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app->debugger));
+
+  app->wraps = g_hash_table_new (g_direct_hash, g_direct_equal);
 }
 
 ViviApplication *
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 1e0d4c0..d691f81 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -54,6 +54,8 @@ struct _ViviApplication
   guint			playback_state;	/* (running, stepping or stopped) */
   guint			playback_count;	/* how often to just restart this on breakpoints */
   GMainLoop *		loop;		/* the breakpoint main loop */
+
+  GHashTable *		wraps;		/* all wrapped objects from @player */
 };
 
 struct _ViviApplicationClass
diff --git a/vivified/core/vivi_wrap.c b/vivified/core/vivi_wrap.c
new file mode 100644
index 0000000..9329d93
--- /dev/null
+++ b/vivified/core/vivi_wrap.c
@@ -0,0 +1,107 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_wrap.h"
+#include "vivi_application.h"
+
+G_DEFINE_TYPE (ViviWrap, vivi_wrap, SWFDEC_TYPE_AS_OBJECT)
+
+static void
+vivi_wrap_dispose (GObject *object)
+{
+  ViviWrap *wrap = VIVI_WRAP (object);
+
+  if (wrap->wrap) {
+    g_hash_table_remove (VIVI_APPLICATION (SWFDEC_AS_OBJECT (wrap)->context)->wraps, wrap->wrap);
+    wrap->wrap = NULL;
+  }
+
+  G_OBJECT_CLASS (vivi_wrap_parent_class)->dispose (object);
+}
+
+static void
+vivi_wrap_class_init (ViviWrapClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_wrap_dispose;
+}
+
+static void
+vivi_wrap_init (ViviWrap *wrap)
+{
+}
+
+SwfdecAsObject *
+vivi_wrap_object (ViviApplication *app, SwfdecAsObject *object)
+{
+  SwfdecAsContext *cx;
+  SwfdecAsObject *wrap;
+  SwfdecAsValue val;
+  
+  wrap = g_hash_table_lookup (app->wraps, object);
+  if (wrap)
+    return wrap;
+
+  cx = SWFDEC_AS_CONTEXT (app);
+  if (!swfdec_as_context_use_mem (cx, sizeof (ViviWrap)))
+    return NULL;
+  wrap = g_object_new (VIVI_TYPE_WRAP, NULL);
+  swfdec_as_object_add (wrap, cx, sizeof (ViviWrap));
+  swfdec_as_object_get_variable (cx->global, swfdec_as_context_get_string (cx, "Wrap"), &val);
+  if (SWFDEC_AS_VALUE_IS_OBJECT (&val))
+    swfdec_as_object_set_constructor (wrap, SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
+  VIVI_WRAP (wrap)->wrap = object;
+  g_hash_table_insert (app->wraps, object, wrap);
+  return wrap;
+}
+
+void
+vivi_wrap_value (ViviApplication *app, SwfdecAsValue *dest, const SwfdecAsValue *src)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+  g_return_if_fail (dest != NULL);
+  g_return_if_fail (SWFDEC_IS_AS_VALUE (src));
+
+  switch (src->type) {
+    case SWFDEC_AS_TYPE_UNDEFINED:
+    case SWFDEC_AS_TYPE_BOOLEAN:
+    case SWFDEC_AS_TYPE_NUMBER:
+    case SWFDEC_AS_TYPE_NULL:
+      *dest = *src;
+      break;
+    case SWFDEC_AS_TYPE_STRING:
+      SWFDEC_AS_VALUE_SET_STRING (dest,
+	  swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (app),
+	    SWFDEC_AS_VALUE_GET_STRING (src)));
+      break;
+    case SWFDEC_AS_TYPE_OBJECT:
+      SWFDEC_AS_VALUE_SET_OBJECT (dest,
+	  vivi_wrap_object (app, SWFDEC_AS_VALUE_GET_OBJECT (src)));
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+}
+
diff --git a/vivified/core/vivi_wrap.h b/vivified/core/vivi_wrap.h
new file mode 100644
index 0000000..2c551e0
--- /dev/null
+++ b/vivified/core/vivi_wrap.h
@@ -0,0 +1,60 @@
+/* Vivified
+ * 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 _VIVI_WRAP_H_
+#define _VIVI_WRAP_H_
+
+#include <libswfdec/swfdec.h>
+#include <vivified/core/vivi_application.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviWrap ViviWrap;
+typedef struct _ViviWrapClass ViviWrapClass;
+
+#define VIVI_TYPE_WRAP                    (vivi_wrap_get_type())
+#define VIVI_IS_WRAP(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_WRAP))
+#define VIVI_IS_WRAP_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_WRAP))
+#define VIVI_WRAP(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_WRAP, ViviWrap))
+#define VIVI_WRAP_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_WRAP, ViviWrapClass))
+#define VIVI_WRAP_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_WRAP, ViviWrapClass))
+
+struct _ViviWrap
+{
+  SwfdecAsObject	object;
+
+  SwfdecAsObject *	wrap;	  	/* the object we wrap */
+};
+
+struct _ViviWrapClass
+{
+  SwfdecAsObjectClass	object_class;
+};
+
+GType			vivi_wrap_get_type   	(void);
+
+SwfdecAsObject *	vivi_wrap_object	(ViviApplication *	app,
+						 SwfdecAsObject *	object);
+void			vivi_wrap_value		(ViviApplication *	app,
+						 SwfdecAsValue *	dest,
+						 const SwfdecAsValue *	src);
+
+G_END_DECLS
+#endif
diff-tree 5c7937ed5b7d16814cf95d45c77bccaf1c9814f0 (from 05162930a43aa66d14489b56f63484a32ca51988)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 10:20:28 2007 +0200

    check for NULL in SWFDEC_IS_AS_VALUE

diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 294df40..54189d8 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -64,7 +64,7 @@ struct _SwfdecAsValue {
   } value;
 };
 
-#define SWFDEC_IS_AS_VALUE(val) ((val)->type <= SWFDEC_TYPE_AS_OBJECT)
+#define SWFDEC_IS_AS_VALUE(val) ((val) != NULL && (val)->type <= SWFDEC_TYPE_AS_OBJECT)
 
 #define SWFDEC_AS_VALUE_IS_UNDEFINED(val) ((val)->type == SWFDEC_AS_TYPE_UNDEFINED)
 #define SWFDEC_AS_VALUE_SET_UNDEFINED(val) (val)->type = SWFDEC_AS_TYPE_UNDEFINED
diff-tree 05162930a43aa66d14489b56f63484a32ca51988 (from f523ffa3245e965c28d8ea8b1d9f64dc6e149f4d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 15 09:57:55 2007 +0200

    fix function name typo

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 585d295..318630f 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -247,7 +247,7 @@ vivi_application_check (ViviApplication 
 }
 
 void
-vivi_applciation_execute (ViviApplication *app, const char *command)
+vivi_application_execute (ViviApplication *app, const char *command)
 {
   SwfdecAsValue val;
   SwfdecAsObject *object;
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index d1f0da7..1e0d4c0 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -89,7 +89,7 @@ void			vivi_application_step		(ViviAppli
 							 guint			n_times);
 void			vivi_application_quit		(ViviApplication *	app);
 
-void			vivi_applciation_execute	(ViviApplication *	app,
+void			vivi_application_execute	(ViviApplication *	app,
 							 const char *		command);
 
 G_END_DECLS
diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
index cfcb382..4c2608c 100644
--- a/vivified/core/vivi_function.c
+++ b/vivified/core/vivi_function.c
@@ -78,7 +78,7 @@ vivi_function_init_context (ViviApplicat
       VIVI_TYPE_BREAKPOINT);
 
   g_signal_connect (app, "message", G_CALLBACK (vivi_function_not_reached), NULL);
-  vivi_applciation_execute (app, vivi_initialize);
+  vivi_application_execute (app, vivi_initialize);
   g_signal_handlers_disconnect_by_func (app, G_CALLBACK (vivi_function_not_reached), NULL);
 }
 
diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
index 7003065..555e922 100644
--- a/vivified/ui/vivi_commandline.c
+++ b/vivified/ui/vivi_commandline.c
@@ -90,7 +90,7 @@ vivi_command_line_execute (ViviCommandLi
   }
 
   
-  vivi_applciation_execute (cl->app, run);
+  vivi_application_execute (cl->app, run);
   if (command != run)
     g_free (run);
 }
diff-tree f523ffa3245e965c28d8ea8b1d9f64dc6e149f4d (from eedb937ec77addb1da3710a776951c886c7a5d70)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 22:29:46 2007 +0200

    add support for new frames and finishing frames

diff --git a/libswfdec/swfdec_as_debugger.h b/libswfdec/swfdec_as_debugger.h
index 643ac53..fdd2a76 100644
--- a/libswfdec/swfdec_as_debugger.h
+++ b/libswfdec/swfdec_as_debugger.h
@@ -46,9 +46,15 @@ struct _SwfdecAsDebuggerClass {
   /* called before executing a bytecode */
   void			(* step)	(SwfdecAsDebugger *	debugger,
 					 SwfdecAsContext *	context);
-  /* called after adding or removing a frame from the function stack */
-  void			(* frame_change)(SwfdecAsDebugger *	debugger,
-					 SwfdecAsContext *	context);
+  /* called after adding a frame from the function stack */
+  void			(* start_frame)	(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context,
+					 SwfdecAsFrame *	frame);
+  /* called after removing a frame from the function stack */
+  void			(* finish_frame)(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context,
+					 SwfdecAsFrame *	frame,
+					 SwfdecAsValue *	return_value);
 };
 
 GType		swfdec_as_debugger_get_type	(void);
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 4608b0a..3a08819 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -419,6 +419,12 @@ swfdec_as_frame_return (SwfdecAsFrame *f
       swfdec_as_stack_pop_segment (context);
     }
   }
+  if (context->debugger) {
+    SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger);
+
+    if (klass->finish_frame)
+      klass->finish_frame (context->debugger, context, frame, &retval);
+  }
   /* set return value */
   if (frame->return_value) {
     *frame->return_value = retval;
@@ -569,12 +575,13 @@ swfdec_as_frame_preload (SwfdecAsFrame *
 
   g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
 
-  if (frame->script == NULL)
-    return;
+
   /* setup */
   object = SWFDEC_AS_OBJECT (frame);
   context = object->context;
   script = frame->script;
+  if (frame->script == NULL)
+    goto out;
 
   /* create arguments and super object if necessary */
   if ((script->flags & (SWFDEC_SCRIPT_PRELOAD_ARGS | SWFDEC_SCRIPT_SUPPRESS_ARGS)) != SWFDEC_SCRIPT_SUPPRESS_ARGS) {
@@ -682,6 +689,14 @@ swfdec_as_frame_preload (SwfdecAsFrame *
   if (script->flags & SWFDEC_SCRIPT_PRELOAD_GLOBAL && current_reg < script->n_registers) {
     SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], context->global);
   }
+
+out:
+  if (context->debugger) {
+    SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger);
+
+    if (klass->start_frame)
+      klass->start_frame (context->debugger, context, frame);
+  }
 }
 
 /**
diff-tree eedb937ec77addb1da3710a776951c886c7a5d70 (from 0fc26b7da7563261f05d8930120e2ae8a566d3f9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 20:48:31 2007 +0200

    properly accumulate signal return values

diff --git a/vivified/core/.gitignore b/vivified/core/.gitignore
index da08114..4bc848f 100644
--- a/vivified/core/.gitignore
+++ b/vivified/core/.gitignore
@@ -12,3 +12,5 @@ Makefile.in
 *.loT
 
 vivi_function_list.h
+vivi_marshal.h
+vivi_marshal.c
diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 694ddad..28916c3 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -12,6 +12,7 @@ libvivified_core_la_SOURCES = \
 	vivi_function.c \
 	vivi_initialize.as \
 	vivi_initialize.s \
+	vivi_marshal.c \
 	vivi_ming.c
 
 vivi_initialize.lo: vivi_initialize.s vivi_initialize.as
@@ -23,11 +24,14 @@ noinst_HEADERS = \
 	vivi_debugger.h \
 	vivi_function.h \
 	vivi_function_list.h \
+	vivi_marshal.h \
 	vivi_ming.h \
 	vivified-core.h
 
 BUILT_SOURCES = \
-	vivi_function_list.h
+	vivi_function_list.h \
+	vivi_marshal.h \
+	vivi_marshal.c
 
 CLEANFILES = \
 	$(BUILT_SOURCES)
@@ -36,5 +40,17 @@ vivi_function_list.h: $(libvivified_core
 	(cd $(srcdir) \
 	  && grep -he "^VIVI_FUNCTION" $(libvivified_core_la_SOURCES) \
 	 ) >> xgen-vfl \
-	&& (cmp -s xgen-vfl swfdec_asnative.h || cp xgen-vfl vivi_function_list.h) \
+	&& (cmp -s xgen-vfl vivi_asnative.h || cp xgen-vfl vivi_function_list.h) \
 	&& rm -f xgen-vfl
+
+vivi_marshal.h: vivi_marshal.list Makefile
+	$(GLIB_GENMARSHAL) --prefix=vivi_marshal $(srcdir)/vivi_marshal.list --header >> xgen-vmh \
+	&& (cmp -s xgen-vmh vivi_marshal.h || cp xgen-vmh vivi_marshal.h) \
+	&& rm -f xgen-vmh
+
+vivi_marshal.c: vivi_marshal.list vivi_marshal.h Makefile
+	(echo "#include \"vivi_marshal.h\""; \
+	 $(GLIB_GENMARSHAL) --prefix=vivi_marshal $(srcdir)/vivi_marshal.list --body;) >> xgen-vmc \
+	&& cp xgen-vmc vivi_marshal.c \
+	&& rm -f xgen-vmc 
+
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
index fcad454..70c71b3 100644
--- a/vivified/core/vivi_debugger.c
+++ b/vivified/core/vivi_debugger.c
@@ -23,6 +23,7 @@
 
 #include "vivi_debugger.h"
 #include "vivi_application.h"
+#include "vivi_marshal.h"
 /* FIXME: oops */
 #include "libswfdec/swfdec_player_internal.h"
 
@@ -90,7 +91,7 @@ vivi_debugger_class_init (ViviDebuggerCl
   object_class->dispose = vivi_debugger_dispose;
 
   signals[STEP] = g_signal_new ("step", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, g_cclosure_marshal_VOID__VOID,
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, vivi_marshal_BOOLEAN__VOID,
       G_TYPE_BOOLEAN, 0);
 
   debugger_class->step = vivi_debugger_step;
diff --git a/vivified/core/vivi_marshal.list b/vivified/core/vivi_marshal.list
new file mode 100644
index 0000000..6ff7797
--- /dev/null
+++ b/vivified/core/vivi_marshal.list
@@ -0,0 +1 @@
+BOOLEAN:VOID
diff-tree 0fc26b7da7563261f05d8930120e2ae8a566d3f9 (from adc7c2987283fe1ec7df8aa442d6d11b6d8d762a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 20:47:59 2007 +0200

    make sure handlers are properly cleared so setting them up again later does work.

diff --git a/vivified/core/vivi_breakpoint.c b/vivified/core/vivi_breakpoint.c
index 7931e28..19a1f22 100644
--- a/vivified/core/vivi_breakpoint.c
+++ b/vivified/core/vivi_breakpoint.c
@@ -73,8 +73,10 @@ vivi_breakpoint_set (SwfdecAsObject *obj
 	breakpoint->handlers[i] = g_signal_connect (debugger, events[i].signal,
 	    events[i].handler, object);
     } else {
-      if (breakpoint->handlers[i])
+      if (breakpoint->handlers[i]) {
 	g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
+	breakpoint->handlers[i] = 0;
+      }
     }
   }
   SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val);
@@ -90,6 +92,7 @@ vivi_breakpoint_delete (SwfdecAsObject *
   if (i && breakpoint->handlers[i]) {
     ViviDebugger *debugger = VIVI_APPLICATION (object->context)->debugger;
     g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
+    breakpoint->handlers[i] = 0;
   }
 
   return SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
diff-tree adc7c2987283fe1ec7df8aa442d6d11b6d8d762a (from c1e028a0e58fb2821ce1d10898aca11fbc3c19a0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 20:29:22 2007 +0200

    remove debugging g_print's

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index d822642..585d295 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -140,7 +140,6 @@ vivi_application_init_player (ViviApplic
 
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
-  g_print ("init\n");
   if (app->player_inited)
     return;
   
@@ -149,7 +148,6 @@ vivi_application_init_player (ViviApplic
     return;
   }
 
-  g_print ("really init\n");
   loader = swfdec_file_loader_new (app->filename);
   swfdec_player_set_loader (app->player, loader);
   app->player_inited = TRUE;
diff-tree c1e028a0e58fb2821ce1d10898aca11fbc3c19a0 (from 507c1f215ba04bee30f9b82d13040b51780275e9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 20:29:01 2007 +0200

    add a quit command/function

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index fadfcde..d822642 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -31,6 +31,7 @@ typedef enum {
   VIVI_APPLICATION_STOPPED,
   VIVI_APPLICATION_PLAYING,
   VIVI_APPLICATION_STEPPING,
+  VIVI_APPLICATION_EXITING,
 } ViviApplicationPlayback;
 
 enum {
@@ -215,6 +216,12 @@ vivi_application_check (ViviApplication 
   swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (app));
 
   switch (app->playback_state) {
+    case VIVI_APPLICATION_EXITING:
+      if (is_playing)
+	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
+      if (is_breakpoint)
+	g_main_loop_quit (app->loop);
+      break;
     case VIVI_APPLICATION_STOPPED:
       if (is_playing)
 	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
@@ -314,3 +321,13 @@ vivi_application_step (ViviApplication *
   app->playback_count = n_times;
 }
 
+void
+vivi_application_quit (ViviApplication *app)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  app->playback_state = VIVI_APPLICATION_EXITING;
+  app->playback_count = 1;
+  gtk_main_quit ();
+}
+
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 2f4fd33..d1f0da7 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -87,6 +87,7 @@ void			vivi_application_play		(ViviAppli
 void			vivi_application_stop		(ViviApplication *	app);
 void			vivi_application_step		(ViviApplication *	app,
 							 guint			n_times);
+void			vivi_application_quit		(ViviApplication *	app);
 
 void			vivi_applciation_execute	(ViviApplication *	app,
 							 const char *		command);
diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index 2e72f23..a637428 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -89,3 +89,13 @@ vivi_application_as_print (SwfdecAsConte
   vivi_application_output (app, "%s", s);
 }
 
+VIVI_FUNCTION ("quit", vivi_application_as_quit)
+void
+vivi_application_as_quit (SwfdecAsContext *cx, SwfdecAsObject *this, 
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+
+  vivi_application_quit (app);
+}
+
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index e5809b0..376e594 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -30,5 +30,6 @@ Commands.restart = function () {
   Commands.reset ();
   Commands.run ();
 };
+Commands.quit = Native.quit;
 
 Breakpoint = Native.Breakpoint;
diff-tree 507c1f215ba04bee30f9b82d13040b51780275e9 (from c26fe8330d6c77a5a0bc34f4ca3ce63a74f8bf28)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 15:16:31 2007 +0200

    add breakpoints

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 7d2fd48..694ddad 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -6,6 +6,8 @@ libvivified_core_la_LDFLAGS = $(SWFDEC_G
 libvivified_core_la_SOURCES = \
 	vivi_application.c \
 	vivi_application_as.c \
+	vivi_application.c \
+	vivi_breakpoint.c \
 	vivi_debugger.c \
 	vivi_function.c \
 	vivi_initialize.as \
@@ -17,6 +19,7 @@ vivi_initialize.lo: vivi_initialize.s vi
 
 noinst_HEADERS = \
 	vivi_application.h \
+	vivi_breakpoint.h \
 	vivi_debugger.h \
 	vivi_function.h \
 	vivi_function_list.h \
diff --git a/vivified/core/vivi_breakpoint.c b/vivified/core/vivi_breakpoint.c
new file mode 100644
index 0000000..7931e28
--- /dev/null
+++ b/vivified/core/vivi_breakpoint.c
@@ -0,0 +1,130 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_breakpoint.h"
+#include "vivi_application.h"
+#include "vivi_function.h"
+
+G_DEFINE_TYPE (ViviBreakpoint, vivi_breakpoint, SWFDEC_TYPE_AS_OBJECT)
+
+static gboolean
+vivi_breakpoint_step (ViviDebugger *debugger, ViviBreakpoint *breakpoint)
+{
+  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
+  SwfdecAsValue val;
+
+  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStep"), 0, NULL, &val);
+  return swfdec_as_value_to_boolean (obj->context, &val);
+}
+
+static const struct {
+  const char *	event;
+  const char *	signal;
+  GCallback	handler;
+} events[] = {
+  { NULL, NULL, NULL }, /* invalid */
+  { "onStep", "step", G_CALLBACK (vivi_breakpoint_step) }
+};
+
+static guint
+vivi_breakpoint_find_event (const char *name)
+{
+  guint i;
+
+  for (i = 1; i < G_N_ELEMENTS (events); i++) {
+    if (g_str_equal (events[i].event, name))
+      return i;
+  }
+  return 0;
+}
+
+static void
+vivi_breakpoint_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val)
+{
+  guint i;
+
+  i = vivi_breakpoint_find_event (variable);
+  if (i) {
+    ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
+    ViviDebugger *debugger = VIVI_APPLICATION (object->context)->debugger;
+    if (SWFDEC_AS_VALUE_IS_OBJECT (val) &&
+	SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (val))) {
+      if (!breakpoint->handlers[i])
+	breakpoint->handlers[i] = g_signal_connect (debugger, events[i].signal,
+	    events[i].handler, object);
+    } else {
+      if (breakpoint->handlers[i])
+	g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
+    }
+  }
+  SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val);
+}
+
+static gboolean
+vivi_breakpoint_delete (SwfdecAsObject *object, const char *variable)
+{
+  ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
+  guint i;
+
+  i = vivi_breakpoint_find_event (variable);
+  if (i && breakpoint->handlers[i]) {
+    ViviDebugger *debugger = VIVI_APPLICATION (object->context)->debugger;
+    g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
+  }
+
+  return SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
+}
+
+static void
+vivi_breakpoint_dispose (GObject *object)
+{
+  ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
+  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
+  guint i;
+
+  for (i = 0; i < G_N_ELEMENTS (events); i++) {
+    if (breakpoint->handlers[i])
+      g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
+  }
+  G_OBJECT_CLASS (vivi_breakpoint_parent_class)->dispose (object);
+}
+
+static void
+vivi_breakpoint_class_init (ViviBreakpointClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  SwfdecAsObjectClass *as_object_class = SWFDEC_AS_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_breakpoint_dispose;
+
+  as_object_class->set = vivi_breakpoint_set;
+  as_object_class->del = vivi_breakpoint_delete;
+}
+
+static void
+vivi_breakpoint_init (ViviBreakpoint *breakpoint)
+{
+}
+
+/*** AS CODE ***/
+
diff --git a/vivified/core/vivi_breakpoint.h b/vivified/core/vivi_breakpoint.h
new file mode 100644
index 0000000..084cc8f
--- /dev/null
+++ b/vivified/core/vivi_breakpoint.h
@@ -0,0 +1,55 @@
+/* Vivified
+ * 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 _VIVI_BREAKPOINT_H_
+#define _VIVI_BREAKPOINT_H_
+
+#include <libswfdec/swfdec.h>
+#include <vivified/core/vivi_application.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviBreakpoint ViviBreakpoint;
+typedef struct _ViviBreakpointClass ViviBreakpointClass;
+
+#define VIVI_TYPE_BREAKPOINT                    (vivi_breakpoint_get_type())
+#define VIVI_IS_BREAKPOINT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_BREAKPOINT))
+#define VIVI_IS_BREAKPOINT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_BREAKPOINT))
+#define VIVI_BREAKPOINT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_BREAKPOINT, ViviBreakpoint))
+#define VIVI_BREAKPOINT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_BREAKPOINT, ViviBreakpointClass))
+#define VIVI_BREAKPOINT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_BREAKPOINT, ViviBreakpointClass))
+
+struct _ViviBreakpoint
+{
+  SwfdecAsObject	object;
+
+  gulong		handlers[2];	/* handlers for every signal of the debugger or 0 */
+};
+
+struct _ViviBreakpointClass
+{
+  SwfdecAsObjectClass	object_class;
+};
+
+GType			vivi_breakpoint_get_type   	(void);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
index 6fb5197..cfcb382 100644
--- a/vivified/core/vivi_function.c
+++ b/vivified/core/vivi_function.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "vivi_function.h"
+#include "vivi_breakpoint.h"
 #include "vivi_function_list.h"
 
 /* include vivi_function_list with special macro definition, so we get a nice
@@ -52,6 +53,7 @@ void
 vivi_function_init_context (ViviApplication *app)
 { 
   SwfdecAsContext *cx = SWFDEC_AS_CONTEXT (app);
+  SwfdecAsFunction *fun;
   SwfdecAsObject *obj;
   SwfdecAsValue val;
   guint i;
@@ -68,6 +70,13 @@ vivi_function_init_context (ViviApplicat
       swfdec_as_context_get_string (cx, functions[i].name),
       0, functions[i].fun, 0);
   }
+  /* FIXME: find a better solution than this */
+  fun = swfdec_as_object_add_function (obj,
+    swfdec_as_context_get_string (cx, "Breakpoint"),
+    0, functions[i].fun, 0);
+  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (fun),
+      VIVI_TYPE_BREAKPOINT);
+
   g_signal_connect (app, "message", G_CALLBACK (vivi_function_not_reached), NULL);
   vivi_applciation_execute (app, vivi_initialize);
   g_signal_handlers_disconnect_by_func (app, G_CALLBACK (vivi_function_not_reached), NULL);
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index d8eadc5..e5809b0 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -30,3 +30,5 @@ Commands.restart = function () {
   Commands.reset ();
   Commands.run ();
 };
+
+Breakpoint = Native.Breakpoint;
diff-tree c26fe8330d6c77a5a0bc34f4ca3ce63a74f8bf28 (from 7cc61118ddf98319b1641013587b505affc01300)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 14:49:56 2007 +0200

    apparently the function headers weren't installed either.
    
    They are documented though (nice!)

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index fc9d47f..b9a63b3 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -128,6 +128,8 @@ public_headers = \
 	swfdec_as_context.h \
 	swfdec_as_debugger.h \
 	swfdec_as_frame.h \
+	swfdec_as_function.h \
+	swfdec_as_native_function.h \
 	swfdec_as_object.h \
 	swfdec_as_types.h \
 	swfdec_audio.h \
@@ -147,11 +149,9 @@ noinst_HEADERS = \
 	swfdec_as_array.h \
 	swfdec_as_boolean.h \
 	swfdec_as_frame_internal.h \
-	swfdec_as_function.h \
 	swfdec_as_internal.h \
 	swfdec_as_interpret.h \
 	swfdec_as_math.h \
-	swfdec_as_native_function.h \
 	swfdec_as_number.h \
 	swfdec_as_scope.h \
 	swfdec_as_script_function.h \
diff-tree 7cc61118ddf98319b1641013587b505affc01300 (from b8865e69f74f00f1c2b373003900b24592df341b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 14:48:38 2007 +0200

    These two files were missing in the headers

diff --git a/libswfdec/swfdec.h b/libswfdec/swfdec.h
index ec4d136..8a4cd65 100644
--- a/libswfdec/swfdec.h
+++ b/libswfdec/swfdec.h
@@ -25,6 +25,8 @@
 #include <libswfdec/swfdec_as_context.h>
 #include <libswfdec/swfdec_as_debugger.h>
 #include <libswfdec/swfdec_as_frame.h>
+#include <libswfdec/swfdec_as_function.h>
+#include <libswfdec/swfdec_as_native_function.h>
 #include <libswfdec/swfdec_as_object.h>
 #include <libswfdec/swfdec_as_types.h>
 #include <libswfdec/swfdec_script.h>
diff-tree b8865e69f74f00f1c2b373003900b24592df341b (from 2421ba7779043c938533566a0a23a8ab5c3a84ff)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 12:47:48 2007 +0200

    g_object_notify() about a new player

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index dd3b46f..fadfcde 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -163,6 +163,7 @@ vivi_application_reset (ViviApplication 
   g_object_unref (app->player);
   app->player = swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app->debugger));
   app->player_inited = FALSE;
+  g_object_notify (G_OBJECT (app), "player");
 }
 
 void
diff-tree 2421ba7779043c938533566a0a23a8ab5c3a84ff (from c5c3edfb757eb8ff0bad4301fc877cc38a648815)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 12:45:24 2007 +0200

    implement the debugger and use it

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 6b0e473..7d2fd48 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -6,6 +6,7 @@ libvivified_core_la_LDFLAGS = $(SWFDEC_G
 libvivified_core_la_SOURCES = \
 	vivi_application.c \
 	vivi_application_as.c \
+	vivi_debugger.c \
 	vivi_function.c \
 	vivi_initialize.as \
 	vivi_initialize.s \
@@ -16,6 +17,7 @@ vivi_initialize.lo: vivi_initialize.s vi
 
 noinst_HEADERS = \
 	vivi_application.h \
+	vivi_debugger.h \
 	vivi_function.h \
 	vivi_function_list.h \
 	vivi_ming.h \
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 958b459..dd3b46f 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -23,6 +23,7 @@
 
 #include <libswfdec-gtk/swfdec-gtk.h>
 #include "vivi_application.h"
+#include "vivi_debugger.h"
 #include "vivi_function.h"
 #include "vivi_ming.h"
 
@@ -115,7 +116,9 @@ vivi_application_class_init (ViviApplica
 static void
 vivi_application_init (ViviApplication *app)
 {
-  app->player = swfdec_gtk_player_new (NULL);
+  app->debugger = g_object_new (VIVI_TYPE_DEBUGGER, NULL);
+  app->debugger->app = app;
+  app->player = swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app->debugger));
 }
 
 ViviApplication *
@@ -156,8 +159,9 @@ vivi_application_reset (ViviApplication 
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
+  g_assert (app->loop == NULL); /* FIXME: what do we do if we're inside a breakpoint? */
   g_object_unref (app->player);
-  app->player = swfdec_gtk_player_new (NULL);
+  app->player = swfdec_gtk_player_new (SWFDEC_AS_DEBUGGER (app->debugger));
   app->player_inited = FALSE;
 }
 
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index fab0262..2f4fd33 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -27,6 +27,8 @@ G_BEGIN_DECLS
 
 typedef struct _ViviApplication ViviApplication;
 typedef struct _ViviApplicationClass ViviApplicationClass;
+/* forward declarations */
+typedef struct _ViviDebugger ViviDebugger;
 
 typedef enum {
   VIVI_MESSAGE_INPUT,
@@ -47,6 +49,7 @@ struct _ViviApplication
 
   char *		filename;	/* name of the file we play back or NULL if none set yet */
   SwfdecPlayer *	player;		/* the current player */
+  ViviDebugger *	debugger;	/* the debugger used in player */
   gboolean		player_inited;	/* if the player is inited already */
   guint			playback_state;	/* (running, stepping or stopped) */
   guint			playback_count;	/* how often to just restart this on breakpoints */
diff --git a/vivified/core/vivi_debugger.c b/vivified/core/vivi_debugger.c
new file mode 100644
index 0000000..fcad454
--- /dev/null
+++ b/vivified/core/vivi_debugger.c
@@ -0,0 +1,103 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_debugger.h"
+#include "vivi_application.h"
+/* FIXME: oops */
+#include "libswfdec/swfdec_player_internal.h"
+
+enum {
+  STEP,
+  LAST_SIGNAL
+};
+
+G_DEFINE_TYPE (ViviDebugger, vivi_debugger, SWFDEC_TYPE_AS_DEBUGGER)
+static guint signals[LAST_SIGNAL] = { 0, };
+
+static gboolean
+vivi_accumulate_or (GSignalInvocationHint *ihint, GValue *return_accu, 
+    const GValue *handler_return, gpointer data)
+{
+  if (g_value_get_boolean (handler_return))
+    g_value_set_boolean (return_accu, TRUE);
+  return TRUE;
+}
+
+static void
+vivi_debugger_dispose (GObject *object)
+{
+  //ViviDebugger *debugger = VIVI_DEBUGGER (object);
+
+  G_OBJECT_CLASS (vivi_debugger_parent_class)->dispose (object);
+}
+
+static void
+vivi_debugger_break (ViviDebugger *debugger)
+{
+  ViviApplication *app = debugger->app;
+
+  g_assert (app);
+  swfdec_player_unlock_soft (app->player);
+
+  app->playback_state = 0;
+  app->playback_count = 0;
+  app->loop = g_main_loop_new (NULL, FALSE);
+
+  g_main_loop_run (app->loop);
+
+  g_main_loop_unref (app->loop);
+  app->loop = NULL;
+  swfdec_player_lock_soft (app->player);
+}
+
+static void
+vivi_debugger_step (SwfdecAsDebugger *debugger, SwfdecAsContext *context)
+{
+  gboolean retval = FALSE;
+
+  g_signal_emit (debugger, signals[STEP], 0, &retval);
+
+  if (retval)
+    vivi_debugger_break (VIVI_DEBUGGER (debugger));
+}
+
+static void
+vivi_debugger_class_init (ViviDebuggerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  SwfdecAsDebuggerClass *debugger_class = SWFDEC_AS_DEBUGGER_CLASS (klass);
+
+  object_class->dispose = vivi_debugger_dispose;
+
+  signals[STEP] = g_signal_new ("step", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, vivi_accumulate_or, NULL, g_cclosure_marshal_VOID__VOID,
+      G_TYPE_BOOLEAN, 0);
+
+  debugger_class->step = vivi_debugger_step;
+}
+
+static void
+vivi_debugger_init (ViviDebugger *debugger)
+{
+}
+
diff --git a/vivified/core/vivi_debugger.h b/vivified/core/vivi_debugger.h
new file mode 100644
index 0000000..76873ab
--- /dev/null
+++ b/vivified/core/vivi_debugger.h
@@ -0,0 +1,55 @@
+/* Vivified
+ * 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 _VIVI_DEBUGGER_H_
+#define _VIVI_DEBUGGER_H_
+
+#include <libswfdec/swfdec.h>
+#include <vivified/core/vivi_application.h>
+
+G_BEGIN_DECLS
+
+
+//typedef struct _ViviDebugger ViviDebugger;
+typedef struct _ViviDebuggerClass ViviDebuggerClass;
+
+#define VIVI_TYPE_DEBUGGER                    (vivi_debugger_get_type())
+#define VIVI_IS_DEBUGGER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_DEBUGGER))
+#define VIVI_IS_DEBUGGER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_DEBUGGER))
+#define VIVI_DEBUGGER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_DEBUGGER, ViviDebugger))
+#define VIVI_DEBUGGER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_DEBUGGER, ViviDebuggerClass))
+#define VIVI_DEBUGGER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_DEBUGGER, ViviDebuggerClass))
+
+struct _ViviDebugger
+{
+  SwfdecAsDebugger	debugger;
+
+  ViviApplication *	app;	  	/* the appliction we're playing for */
+};
+
+struct _ViviDebuggerClass
+{
+  SwfdecAsDebuggerClass	debugger_class;
+};
+
+GType			vivi_debugger_get_type   	(void);
+
+
+G_END_DECLS
+#endif
diff-tree c5c3edfb757eb8ff0bad4301fc877cc38a648815 (from df83f6880be9203515164615fae3da464d36027b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 12:26:37 2007 +0200

    add swfdec_player_(un)lock_soft () functions

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index e1c7748..2bb0264 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1043,11 +1043,11 @@ swfdec_player_perform_actions (SwfdecPla
   player->invalid = old_inval;
 }
 
+/* used for breakpoints */
 void
-swfdec_player_lock (SwfdecPlayer *player)
+swfdec_player_lock_soft (SwfdecPlayer *player)
 {
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
-  g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);
   g_assert (swfdec_rect_is_empty (&player->invalid));
 
   g_object_freeze_notify (G_OBJECT (player));
@@ -1055,18 +1055,36 @@ swfdec_player_lock (SwfdecPlayer *player
 }
 
 void
-swfdec_player_unlock (SwfdecPlayer *player)
+swfdec_player_lock (SwfdecPlayer *player)
 {
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
   g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);
 
+  swfdec_player_lock_soft (player);
+}
+
+/* used for breakpoints */
+void
+swfdec_player_unlock_soft (SwfdecPlayer *player)
+{
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+
   SWFDEC_DEBUG ("UNLOCK");
-  swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (player));
   swfdec_player_update_mouse_cursor (player);
   g_object_thaw_notify (G_OBJECT (player));
   swfdec_player_emit_signals (player);
 }
 
+void
+swfdec_player_unlock (SwfdecPlayer *player)
+{
+  g_return_if_fail (SWFDEC_IS_PLAYER (player));
+  g_assert (swfdec_ring_buffer_get_n_elements (player->actions) == 0);
+
+  swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (player));
+  swfdec_player_unlock_soft (player);
+}
+
 static gboolean
 swfdec_accumulate_or (GSignalInvocationHint *ihint, GValue *return_accu, 
     const GValue *handler_return, gpointer data)
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index 0d27ec8..0c7ed68 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -148,7 +148,9 @@ void		swfdec_player_remove_movie	(Swfdec
 						 SwfdecMovie *		movie);
 
 void		swfdec_player_lock		(SwfdecPlayer *		player);
+void		swfdec_player_lock_soft		(SwfdecPlayer *		player);
 void		swfdec_player_unlock		(SwfdecPlayer *		player);
+void		swfdec_player_unlock_soft	(SwfdecPlayer *		player);
 void		swfdec_player_perform_actions	(SwfdecPlayer *		player);
 
 SwfdecAsObject *swfdec_player_get_export_class	(SwfdecPlayer *		player,
diff-tree df83f6880be9203515164615fae3da464d36027b (from 1ffa1414f746e1ae2c7cce75518419a501428c83)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 11:12:43 2007 +0200

    maybe GC after function calls

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 0b13eaa..958b459 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -207,6 +207,8 @@ vivi_application_check (ViviApplication 
   gboolean is_playing = swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (app->player));
   gboolean is_breakpoint = app->loop != NULL;
 
+  swfdec_as_context_maybe_gc (SWFDEC_AS_CONTEXT (app));
+
   switch (app->playback_state) {
     case VIVI_APPLICATION_STOPPED:
       if (is_playing)
diff-tree 1ffa1414f746e1ae2c7cce75518419a501428c83 (from f78c7cf7699db1844c0215bd637105b367d86912)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 10:40:23 2007 +0200

    return TRUE for consumed key press/reelease events
    
    This gets around those events changing focus, so the widget is still focused
    after pressing tab

diff --git a/libswfdec-gtk/swfdec_gtk_widget.c b/libswfdec-gtk/swfdec_gtk_widget.c
index 61cffca..94b7f31 100644
--- a/libswfdec-gtk/swfdec_gtk_widget.c
+++ b/libswfdec-gtk/swfdec_gtk_widget.c
@@ -166,6 +166,7 @@ swfdec_gtk_widget_key_press (GtkWidget *
       swfdec_player_key_press (priv->player, keycode, 
 	  gdk_keyval_to_unicode (event->keyval));
     }
+    return TRUE;
   }
 
   return FALSE;
@@ -183,6 +184,7 @@ swfdec_gtk_widget_key_release (GtkWidget
       swfdec_player_key_release (priv->player, keycode, 
 	  gdk_keyval_to_unicode (event->keyval));
     }
+    return TRUE;
   }
 
   return FALSE;
diff-tree f78c7cf7699db1844c0215bd637105b367d86912 (from e6ae2a00a9b1aadbbc45cea54cefe6bfa60f023b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Aug 14 10:27:07 2007 +0200

    add a method to stop a running player

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index a87aa55..0b13eaa 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -290,6 +290,15 @@ vivi_application_play (ViviApplication *
 }
 
 void
+vivi_application_stop (ViviApplication *app)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  app->playback_state = VIVI_APPLICATION_STOPPED;
+  app->playback_count = 0;
+}
+
+void
 vivi_application_step (ViviApplication *app, guint n_times)
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index d250989..fab0262 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -81,6 +81,7 @@ SwfdecPlayer *	      	vivi_application_g
 void			vivi_application_init_player	(ViviApplication *	app);
 void			vivi_application_reset		(ViviApplication *	app);
 void			vivi_application_play		(ViviApplication *	app);
+void			vivi_application_stop		(ViviApplication *	app);
 void			vivi_application_step		(ViviApplication *	app,
 							 guint			n_times);
 
diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index 24814a7..2e72f23 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -45,6 +45,16 @@ vivi_application_as_run (SwfdecAsContext
   vivi_application_play (app);
 }
 
+VIVI_FUNCTION ("stop", vivi_application_as_stop)
+void
+vivi_application_as_stop (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+
+  vivi_application_stop (app);
+}
+
 VIVI_FUNCTION ("step", vivi_application_as_step)
 void
 vivi_application_as_step (SwfdecAsContext *cx, SwfdecAsObject *this, 
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index dfae8f3..d8eadc5 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -21,6 +21,8 @@ Commands = new Object ();
 Commands.print = Native.print;
 Commands.r = Native.run;
 Commands.run = Native.run;
+Commands.halt = Native.stop;
+Commands.stop = Native.stop;
 Commands.s = Native.step;
 Commands.step = Native.step;
 Commands.reset = Native.reset;
diff-tree e6ae2a00a9b1aadbbc45cea54cefe6bfa60f023b (from 304e2632c4cf90212677d717ad4adbb2e050de7e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 22:31:36 2007 +0200

    make sure the player is inited when stepping

diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index f5e68f9..24814a7 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -53,6 +53,7 @@ vivi_application_as_step (SwfdecAsContex
   ViviApplication *app = VIVI_APPLICATION (cx);
   int steps;
 
+  vivi_application_init_player (app);
   if (argc > 0) {
     steps = swfdec_as_value_to_integer (cx, &argv[0]);
     if (steps <= 1)
diff-tree 304e2632c4cf90212677d717ad4adbb2e050de7e (from 9f18261bca69f8c630cb5ba3e2b98694c68fd100)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 22:30:53 2007 +0200

    actually set the filename, so we can play this thing

diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 4a2093c..399483f 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -44,6 +44,7 @@ setup (const char *filename)
   ViviApplication *app;
 
   app = vivi_application_new ();
+  vivi_application_set_filename (app, filename);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
diff-tree 9f18261bca69f8c630cb5ba3e2b98694c68fd100 (from d0cced1cadf66bc1deaeb20b0d9ace5c4f7227c9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 22:28:32 2007 +0200

    make run() and step() actually do something

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index a2b2a95..a87aa55 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -26,6 +26,12 @@
 #include "vivi_function.h"
 #include "vivi_ming.h"
 
+typedef enum {
+  VIVI_APPLICATION_STOPPED,
+  VIVI_APPLICATION_PLAYING,
+  VIVI_APPLICATION_STEPPING,
+} ViviApplicationPlayback;
+
 enum {
   MESSAGE,
   LAST_SIGNAL
@@ -130,10 +136,16 @@ vivi_application_init_player (ViviApplic
 
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
-  if (app->player_inited ||
-      app->filename == NULL)
+  g_print ("init\n");
+  if (app->player_inited)
+    return;
+  
+  if (app->filename == NULL) {
+    vivi_application_error (app, "no file set to play.");
     return;
+  }
 
+  g_print ("really init\n");
   loader = swfdec_file_loader_new (app->filename);
   swfdec_player_set_loader (app->player, loader);
   app->player_inited = TRUE;
@@ -177,6 +189,51 @@ vivi_application_get_player (ViviApplica
   return app->player;
 }
 
+static gboolean
+vivi_application_step_forward (gpointer appp)
+{
+  ViviApplication *app = appp;
+  guint next_event;
+
+  next_event = swfdec_player_get_next_event (app->player);
+  swfdec_player_advance (app->player, next_event);
+
+  return FALSE;
+}
+
+static void
+vivi_application_check (ViviApplication *app)
+{
+  gboolean is_playing = swfdec_gtk_player_get_playing (SWFDEC_GTK_PLAYER (app->player));
+  gboolean is_breakpoint = app->loop != NULL;
+
+  switch (app->playback_state) {
+    case VIVI_APPLICATION_STOPPED:
+      if (is_playing)
+	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
+      break;
+    case VIVI_APPLICATION_PLAYING:
+      if (!is_playing)
+	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), TRUE);
+      if (is_breakpoint)
+	g_main_loop_quit (app->loop);
+      break;
+    case VIVI_APPLICATION_STEPPING:
+      if (is_playing)
+	swfdec_gtk_player_set_playing (SWFDEC_GTK_PLAYER (app->player), FALSE);
+      if (is_breakpoint) {
+	g_main_loop_quit (app->loop);
+      } else {
+	/* FIXME: sanely handle this */
+	g_idle_add_full (-100, vivi_application_step_forward, app, NULL);
+      }
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+}
+
 void
 vivi_applciation_execute (ViviApplication *app, const char *command)
 {
@@ -203,6 +260,7 @@ vivi_applciation_execute (ViviApplicatio
     object = SWFDEC_AS_VALUE_GET_OBJECT (&val);
   swfdec_as_object_run (object, script);
   swfdec_script_unref (script);
+  vivi_application_check (app);
 }
 
 void
@@ -222,25 +280,13 @@ vivi_application_send_message (ViviAppli
   g_free (msg);
 }
 
-typedef enum {
-  VIVI_APPLICATION_STOPPED,
-  VIVI_APPLICATION_PLAYING,
-  VIVI_APPLICATION_STEPPING,
-} ViviApplicationPlayback;
-
-static void
-vivi_application_set_playback (ViviApplication *app, ViviApplicationPlayback playback, guint steps)
-{
-  app->playback_state = playback;
-  app->playback_count = steps;
-}
-
 void
 vivi_application_play (ViviApplication *app)
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
-  vivi_application_set_playback (app, VIVI_APPLICATION_PLAYING, 1);
+  app->playback_state = VIVI_APPLICATION_PLAYING;
+  app->playback_count = 1;
 }
 
 void
@@ -248,5 +294,7 @@ vivi_application_step (ViviApplication *
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
-  vivi_application_set_playback (app, VIVI_APPLICATION_STEPPING, n_times);
+  app->playback_state = VIVI_APPLICATION_STEPPING;
+  app->playback_count = n_times;
 }
+
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index f801c50..d250989 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -50,6 +50,7 @@ struct _ViviApplication
   gboolean		player_inited;	/* if the player is inited already */
   guint			playback_state;	/* (running, stepping or stopped) */
   guint			playback_count;	/* how often to just restart this on breakpoints */
+  GMainLoop *		loop;		/* the breakpoint main loop */
 };
 
 struct _ViviApplicationClass
diff-tree d0cced1cadf66bc1deaeb20b0d9ace5c4f7227c9 (from f49bb00b9cf6d91ec6694e47ac1189b7b1c0c433)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 22:25:45 2007 +0200

    get rid of functions named after reserved strings
    
    also add restart() and reset()

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index e9480a4..dfae8f3 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -19,9 +19,12 @@
 
 Commands = new Object ();
 Commands.print = Native.print;
-Commands.br = Native["break"];
-Commands["break"] = Native["break"];
-Commands.c = Native.play;
-Commands["continue"] = Native.play;
+Commands.r = Native.run;
+Commands.run = Native.run;
 Commands.s = Native.step;
 Commands.step = Native.step;
+Commands.reset = Native.reset;
+Commands.restart = function () {
+  Commands.reset ();
+  Commands.run ();
+};
diff-tree f49bb00b9cf6d91ec6694e47ac1189b7b1c0c433 (from de5020c9352f8d7470d707ff5ee9b1f5c64a281a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 22:25:04 2007 +0200

    don't name functions like reserved words
    
    run => reset
    continue => run

diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index e651248..f5e68f9 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -24,21 +24,19 @@
 #include "vivi_application.h"
 #include "vivi_function.h"
 
-VIVI_FUNCTION ("run", vivi_application_as_run)
+VIVI_FUNCTION ("reset", vivi_application_as_reset)
 void
-vivi_application_as_run (SwfdecAsContext *cx, SwfdecAsObject *this,
+vivi_application_as_reset (SwfdecAsContext *cx, SwfdecAsObject *this,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 {
   ViviApplication *app = VIVI_APPLICATION (cx);
 
   vivi_application_reset (app);
-  vivi_application_init_player (app);
-  vivi_application_play (app);
 }
 
-VIVI_FUNCTION ("continue", vivi_application_as_continue)
+VIVI_FUNCTION ("run", vivi_application_as_run)
 void
-vivi_application_as_continue (SwfdecAsContext *cx, SwfdecAsObject *this,
+vivi_application_as_run (SwfdecAsContext *cx, SwfdecAsObject *this,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 {
   ViviApplication *app = VIVI_APPLICATION (cx);
diff-tree de5020c9352f8d7470d707ff5ee9b1f5c64a281a (from eff171fc6e57dcc745125672485ba2e55463d47d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 19:39:50 2007 +0200

    add hack to get focus to the right widget

diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 590d785..4a2093c 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -29,6 +29,15 @@
 #include "vivi_player.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);
+}
+
+static void
 setup (const char *filename)
 {
   GtkWidget *window, *box, *widget;
@@ -42,6 +51,7 @@ setup (const char *filename)
   gtk_container_add (GTK_CONTAINER (box), widget);
   widget = vivi_command_line_new (app);
   gtk_container_add (GTK_CONTAINER (box), widget);
+  gtk_container_foreach (GTK_CONTAINER (widget), try_grab_focus, NULL);
 
   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
   gtk_widget_show_all (window);
diff-tree eff171fc6e57dcc745125672485ba2e55463d47d (from 746566d83ba51568101d1d71483201cbfbc96e1c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 19:28:20 2007 +0200

    add shortcut mode for calling functions

diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
index 3bf90f7..7003065 100644
--- a/vivified/ui/vivi_commandline.c
+++ b/vivified/ui/vivi_commandline.c
@@ -21,6 +21,7 @@
 #include "config.h"
 #endif
 
+#include <string.h>
 #include "vivi_commandline.h"
 
 G_DEFINE_TYPE (ViviCommandLine, vivi_command_line, VIVI_TYPE_DOCKLET)
@@ -62,6 +63,39 @@ vivi_command_line_class_init (ViviComman
 }
 
 static void
+vivi_command_line_execute (ViviCommandLine *cl, const char *command)
+{
+  char *run;
+
+  if (!strpbrk (command, ";\"',()[]{}")) {
+    /* special mode: interpret as space-delimited list:
+     * first argument is function name, following arguemnts are function arguments
+     */
+    char **args = g_strsplit (command, " ", -1);
+    GString *str = g_string_new (args[0]);
+    guint i;
+
+    g_string_append (str, " (");
+    for (i = 1; args[i] != NULL; i++) {
+      if (i > 1)
+	g_string_append (str, ", ");
+      g_string_append_c (str, '"');
+      g_string_append (str, args[i]);
+      g_string_append_c (str, '"');
+    }
+    g_string_append (str, ");");
+    run = g_string_free (str, FALSE);
+  } else {
+    run = (char *) command;
+  }
+
+  
+  vivi_applciation_execute (cl->app, run);
+  if (command != run)
+    g_free (run);
+}
+
+static void
 command_line_entry_activate_cb (GtkEntry *entry, ViviCommandLine *command_line)
 {
   const char *text = gtk_entry_get_text (entry);
@@ -69,7 +103,7 @@ command_line_entry_activate_cb (GtkEntry
   if (text[0] == '\0')
     return;
 
-  vivi_applciation_execute (command_line->app, text);
+  vivi_command_line_execute (command_line, text);
   gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
 }
 
diff-tree 746566d83ba51568101d1d71483201cbfbc96e1c (from 56a6d3db4c4effe7befb19f64dabc3af16a7f88b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 19:27:56 2007 +0200

    run scripts with "Commands" object as this object

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index eca0eaf..a2b2a95 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -180,6 +180,8 @@ vivi_application_get_player (ViviApplica
 void
 vivi_applciation_execute (ViviApplication *app, const char *command)
 {
+  SwfdecAsValue val;
+  SwfdecAsObject *object;
   SwfdecScript *script;
   char *error = NULL;
 
@@ -193,7 +195,13 @@ vivi_applciation_execute (ViviApplicatio
     g_free (error);
     return;
   }
-  swfdec_as_object_run (SWFDEC_AS_CONTEXT (app)->global, script);
+  object = SWFDEC_AS_CONTEXT (app)->global;
+  swfdec_as_object_get_variable (object, 
+      swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (app), "Commands"),
+      &val);
+  if (SWFDEC_AS_VALUE_IS_OBJECT (&val))
+    object = SWFDEC_AS_VALUE_GET_OBJECT (&val);
+  swfdec_as_object_run (object, script);
   swfdec_script_unref (script);
 }
 
diff-tree 56a6d3db4c4effe7befb19f64dabc3af16a7f88b (from 6fc83760a0d677fb11b348c556d307226b1df053)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 19:27:00 2007 +0200

    crash if init script breaks

diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
index f518515..6fb5197 100644
--- a/vivified/core/vivi_function.c
+++ b/vivified/core/vivi_function.c
@@ -41,6 +41,13 @@ static const struct {
 /* defined in vivi_initialize.s */
 extern const char vivi_initialize[];
 
+static void
+vivi_function_not_reached (ViviApplication *app, guint type, char *message, gpointer unused)
+{
+  if (type == VIVI_MESSAGE_ERROR)
+    g_error ("%s", message);
+}
+
 void
 vivi_function_init_context (ViviApplication *app)
 { 
@@ -61,6 +68,8 @@ vivi_function_init_context (ViviApplicat
       swfdec_as_context_get_string (cx, functions[i].name),
       0, functions[i].fun, 0);
   }
+  g_signal_connect (app, "message", G_CALLBACK (vivi_function_not_reached), NULL);
   vivi_applciation_execute (app, vivi_initialize);
+  g_signal_handlers_disconnect_by_func (app, G_CALLBACK (vivi_function_not_reached), NULL);
 }
 
diff-tree 6fc83760a0d677fb11b348c556d307226b1df053 (from 882e7bcb4894ab334ff18c1ba3386fde7450b780)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 19:10:04 2007 +0200

    lots of fixes
    
    - add copyright header
    - the magic object is named "Commands", not "commands"
    - only init functions that do exist

diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
index 7293fd5..e9480a4 100644
--- a/vivified/core/vivi_initialize.as
+++ b/vivified/core/vivi_initialize.as
@@ -1,8 +1,27 @@
-commands = new Object ();
-commands.print = Native.print;
-commands.br = Native.break;
-commands.break = Native.break;
-commands.c = Native.play;
-commands.continue = Native.play;
-commands.s = Native.step;
-commands.step = Native.step;
+/* Vivified
+ * 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
+ */
+
+Commands = new Object ();
+Commands.print = Native.print;
+Commands.br = Native["break"];
+Commands["break"] = Native["break"];
+Commands.c = Native.play;
+Commands["continue"] = Native.play;
+Commands.s = Native.step;
+Commands.step = Native.step;
diff-tree 882e7bcb4894ab334ff18c1ba3386fde7450b780 (from a4ce7815b625ed24f0350f3e45ce273c7a518a51)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 19:07:10 2007 +0200

    make sure swfdec_initialize.lo gets rebuilt when the as file changes

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 8bd684c..6b0e473 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -11,6 +11,9 @@ libvivified_core_la_SOURCES = \
 	vivi_initialize.s \
 	vivi_ming.c
 
+vivi_initialize.lo: vivi_initialize.s vivi_initialize.as
+	$(LTCCASCOMPILE) -c -o $@ vivi_initialize.s
+
 noinst_HEADERS = \
 	vivi_application.h \
 	vivi_function.h \
diff-tree a4ce7815b625ed24f0350f3e45ce273c7a518a51 (from 412e1924509cc3190c2437a01e097cf36f4e7038)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 18:02:51 2007 +0200

    s/vivi_application_run/vivi_application_execute/

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 4f1915f..eca0eaf 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -178,7 +178,7 @@ vivi_application_get_player (ViviApplica
 }
 
 void
-vivi_application_run (ViviApplication *app, const char *command)
+vivi_applciation_execute (ViviApplication *app, const char *command)
 {
   SwfdecScript *script;
   char *error = NULL;
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index f45540e..f801c50 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -83,7 +83,7 @@ void			vivi_application_play		(ViviAppli
 void			vivi_application_step		(ViviApplication *	app,
 							 guint			n_times);
 
-void			vivi_application_run		(ViviApplication *	app,
+void			vivi_applciation_execute	(ViviApplication *	app,
 							 const char *		command);
 
 G_END_DECLS
diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
index 9762f5a..f518515 100644
--- a/vivified/core/vivi_function.c
+++ b/vivified/core/vivi_function.c
@@ -61,6 +61,6 @@ vivi_function_init_context (ViviApplicat
       swfdec_as_context_get_string (cx, functions[i].name),
       0, functions[i].fun, 0);
   }
-  vivi_application_run (app, vivi_initialize);
+  vivi_applciation_execute (app, vivi_initialize);
 }
 
diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
index 6ae6b03..3bf90f7 100644
--- a/vivified/ui/vivi_commandline.c
+++ b/vivified/ui/vivi_commandline.c
@@ -69,7 +69,7 @@ command_line_entry_activate_cb (GtkEntry
   if (text[0] == '\0')
     return;
 
-  vivi_application_run (command_line->app, text);
+  vivi_applciation_execute (command_line->app, text);
   gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
 }
 
diff-tree 412e1924509cc3190c2437a01e097cf36f4e7038 (from 9cc9d27957f27f1137814ff95a1fb4da8e67669c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 17:16:33 2007 +0200

    really error out on errors

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 071b1ab..4f1915f 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -191,6 +191,7 @@ vivi_application_run (ViviApplication *a
   if (script == NULL) {
     vivi_application_error (app, error);
     g_free (error);
+    return;
   }
   swfdec_as_object_run (SWFDEC_AS_CONTEXT (app)->global, script);
   swfdec_script_unref (script);
diff-tree 9cc9d27957f27f1137814ff95a1fb4da8e67669c (from 8ea4ca0ffef854446d2ddfdb7c979397a7f3da90)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 17:16:15 2007 +0200

    we need an assembler for including the script

diff --git a/configure.ac b/configure.ac
index e9996f4..1303884 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,6 +270,7 @@ AC_ARG_ENABLE(vivified,
 	enable_vivi=$enableval,
 	enable_vivi="no")
 if test "$enable_vivi" = "yes"; then
+	AM_PROG_AS
 	MING_REQUIRED=0.4.0.beta5
 	PKG_CHECK_MODULES(VIVI, libming >= $MING_REQUIRED, HAVE_VIVI=yes, HAVE_VIVI=no)
 	if test "x$HAVE_VIVI" = xyes; then
diff-tree 8ea4ca0ffef854446d2ddfdb7c979397a7f3da90 (from 9a26eb30be715cbf23f4dde1bf1ac95b024254c6)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 17:15:16 2007 +0200

    add support for a hardcoded init script

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 8639fb4..8bd684c 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -7,6 +7,8 @@ libvivified_core_la_SOURCES = \
 	vivi_application.c \
 	vivi_application_as.c \
 	vivi_function.c \
+	vivi_initialize.as \
+	vivi_initialize.s \
 	vivi_ming.c
 
 noinst_HEADERS = \
diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
index 5dc64e1..9762f5a 100644
--- a/vivified/core/vivi_function.c
+++ b/vivified/core/vivi_function.c
@@ -38,6 +38,8 @@ static const struct {
 };
 #undef VIVI_FUNCTION
 
+/* defined in vivi_initialize.s */
+extern const char vivi_initialize[];
 
 void
 vivi_function_init_context (ViviApplication *app)
@@ -57,7 +59,8 @@ vivi_function_init_context (ViviApplicat
   for (i = 0; functions[i].name; i++) {
     swfdec_as_object_add_function (obj,
       swfdec_as_context_get_string (cx, functions[i].name),
-      G_TYPE_NONE, functions[i].fun, 0);
+      0, functions[i].fun, 0);
   }
+  vivi_application_run (app, vivi_initialize);
 }
 
diff --git a/vivified/core/vivi_initialize.as b/vivified/core/vivi_initialize.as
new file mode 100644
index 0000000..7293fd5
--- /dev/null
+++ b/vivified/core/vivi_initialize.as
@@ -0,0 +1,8 @@
+commands = new Object ();
+commands.print = Native.print;
+commands.br = Native.break;
+commands.break = Native.break;
+commands.c = Native.play;
+commands.continue = Native.play;
+commands.s = Native.step;
+commands.step = Native.step;
diff --git a/vivified/core/vivi_initialize.s b/vivified/core/vivi_initialize.s
new file mode 100644
index 0000000..eec00c6
--- /dev/null
+++ b/vivified/core/vivi_initialize.s
@@ -0,0 +1,7 @@
+.section ".rodata"
+.global vivi_initialize
+  .type vivi_initialize, at object
+  .size vivi_initialize, .-vivi_initialize
+vivi_initialize:
+.incbin "vivi_initialize.as"
+.byte 0
diff-tree 9a26eb30be715cbf23f4dde1bf1ac95b024254c6 (from a56f1d2fe63954590ae4f0299af004cc99859131)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 17:12:46 2007 +0200

    make the compiler properly detect errors

diff --git a/vivified/core/vivi_ming.c b/vivified/core/vivi_ming.c
index 3ef14b1..7478fac 100644
--- a/vivified/core/vivi_ming.c
+++ b/vivified/core/vivi_ming.c
@@ -57,6 +57,17 @@ vivi_ming_get_error (void)
 }
 
 static void
+vivi_ming_clear_error (void)
+{
+  char *ret;
+  
+  if (ming_errors != NULL) {
+    ret = vivi_ming_get_error ();
+    g_free (ret);
+  }
+}
+
+static void
 vivi_ming_init (void)
 {
   static gboolean ming_inited = FALSE;
@@ -85,14 +96,16 @@ vivi_ming_compile (const char *code, cha
 
   action = newSWFAction (code);
   data = SWFAction_getByteCode (action, &len);
-  if (data == NULL || len == 0) {
+  if (data == NULL || len <= 1) {
     if (error)
       *error = vivi_ming_get_error ();
-    return NULL;
+    script = NULL;
+  } else {
+    buffer = swfdec_buffer_new_and_alloc (len);
+    memcpy (buffer->data, data, len);
+    script = swfdec_script_new (buffer, "compiled script", 8);
   }
-  buffer = swfdec_buffer_new_and_alloc (len);
-  memcpy (buffer->data, data, len);
-  script = swfdec_script_new (buffer, "compiled script", 8);
+  vivi_ming_clear_error ();
   return script;
 }
 
diff-tree a56f1d2fe63954590ae4f0299af004cc99859131 (from fac1e751e6b978fe7f6c69bcc6359af4fb080da7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 17:00:24 2007 +0200

    don't make the printed text a format string

diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index ac8e0ae..e651248 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -77,6 +77,6 @@ vivi_application_as_print (SwfdecAsConte
     return;
 
   s = swfdec_as_value_to_string (cx, &argv[0]);
-  vivi_application_output (app, s);
+  vivi_application_output (app, "%s", s);
 }
 
diff-tree fac1e751e6b978fe7f6c69bcc6359af4fb080da7 (from 89f494a62f58bca42f675acf9656fdb1023c8618)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 16:59:50 2007 +0200

    actually execute the native function setup code (oops)

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index f93fb16..071b1ab 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -23,6 +23,7 @@
 
 #include <libswfdec-gtk/swfdec-gtk.h>
 #include "vivi_application.h"
+#include "vivi_function.h"
 #include "vivi_ming.h"
 
 enum {
@@ -118,6 +119,7 @@ vivi_application_new (void)
 
   app = g_object_new (VIVI_TYPE_APPLICATION, NULL);
   swfdec_as_context_startup (SWFDEC_AS_CONTEXT (app), 8);
+  vivi_function_init_context (app);
   return app;
 }
 
diff-tree 89f494a62f58bca42f675acf9656fdb1023c8618 (from c8fa0c151546ec27138afd73f3bf2cddd9453aad)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 15:52:52 2007 +0200

    add print function

diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
index 988e650..ac8e0ae 100644
--- a/vivified/core/vivi_application_as.c
+++ b/vivified/core/vivi_application_as.c
@@ -64,3 +64,19 @@ vivi_application_as_step (SwfdecAsContex
   }
   vivi_application_step (app, steps);
 }
+
+VIVI_FUNCTION ("print", vivi_application_as_print)
+void
+vivi_application_as_print (SwfdecAsContext *cx, SwfdecAsObject *this, 
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  const char *s;
+
+  if (argc == 0)
+    return;
+
+  s = swfdec_as_value_to_string (cx, &argv[0]);
+  vivi_application_output (app, s);
+}
+
diff-tree c8fa0c151546ec27138afd73f3bf2cddd9453aad (from 7d3e4b2abaf2803e43a608dd29f2281e6be38df5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 15:37:59 2007 +0200

    have a player widget

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 5509035..2a8ed4a 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -8,8 +8,10 @@ vivified_LDADD = \
 
 vivified_SOURCES = \
 	vivi_commandline.c \
+	vivi_player.c \
 	main.c
 
 noinst_HEADERS = \
-	vivi_commandline.h
+	vivi_commandline.h \
+	vivi_player.h
 
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 1dd43e6..590d785 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -26,6 +26,7 @@
 #include "vivified/core/vivified-core.h"
 #include "vivified/dock/vivified-dock.h"
 #include "vivi_commandline.h"
+#include "vivi_player.h"
 
 static void
 setup (const char *filename)
@@ -37,6 +38,8 @@ setup (const char *filename)
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
+  widget = vivi_player_new (app);
+  gtk_container_add (GTK_CONTAINER (box), widget);
   widget = vivi_command_line_new (app);
   gtk_container_add (GTK_CONTAINER (box), widget);
 
diff --git a/vivified/ui/vivi_player.c b/vivified/ui/vivi_player.c
new file mode 100644
index 0000000..657d169
--- /dev/null
+++ b/vivified/ui/vivi_player.c
@@ -0,0 +1,80 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_player.h"
+#include <libswfdec-gtk/swfdec-gtk.h>
+
+G_DEFINE_TYPE (ViviPlayer, vivi_player, VIVI_TYPE_DOCKLET)
+
+static void
+vivi_player_notify_app (ViviApplication *app, GParamSpec *pspec, ViviPlayer *player)
+{
+  if (g_str_equal (pspec->name, "player")) {
+    swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
+  }
+}
+
+static void
+vivi_player_dispose (GObject *object)
+{
+  ViviPlayer *player = VIVI_PLAYER (object);
+
+  g_signal_handlers_disconnect_by_func (player->app, vivi_player_notify_app, player);
+
+  G_OBJECT_CLASS (vivi_player_parent_class)->dispose (object);
+}
+
+static void
+vivi_player_class_init (ViviPlayerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_player_dispose;
+}
+
+static void
+vivi_player_init (ViviPlayer *player)
+{
+  GtkWidget *box;
+
+  box = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+  gtk_container_add (GTK_CONTAINER (player), box);
+  /* the player */
+  player->player = swfdec_gtk_widget_new (NULL);
+  gtk_container_add (GTK_CONTAINER (box), player->player);
+
+  gtk_widget_show_all (box);
+}
+
+GtkWidget *
+vivi_player_new (ViviApplication *app)
+{
+  ViviPlayer *player;
+
+  player = g_object_new (VIVI_TYPE_PLAYER, "title", "Player", NULL);
+  player->app = app;
+  g_signal_connect (player->app, "notify", G_CALLBACK (vivi_player_notify_app), player);
+  swfdec_gtk_widget_set_player (SWFDEC_GTK_WIDGET (player->player), vivi_application_get_player (app));
+  return GTK_WIDGET (player);
+}
+
diff --git a/vivified/ui/vivi_player.h b/vivified/ui/vivi_player.h
new file mode 100644
index 0000000..9aa9102
--- /dev/null
+++ b/vivified/ui/vivi_player.h
@@ -0,0 +1,57 @@
+/* Vivified
+ * 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 _VIVI_PLAYER_H_
+#define _VIVI_PLAYER_H_
+
+#include <vivified/core/vivified-core.h>
+#include <vivified/dock/vivified-dock.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviPlayer ViviPlayer;
+typedef struct _ViviPlayerClass ViviPlayerClass;
+
+#define VIVI_TYPE_PLAYER                    (vivi_player_get_type())
+#define VIVI_IS_PLAYER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_PLAYER))
+#define VIVI_IS_PLAYER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_PLAYER))
+#define VIVI_PLAYER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_PLAYER, ViviPlayer))
+#define VIVI_PLAYER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_PLAYER, ViviPlayerClass))
+#define VIVI_PLAYER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_PLAYER, ViviPlayerClass))
+
+struct _ViviPlayer {
+  ViviDocklet		docklet;
+
+  ViviApplication *	app;		/* the application we connect to */
+  GtkWidget *		player;		/* SwfdecGtkWidget */
+};
+
+struct _ViviPlayerClass
+{
+  ViviDockletClass    	docklet_class;
+};
+
+GType			vivi_player_get_type   	(void);
+
+GtkWidget *		vivi_player_new		(ViviApplication *	app);
+
+
+G_END_DECLS
+#endif
diff-tree 7d3e4b2abaf2803e43a608dd29f2281e6be38df5 (from 790d893846fd4ea043d10386a29cb4eab5da6d25)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 15:31:07 2007 +0200

    make embedding a second item really work

diff --git a/vivified/dock/vivi_vdock.c b/vivified/dock/vivi_vdock.c
index 1559ec1..d37d563 100644
--- a/vivified/dock/vivi_vdock.c
+++ b/vivified/dock/vivi_vdock.c
@@ -75,20 +75,20 @@ vivi_vdock_add (GtkContainer *container,
   if (vdock->docklets == NULL) {
     GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->add (container, docker);
   } else {
-    /* docklet is in docker */
+    /* docklet is in docker, so we need to use parent */
     GtkWidget *last = gtk_widget_get_parent (vdock->docklets->data);
     GtkWidget *parent = gtk_widget_get_parent (last);
     GtkWidget *paned;
 
-    g_object_ref (parent);
+    g_object_ref (last);
     if (parent == (GtkWidget *) container) {
       GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, last);
     } else {
       gtk_container_remove (GTK_CONTAINER (parent), last);
     }
     paned = gtk_vpaned_new ();
-    gtk_paned_pack1 (GTK_PANED (paned), docker, TRUE, FALSE);
-    gtk_paned_pack2 (GTK_PANED (paned), last, TRUE, FALSE);
+    gtk_paned_pack1 (GTK_PANED (paned), last, TRUE, FALSE);
+    gtk_paned_pack2 (GTK_PANED (paned), docker, TRUE, FALSE);
     g_object_unref (last);
     gtk_widget_show (paned);
     if (parent == (GtkWidget *) container) {
diff-tree 790d893846fd4ea043d10386a29cb4eab5da6d25 (from parents)
Merge: aa9c233ed15e37e156d05f1e296126c2a8933132 37ed222d6ea5305df2c238122be4e31a98af3229
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 13 15:11:04 2007 +0200

    Merge branch 'master' into vivi

diff-tree aa9c233ed15e37e156d05f1e296126c2a8933132 (from 41394382ea0de8a1937d2392baf699e28589f059)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 12 02:02:39 2007 +0200

    add stubs for missing functions

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index b2ec3bd..f93fb16 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -201,6 +201,9 @@ vivi_application_send_message (ViviAppli
   va_list args;
   char *msg;
 
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+  g_return_if_fail (format != NULL);
+
   va_start (args, format);
   msg = g_strdup_vprintf (format, args);
   va_end (args);
@@ -208,3 +211,31 @@ vivi_application_send_message (ViviAppli
   g_free (msg);
 }
 
+typedef enum {
+  VIVI_APPLICATION_STOPPED,
+  VIVI_APPLICATION_PLAYING,
+  VIVI_APPLICATION_STEPPING,
+} ViviApplicationPlayback;
+
+static void
+vivi_application_set_playback (ViviApplication *app, ViviApplicationPlayback playback, guint steps)
+{
+  app->playback_state = playback;
+  app->playback_count = steps;
+}
+
+void
+vivi_application_play (ViviApplication *app)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  vivi_application_set_playback (app, VIVI_APPLICATION_PLAYING, 1);
+}
+
+void
+vivi_application_step (ViviApplication *app, guint n_times)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  vivi_application_set_playback (app, VIVI_APPLICATION_STEPPING, n_times);
+}
diff-tree 41394382ea0de8a1937d2392baf699e28589f059 (from bd466511d940904f33e8b3553f529e1b2eca5c7d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 10 13:14:12 2007 +0200

    add infrastructure for native functions

diff --git a/vivified/core/.gitignore b/vivified/core/.gitignore
index b580c89..da08114 100644
--- a/vivified/core/.gitignore
+++ b/vivified/core/.gitignore
@@ -10,3 +10,5 @@ Makefile.in
 *.la
 *.lo
 *.loT
+
+vivi_function_list.h
diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index 0bcac39..8639fb4 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -5,9 +5,26 @@ libvivified_core_la_LDFLAGS = $(SWFDEC_G
 
 libvivified_core_la_SOURCES = \
 	vivi_application.c \
+	vivi_application_as.c \
+	vivi_function.c \
 	vivi_ming.c
 
 noinst_HEADERS = \
 	vivi_application.h \
+	vivi_function.h \
+	vivi_function_list.h \
 	vivi_ming.h \
 	vivified-core.h
+
+BUILT_SOURCES = \
+	vivi_function_list.h
+
+CLEANFILES = \
+	$(BUILT_SOURCES)
+
+vivi_function_list.h: $(libvivified_core_la_SOURCES)
+	(cd $(srcdir) \
+	  && grep -he "^VIVI_FUNCTION" $(libvivified_core_la_SOURCES) \
+	 ) >> xgen-vfl \
+	&& (cmp -s xgen-vfl swfdec_asnative.h || cp xgen-vfl vivi_function_list.h) \
+	&& rm -f xgen-vfl
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 783a3f9..b2ec3bd 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -122,12 +122,29 @@ vivi_application_new (void)
 }
 
 void
+vivi_application_init_player (ViviApplication *app)
+{
+  SwfdecLoader *loader;
+
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  if (app->player_inited ||
+      app->filename == NULL)
+    return;
+
+  loader = swfdec_file_loader_new (app->filename);
+  swfdec_player_set_loader (app->player, loader);
+  app->player_inited = TRUE;
+}
+
+void
 vivi_application_reset (ViviApplication *app)
 {
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
   g_object_unref (app->player);
   app->player = swfdec_gtk_player_new (NULL);
+  app->player_inited = FALSE;
 }
 
 void
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 40bdc64..f45540e 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -47,6 +47,9 @@ struct _ViviApplication
 
   char *		filename;	/* name of the file we play back or NULL if none set yet */
   SwfdecPlayer *	player;		/* the current player */
+  gboolean		player_inited;	/* if the player is inited already */
+  guint			playback_state;	/* (running, stepping or stopped) */
+  guint			playback_count;	/* how often to just restart this on breakpoints */
 };
 
 struct _ViviApplicationClass
@@ -74,7 +77,12 @@ void			vivi_application_set_filename	(Vi
 const char *		vivi_application_get_filename	(ViviApplication *	app);
 SwfdecPlayer *	      	vivi_application_get_player	(ViviApplication *	app);
 
+void			vivi_application_init_player	(ViviApplication *	app);
 void			vivi_application_reset		(ViviApplication *	app);
+void			vivi_application_play		(ViviApplication *	app);
+void			vivi_application_step		(ViviApplication *	app,
+							 guint			n_times);
+
 void			vivi_application_run		(ViviApplication *	app,
 							 const char *		command);
 
diff --git a/vivified/core/vivi_application_as.c b/vivified/core/vivi_application_as.c
new file mode 100644
index 0000000..988e650
--- /dev/null
+++ b/vivified/core/vivi_application_as.c
@@ -0,0 +1,66 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_application.h"
+#include "vivi_function.h"
+
+VIVI_FUNCTION ("run", vivi_application_as_run)
+void
+vivi_application_as_run (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+
+  vivi_application_reset (app);
+  vivi_application_init_player (app);
+  vivi_application_play (app);
+}
+
+VIVI_FUNCTION ("continue", vivi_application_as_continue)
+void
+vivi_application_as_continue (SwfdecAsContext *cx, SwfdecAsObject *this,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+
+  vivi_application_init_player (app);
+  vivi_application_play (app);
+}
+
+VIVI_FUNCTION ("step", vivi_application_as_step)
+void
+vivi_application_as_step (SwfdecAsContext *cx, SwfdecAsObject *this, 
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
+{
+  ViviApplication *app = VIVI_APPLICATION (cx);
+  int steps;
+
+  if (argc > 0) {
+    steps = swfdec_as_value_to_integer (cx, &argv[0]);
+    if (steps <= 1)
+      steps = 1;
+  } else {
+    steps = 1;
+  }
+  vivi_application_step (app, steps);
+}
diff --git a/vivified/core/vivi_function.c b/vivified/core/vivi_function.c
new file mode 100644
index 0000000..5dc64e1
--- /dev/null
+++ b/vivified/core/vivi_function.c
@@ -0,0 +1,63 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_function.h"
+#include "vivi_function_list.h"
+
+/* include vivi_function_list with special macro definition, so we get a nice
+ * way to initialize it */
+#undef VIVI_FUNCTION
+#define VIVI_FUNCTION(name, fun) \
+  { name, fun },
+static const struct {
+  const char *		name;
+  SwfdecAsNative	fun;
+} functions[] = {
+#include "vivi_function_list.h"
+  { NULL, NULL }
+};
+#undef VIVI_FUNCTION
+
+
+void
+vivi_function_init_context (ViviApplication *app)
+{ 
+  SwfdecAsContext *cx = SWFDEC_AS_CONTEXT (app);
+  SwfdecAsObject *obj;
+  SwfdecAsValue val;
+  guint i;
+
+  obj = swfdec_as_object_new (cx);
+  if (obj == NULL)
+    return;
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, obj);
+  swfdec_as_object_set_variable (cx->global, 
+      swfdec_as_context_get_string (cx, "Native"), &val);
+
+  for (i = 0; functions[i].name; i++) {
+    swfdec_as_object_add_function (obj,
+      swfdec_as_context_get_string (cx, functions[i].name),
+      G_TYPE_NONE, functions[i].fun, 0);
+  }
+}
+
diff --git a/vivified/core/vivi_function.h b/vivified/core/vivi_function.h
new file mode 100644
index 0000000..2642579
--- /dev/null
+++ b/vivified/core/vivi_function.h
@@ -0,0 +1,36 @@
+/* Vivified
+ * 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
+ */
+
+#include <libswfdec/swfdec.h>
+#include <vivified/core/vivi_application.h>
+
+#ifndef _VIVI_FUNCTION_H_
+#define _VIVI_FUNCTION_H_
+
+G_BEGIN_DECLS
+
+
+#define VIVI_FUNCTION(name, fun) \
+  void fun (SwfdecAsContext *cx, SwfdecAsObject *this, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
+
+void		vivi_function_init_context	(ViviApplication *	app);
+
+
+G_END_DECLS
+#endif
diff-tree bd466511d940904f33e8b3553f529e1b2eca5c7d (from 9b937d1fa8a9709dda1e153b22adf63c5df2d445)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 23:22:46 2007 +0200

    have a text output window

diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
index ced3e15..6ae6b03 100644
--- a/vivified/ui/vivi_commandline.c
+++ b/vivified/ui/vivi_commandline.c
@@ -26,9 +26,29 @@
 G_DEFINE_TYPE (ViviCommandLine, vivi_command_line, VIVI_TYPE_DOCKLET)
 
 static void
+vivi_command_line_append_message (ViviApplication *app, guint type, const char *message, GtkTextView *view)
+{
+  GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
+  GtkTextIter iter;
+  GtkTextMark *mark;
+  const char *tag_names[] = { "input", "output", "error" };
+
+  gtk_text_buffer_get_end_iter (buffer, &iter);
+  mark = gtk_text_buffer_get_mark (buffer, "end");
+  if (mark == NULL)
+    mark = gtk_text_buffer_create_mark (buffer, "end", &iter, FALSE);
+  if (gtk_text_buffer_get_char_count (buffer) > 0)
+    gtk_text_buffer_insert (buffer, &iter, "\n", 1);
+  gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1, tag_names[type], NULL);
+  gtk_text_view_scroll_to_mark (view, mark, 0.0, TRUE, 0.0, 0.0);
+}
+
+static void
 vivi_command_line_dispose (GObject *object)
 {
-  //ViviCommandLine *command_line = VIVI_COMMAND_LINE (object);
+  ViviCommandLine *cl = VIVI_COMMAND_LINE (object);
+
+  g_signal_handlers_disconnect_by_func (cl->app, vivi_command_line_append_message, cl->view);
 
   G_OBJECT_CLASS (vivi_command_line_parent_class)->dispose (object);
 }
@@ -49,27 +69,48 @@ command_line_entry_activate_cb (GtkEntry
   if (text[0] == '\0')
     return;
 
-  g_print ("%s\n", text);
-  //swfdec_player_manager_execute (manager, text);
+  vivi_application_run (command_line->app, text);
   gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
 }
 
 static void
-vivi_command_line_init (ViviCommandLine *command_line)
+vivi_command_line_init (ViviCommandLine *cl)
 {
-  GtkWidget *entry;
+  GtkWidget *box, *widget, *scroll;
+
+  box = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (cl), box);
+  /* the text entry */
+  widget = gtk_entry_new ();
+  g_signal_connect (widget, "activate", G_CALLBACK (command_line_entry_activate_cb), cl);
+  gtk_box_pack_end (GTK_BOX (box), widget, FALSE, TRUE, 0);
+  /* the text view for outputting messages */
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), 
+      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
+  cl->view = gtk_text_view_new ();
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (cl->view), FALSE);
+  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (cl->view), GTK_WRAP_WORD_CHAR);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (cl->view)),
+      "error", "foreground", "red", "left-margin", 15, NULL);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (cl->view)),
+      "input", "foreground", "dark grey", NULL);
+  gtk_text_buffer_create_tag (gtk_text_view_get_buffer (GTK_TEXT_VIEW (cl->view)),
+      "output", "left-margin", 15, NULL);
+  gtk_container_add (GTK_CONTAINER (scroll), cl->view);
 
-  entry = gtk_entry_new ();
-  gtk_container_add (GTK_CONTAINER (command_line), entry);
-  g_signal_connect (entry, "activate", G_CALLBACK (command_line_entry_activate_cb), command_line);
+  gtk_widget_show_all (box);
 }
 
 GtkWidget *
 vivi_command_line_new (ViviApplication *app)
 {
-  GtkWidget *cl;
+  ViviCommandLine *cl;
 
   cl = g_object_new (VIVI_TYPE_COMMAND_LINE, "title", "Command Line", NULL);
-  return cl;
+  cl->app = app;
+  g_signal_connect (cl->app, "message", G_CALLBACK (vivi_command_line_append_message), cl->view);
+  return GTK_WIDGET (cl);
 }
 
diff --git a/vivified/ui/vivi_commandline.h b/vivified/ui/vivi_commandline.h
index f38da32..96e5924 100644
--- a/vivified/ui/vivi_commandline.h
+++ b/vivified/ui/vivi_commandline.h
@@ -38,6 +38,9 @@ typedef struct _ViviCommandLineClass Viv
 
 struct _ViviCommandLine {
   ViviDocklet		docklet;
+
+  ViviApplication *	app;		/* the application we connect to */
+  GtkWidget *		view;		/* text view for outputting stuff to */
 };
 
 struct _ViviCommandLineClass
diff-tree 9b937d1fa8a9709dda1e153b22adf63c5df2d445 (from f1b1180d52d93122385178620d984597471fa9d0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 23:22:32 2007 +0200

    add ability to emit messages, just like SwfdecPlayerManager
    
    Also startup the context on init

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index c526580..783a3f9 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -26,12 +26,18 @@
 #include "vivi_ming.h"
 
 enum {
+  MESSAGE,
+  LAST_SIGNAL
+};
+
+enum {
   PROP_0,
   PROP_FILENAME,
   PROP_PLAYER
 };
 
 G_DEFINE_TYPE (ViviApplication, vivi_application, SWFDEC_TYPE_AS_CONTEXT)
+static guint signals[LAST_SIGNAL] = { 0, };
 
 static void
 vivi_application_get_property (GObject *object, guint param_id, GValue *value, 
@@ -93,6 +99,10 @@ vivi_application_class_init (ViviApplica
   g_object_class_install_property (object_class, PROP_PLAYER,
       g_param_spec_object ("player", "player", "Flash player in use",
 	  SWFDEC_TYPE_PLAYER, G_PARAM_READABLE));
+
+  signals[MESSAGE] = g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT_POINTER, /* FIXME */
+      G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
 }
 
 static void
@@ -104,7 +114,11 @@ vivi_application_init (ViviApplication *
 ViviApplication *
 vivi_application_new (void)
 {
-  return g_object_new (VIVI_TYPE_APPLICATION, NULL);
+  ViviApplication *app;
+
+  app = g_object_new (VIVI_TYPE_APPLICATION, NULL);
+  swfdec_as_context_startup (SWFDEC_AS_CONTEXT (app), 8);
+  return app;
 }
 
 void
@@ -153,11 +167,27 @@ vivi_application_run (ViviApplication *a
   g_return_if_fail (VIVI_IS_APPLICATION (app));
   g_return_if_fail (command != NULL);
 
+  vivi_application_input (app, command);
   script = vivi_ming_compile (command, &error);
   if (script == NULL) {
+    vivi_application_error (app, error);
     g_free (error);
   }
   swfdec_as_object_run (SWFDEC_AS_CONTEXT (app)->global, script);
   swfdec_script_unref (script);
 }
 
+void
+vivi_application_send_message (ViviApplication *app,
+    ViviMessageType type, const char *format, ...)
+{
+  va_list args;
+  char *msg;
+
+  va_start (args, format);
+  msg = g_strdup_vprintf (format, args);
+  va_end (args);
+  g_signal_emit (app, signals[MESSAGE], 0, (guint) type, msg);
+  g_free (msg);
+}
+
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 8a21410..40bdc64 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -28,6 +28,12 @@ G_BEGIN_DECLS
 typedef struct _ViviApplication ViviApplication;
 typedef struct _ViviApplicationClass ViviApplicationClass;
 
+typedef enum {
+  VIVI_MESSAGE_INPUT,
+  VIVI_MESSAGE_OUTPUT,
+  VIVI_MESSAGE_ERROR
+} ViviMessageType;
+
 #define VIVI_TYPE_APPLICATION                    (vivi_application_get_type())
 #define VIVI_IS_APPLICATION(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_APPLICATION))
 #define VIVI_IS_APPLICATION_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_APPLICATION))
@@ -52,6 +58,17 @@ GType			vivi_application_get_type   	(vo
 
 ViviApplication *	vivi_application_new		(void);
 
+void			vivi_application_send_message	(ViviApplication *	app,
+							 ViviMessageType	type,
+							 const char *		format, 
+							 ...) G_GNUC_PRINTF (3, 4);
+#define vivi_application_input(manager, ...) \
+  vivi_application_send_message (manager, VIVI_MESSAGE_INPUT, __VA_ARGS__)
+#define vivi_application_output(manager, ...) \
+  vivi_application_send_message (manager, VIVI_MESSAGE_OUTPUT, __VA_ARGS__)
+#define vivi_application_error(manager, ...) \
+  vivi_application_send_message (manager, VIVI_MESSAGE_ERROR, __VA_ARGS__)
+
 void			vivi_application_set_filename	(ViviApplication *	app,
 							 const char *		filename);
 const char *		vivi_application_get_filename	(ViviApplication *	app);
diff-tree f1b1180d52d93122385178620d984597471fa9d0 (from 748618dc3faea26ad390e6a033f96054deb9b020)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 22:17:56 2007 +0200

    add vivi_application_run() function
    
    This requires hooking up ming

diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
index dc15041..0bcac39 100644
--- a/vivified/core/Makefile.am
+++ b/vivified/core/Makefile.am
@@ -1,11 +1,13 @@
 noinst_LTLIBRARIES = libvivified-core.la
 
-libvivified_core_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS)
-libvivified_core_la_LDFLAGS = $(SWFDEC_GTK_LIBS)
+libvivified_core_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS) $(VIVI_CFLAGS)
+libvivified_core_la_LDFLAGS = $(SWFDEC_GTK_LIBS) $(VIVI_LIBS)
 
 libvivified_core_la_SOURCES = \
-	vivi_application.c
+	vivi_application.c \
+	vivi_ming.c
 
 noinst_HEADERS = \
 	vivi_application.h \
+	vivi_ming.h \
 	vivified-core.h
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index dd85bc4..c526580 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -21,8 +21,9 @@
 #include "config.h"
 #endif
 
-#include "vivi_application.h"
 #include <libswfdec-gtk/swfdec-gtk.h>
+#include "vivi_application.h"
+#include "vivi_ming.h"
 
 enum {
   PROP_0,
@@ -143,3 +144,20 @@ vivi_application_get_player (ViviApplica
   return app->player;
 }
 
+void
+vivi_application_run (ViviApplication *app, const char *command)
+{
+  SwfdecScript *script;
+  char *error = NULL;
+
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+  g_return_if_fail (command != NULL);
+
+  script = vivi_ming_compile (command, &error);
+  if (script == NULL) {
+    g_free (error);
+  }
+  swfdec_as_object_run (SWFDEC_AS_CONTEXT (app)->global, script);
+  swfdec_script_unref (script);
+}
+
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
index 6e0df41..8a21410 100644
--- a/vivified/core/vivi_application.h
+++ b/vivified/core/vivi_application.h
@@ -58,6 +58,8 @@ const char *		vivi_application_get_filen
 SwfdecPlayer *	      	vivi_application_get_player	(ViviApplication *	app);
 
 void			vivi_application_reset		(ViviApplication *	app);
+void			vivi_application_run		(ViviApplication *	app,
+							 const char *		command);
 
 G_END_DECLS
 #endif
diff --git a/vivified/core/vivi_ming.c b/vivified/core/vivi_ming.c
new file mode 100644
index 0000000..3ef14b1
--- /dev/null
+++ b/vivified/core/vivi_ming.c
@@ -0,0 +1,98 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_ming.h"
+#include <string.h>
+
+static GString *ming_errors = NULL;
+
+static void
+vivi_ming_error (const char *format, ...)
+{
+  va_list varargs;
+  char *s;
+
+  if (ming_errors) {
+    g_string_append_c (ming_errors, '\n');
+  } else {
+    ming_errors = g_string_new ("");
+  }
+  va_start (varargs, format);
+  g_string_append_vprintf (ming_errors, format, varargs);
+  s = g_strdup_vprintf (format, varargs);
+  va_end (varargs);
+}
+
+static char *
+vivi_ming_get_error (void)
+{
+  char *ret;
+
+  if (ming_errors == NULL)
+    return g_strdup ("Unknown error");
+
+  ret = g_string_free (ming_errors, FALSE);
+  ming_errors = NULL;
+  return ret;
+}
+
+static void
+vivi_ming_init (void)
+{
+  static gboolean ming_inited = FALSE;
+
+  if (ming_inited)
+    return;
+
+  ming_inited = TRUE;
+
+  Ming_init ();
+  Ming_useSWFVersion (8);
+  Ming_setErrorFunction (vivi_ming_error);
+  Ming_setWarnFunction (vivi_ming_error);
+}
+
+SwfdecScript *
+vivi_ming_compile (const char *code, char **error)
+{
+  byte *data;
+  SWFAction action;
+  gsize len;
+  SwfdecBuffer *buffer;
+  SwfdecScript *script;
+
+  vivi_ming_init ();
+
+  action = newSWFAction (code);
+  data = SWFAction_getByteCode (action, &len);
+  if (data == NULL || len == 0) {
+    if (error)
+      *error = vivi_ming_get_error ();
+    return NULL;
+  }
+  buffer = swfdec_buffer_new_and_alloc (len);
+  memcpy (buffer->data, data, len);
+  script = swfdec_script_new (buffer, "compiled script", 8);
+  return script;
+}
+
diff --git a/vivified/core/vivi_ming.h b/vivified/core/vivi_ming.h
new file mode 100644
index 0000000..98d3b85
--- /dev/null
+++ b/vivified/core/vivi_ming.h
@@ -0,0 +1,34 @@
+/* Vivified
+ * 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
+ */
+
+#include <libswfdec/swfdec.h>
+#include <ming.h>
+
+#ifndef _VIVI_MING_H_
+#define _VIVI_MING_H_
+
+G_BEGIN_DECLS
+
+
+SwfdecScript *		vivi_ming_compile		(const char *	code,
+							 char **	error);
+
+
+G_END_DECLS
+#endif
diff-tree 748618dc3faea26ad390e6a033f96054deb9b020 (from 54778c3616f3488668d7ba7b12105ea722b2845a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 20:56:45 2007 +0200

    make swfdec_script_new take ownership of the passed in buffer
    
    And document that behaviour

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index c207435..221e25c 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -199,15 +199,29 @@ validate_action (gconstpointer bytecode,
   return TRUE;
 }
 
+/**
+ * swfdec_script_new:
+ * @buffer: the #SwfdecBuffer containing the script. This function will take
+ *          ownership of the passed in buffer.
+ * @name: name of the script for debugging purposes
+ * @version: Actionscript version to use in this script
+ *
+ * Creates a new script for the actionscript provided in @buffer.
+ *
+ * Returns: a new #SwfdecScript for executing the script i @buffer.
+ **/
 SwfdecScript *
 swfdec_script_new (SwfdecBuffer *buffer, const char *name, guint version)
 {
   SwfdecBits bits;
+  SwfdecScript *script;
 
   g_return_val_if_fail (buffer != NULL, NULL);
 
   swfdec_bits_init (&bits, buffer);
-  return swfdec_script_new_from_bits (&bits, name, version);
+  script = swfdec_script_new_from_bits (&bits, name, version);
+  swfdec_buffer_unref (buffer);
+  return script;
 }
 
 SwfdecScript *
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index 11bb485..34496df 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -322,7 +322,6 @@ swfedit_script_from_string (const char *
   }
 
   script = swfdec_script_new (buffer, "unknown", 6 /* FIXME */);
-  swfdec_buffer_unref (buffer);
   if (script != NULL) {
     *result = script;
     return TRUE;
diff --git a/test/swfscript.c b/test/swfscript.c
index 187aeb5..4e2a9e4 100644
--- a/test/swfscript.c
+++ b/test/swfscript.c
@@ -208,7 +208,6 @@ modify_file (SwfeditToken *token, guint 
       state.buffer->length, state.script->buffer->length);
 #endif
   script = swfdec_script_new (state.buffer, state.script->name, state.script->version);
-  swfdec_buffer_unref (state.buffer);
   g_assert (script);
   swfedit_token_set (token, idx, script);
 
diff-tree 54778c3616f3488668d7ba7b12105ea722b2845a (from 5c17c6e1324644006db930660e04ea910d6d4a6c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 19:15:16 2007 +0200

    move SwfdecScript into the API
    
    this unfortunately requires a new internal header, and all the files need to be
    updated

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index dd62712..fc9d47f 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -136,6 +136,7 @@ public_headers = \
 	swfdec_keys.h \
 	swfdec_loader.h \
 	swfdec_player.h \
+	swfdec_script.h \
 	swfdec_url.h
 
 libswfdec_ at SWFDEC_MAJORMINOR@_la_LIBADD = jpeg/libjpeg.la 
@@ -201,7 +202,7 @@ noinst_HEADERS = \
 	swfdec_player_internal.h \
 	swfdec_rect.h \
 	swfdec_ringbuffer.h \
-	swfdec_script.h \
+	swfdec_script_internal.h \
 	swfdec_shape.h \
 	swfdec_sound.h \
 	swfdec_sprite.h \
diff --git a/libswfdec/swfdec.h b/libswfdec/swfdec.h
index 27e65e9..ec4d136 100644
--- a/libswfdec/swfdec.h
+++ b/libswfdec/swfdec.h
@@ -27,6 +27,7 @@
 #include <libswfdec/swfdec_as_frame.h>
 #include <libswfdec/swfdec_as_object.h>
 #include <libswfdec/swfdec_as_types.h>
+#include <libswfdec/swfdec_script.h>
 
 #include <libswfdec/swfdec_audio.h>
 #include <libswfdec/swfdec_buffer.h>
diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h
index f6d7644..4f613b4 100644
--- a/libswfdec/swfdec_as_frame_internal.h
+++ b/libswfdec/swfdec_as_frame_internal.h
@@ -22,7 +22,7 @@
 
 #include <libswfdec/swfdec_as_scope.h>
 #include <libswfdec/swfdec_as_types.h>
-#include <libswfdec/swfdec_script.h>
+#include <libswfdec/swfdec_script_internal.h>
 
 G_BEGIN_DECLS
 
diff --git a/libswfdec/swfdec_as_internal.h b/libswfdec/swfdec_as_internal.h
index ca6ab2d..5906ef4 100644
--- a/libswfdec/swfdec_as_internal.h
+++ b/libswfdec/swfdec_as_internal.h
@@ -49,8 +49,6 @@ guint		swfdec_as_object_foreach_remove	(
 void		swfdec_as_object_foreach_rename	(SwfdecAsObject *       object,
 						 SwfdecAsVariableForeachRename func,
 						 gpointer		data);
-void		swfdec_as_object_run		(SwfdecAsObject *       object,
-						 SwfdecScript *		script);
 
 void		swfdec_as_object_init_context	(SwfdecAsContext *	context,
 					      	 guint			version);
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 90fd2e2..73907ee 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1551,7 +1551,7 @@ swfdec_action_define_function (SwfdecAsC
   }
   if (name == NULL)
     name = "unnamed_function";
-  script = swfdec_script_new (&bits, name, cx->version);
+  script = swfdec_script_new_from_bits (&bits, name, cx->version);
   if (script == NULL) {
     SWFDEC_ERROR ("failed to create script");
     g_free (args);
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index f82cd9c..7ad1c98 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -151,6 +151,8 @@ void		swfdec_as_object_call		(SwfdecAsOb
 						 guint			argc,
 						 SwfdecAsValue *	argv,
 						 SwfdecAsValue *	return_value);
+void		swfdec_as_object_run		(SwfdecAsObject *       object,
+						 SwfdecScript *		script);
 
 
 G_END_DECLS
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index d435cb9..294df40 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -49,6 +49,8 @@ typedef void (* SwfdecAsNative) (SwfdecA
 				 guint			argc,
 				 SwfdecAsValue *	argv,
 				 SwfdecAsValue *	retval);
+typedef struct _SwfdecScript SwfdecScript;
+
 
 /* IMPORTANT: a SwfdecAsValue memset to 0 is a valid undefined value */
 struct _SwfdecAsValue {
diff --git a/libswfdec/swfdec_color_as.h b/libswfdec/swfdec_color_as.h
index b197f8e..97bc731 100644
--- a/libswfdec/swfdec_color_as.h
+++ b/libswfdec/swfdec_color_as.h
@@ -22,7 +22,7 @@
 
 #include <libswfdec/swfdec_as_object.h>
 #include <libswfdec/swfdec_as_types.h>
-#include <libswfdec/swfdec_script.h>
+#include <libswfdec/swfdec_movie.h>
 
 G_BEGIN_DECLS
 
diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c
index 26c4dfb..5474248 100644
--- a/libswfdec/swfdec_event.c
+++ b/libswfdec/swfdec_event.c
@@ -25,7 +25,7 @@
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
-#include "swfdec_script.h"
+#include "swfdec_script_internal.h"
 
 typedef struct _SwfdecEvent SwfdecEvent;
 
@@ -202,7 +202,7 @@ swfdec_event_list_parse (SwfdecEventList
   event.key = key;
   name = g_strconcat (description, ".", 
       swfdec_event_list_condition_name (conditions), NULL);
-  event.script = swfdec_script_new (bits, name, version);
+  event.script = swfdec_script_new_from_bits (bits, name, version);
   g_free (name);
   if (event.script) 
     g_array_append_val (list->events, event);
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index a1acf87..e1c7748 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -40,7 +40,7 @@
 #include "swfdec_loader_internal.h"
 #include "swfdec_marshal.h"
 #include "swfdec_movie.h"
-#include "swfdec_script.h"
+#include "swfdec_script_internal.h"
 #include "swfdec_sprite_movie.h"
 #include "swfdec_swf_instance.h"
 
@@ -1432,7 +1432,7 @@ swfdec_player_initialize (SwfdecPlayer *
       SwfdecBits bits;
       SwfdecScript *script;
       swfdec_bits_init_data (&bits, swfdec_initialize, sizeof (swfdec_initialize));
-      script = swfdec_script_new (&bits, "init", version);
+      script = swfdec_script_new_from_bits (&bits, "init", version);
       g_assert (script);
       swfdec_as_object_run (context->global, script);
       swfdec_script_unref (script);
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 87f2010..c207435 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "swfdec_script.h"
+#include "swfdec_script_internal.h"
 #include "swfdec_as_context.h"
 #include "swfdec_as_interpret.h"
 #include "swfdec_debug.h"
@@ -199,7 +200,18 @@ validate_action (gconstpointer bytecode,
 }
 
 SwfdecScript *
-swfdec_script_new (SwfdecBits *bits, const char *name, guint version)
+swfdec_script_new (SwfdecBuffer *buffer, const char *name, guint version)
+{
+  SwfdecBits bits;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+
+  swfdec_bits_init (&bits, buffer);
+  return swfdec_script_new_from_bits (&bits, name, version);
+}
+
+SwfdecScript *
+swfdec_script_new_from_bits (SwfdecBits *bits, const char *name, guint version)
 {
   SwfdecScript *script;
   SwfdecBits org;
diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h
index 6a0870b..fe90428 100644
--- a/libswfdec/swfdec_script.h
+++ b/libswfdec/swfdec_script.h
@@ -20,76 +20,18 @@
 #ifndef _SWFDEC_SCRIPT_H_
 #define _SWFDEC_SCRIPT_H_
 
-#include <libswfdec/swfdec.h>
 #include <libswfdec/swfdec_as_types.h>
-#include <libswfdec/swfdec_types.h>
-#include <libswfdec/swfdec_bits.h>
+#include <libswfdec/swfdec_buffer.h>
 
 G_BEGIN_DECLS
 
-//typedef struct _SwfdecScript SwfdecScript;
-typedef struct _SwfdecScriptArgument SwfdecScriptArgument;
-typedef struct _SwfdecConstantPool SwfdecConstantPool;
-
-typedef enum {
-  SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0),
-  SWFDEC_SCRIPT_SUPPRESS_THIS = (1 << 1),
-  SWFDEC_SCRIPT_PRELOAD_ARGS = (1 << 2),
-  SWFDEC_SCRIPT_SUPPRESS_ARGS = (1 << 3),
-  SWFDEC_SCRIPT_PRELOAD_SUPER = (1 << 4),
-  SWFDEC_SCRIPT_SUPPRESS_SUPER = (1 << 5),
-  SWFDEC_SCRIPT_PRELOAD_ROOT = (1 << 6),
-  SWFDEC_SCRIPT_PRELOAD_PARENT = (1 << 7),
-  SWFDEC_SCRIPT_PRELOAD_GLOBAL = (1 << 8)
-} SwfdecScriptFlag;
-
-typedef gboolean (* SwfdecScriptForeachFunc) (gconstpointer bytecode, guint action, 
-    const guint8 *data, guint len, gpointer user_data);
-
-/* FIXME: May want to typedef to SwfdecBuffer directly */
-struct _SwfdecScript {
-  SwfdecBuffer *	buffer;			/* buffer holding the script */
-  guint		 	refcount;		/* reference count */
-  char *		name;			/* name identifying this script */
-  guint			version;		/* version of the script */
-  guint			n_registers;		/* number of registers */
-  SwfdecBuffer *	constant_pool;		/* constant pool action */
-  guint			flags;			/* SwfdecScriptFlags */
-  guint			n_arguments;  		/* number of arguments */
-  SwfdecScriptArgument *arguments;		/* arguments or NULL if none */
-};
-
-struct _SwfdecScriptArgument {
-  char *		name;			/* name of the argument (not GC'ed) */
-  guint			preload;		/* preload slot to preload to or 0 */
-};
-
-const char *	swfdec_action_get_name		(guint			action);
-guint		swfdec_action_get_from_name	(const char *		name);
-
-SwfdecConstantPool *
-		swfdec_constant_pool_new_from_action	(const guint8 *		data,
-							 guint			len,
-							 guint			version);
-void		swfdec_constant_pool_free	  	(SwfdecConstantPool *	pool);
-guint		swfdec_constant_pool_size		(SwfdecConstantPool *	pool);
-const char *	swfdec_constant_pool_get		(SwfdecConstantPool *	pool,
-							 guint			i);
-void		swfdec_constant_pool_attach_to_context	(SwfdecConstantPool *	pool,
-							 SwfdecAsContext *	context);
 
-SwfdecScript *	swfdec_script_new			(SwfdecBits *		bits,
+SwfdecScript *	swfdec_script_new			(SwfdecBuffer *		buffer,
 							 const char *		name,
 							 guint			version);
 SwfdecScript *	swfdec_script_ref			(SwfdecScript *		script);
 void		swfdec_script_unref			(SwfdecScript *		script);
 
-gboolean	swfdec_script_foreach			(SwfdecScript *		script,
-							 SwfdecScriptForeachFunc func,
-							 gpointer		user_data);
-char *		swfdec_script_print_action		(guint			action,
-							 const guint8 *		data,
-							 guint			len);
 
 G_END_DECLS
 
diff --git a/libswfdec/swfdec_script_internal.h b/libswfdec/swfdec_script_internal.h
new file mode 100644
index 0000000..aee0b94
--- /dev/null
+++ b/libswfdec/swfdec_script_internal.h
@@ -0,0 +1,93 @@
+/* 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_SCRIPT_INTERNAL_H_
+#define _SWFDEC_SCRIPT_INTERNAL_H_
+
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_as_types.h>
+#include <libswfdec/swfdec_types.h>
+#include <libswfdec/swfdec_bits.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecScriptArgument SwfdecScriptArgument;
+typedef struct _SwfdecConstantPool SwfdecConstantPool;
+
+typedef enum {
+  SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0),
+  SWFDEC_SCRIPT_SUPPRESS_THIS = (1 << 1),
+  SWFDEC_SCRIPT_PRELOAD_ARGS = (1 << 2),
+  SWFDEC_SCRIPT_SUPPRESS_ARGS = (1 << 3),
+  SWFDEC_SCRIPT_PRELOAD_SUPER = (1 << 4),
+  SWFDEC_SCRIPT_SUPPRESS_SUPER = (1 << 5),
+  SWFDEC_SCRIPT_PRELOAD_ROOT = (1 << 6),
+  SWFDEC_SCRIPT_PRELOAD_PARENT = (1 << 7),
+  SWFDEC_SCRIPT_PRELOAD_GLOBAL = (1 << 8)
+} SwfdecScriptFlag;
+
+typedef gboolean (* SwfdecScriptForeachFunc) (gconstpointer bytecode, guint action, 
+    const guint8 *data, guint len, gpointer user_data);
+
+/* FIXME: May want to typedef to SwfdecBuffer directly */
+struct _SwfdecScript {
+  SwfdecBuffer *	buffer;			/* buffer holding the script */
+  guint		 	refcount;		/* reference count */
+  char *		name;			/* name identifying this script */
+  guint			version;		/* version of the script */
+  guint			n_registers;		/* number of registers */
+  SwfdecBuffer *	constant_pool;		/* constant pool action */
+  guint			flags;			/* SwfdecScriptFlags */
+  guint			n_arguments;  		/* number of arguments */
+  SwfdecScriptArgument *arguments;		/* arguments or NULL if none */
+};
+
+struct _SwfdecScriptArgument {
+  char *		name;			/* name of the argument (not GC'ed) */
+  guint			preload;		/* preload slot to preload to or 0 */
+};
+
+const char *	swfdec_action_get_name		(guint			action);
+guint		swfdec_action_get_from_name	(const char *		name);
+
+SwfdecConstantPool *
+		swfdec_constant_pool_new_from_action	(const guint8 *		data,
+							 guint			len,
+							 guint			version);
+void		swfdec_constant_pool_free	  	(SwfdecConstantPool *	pool);
+guint		swfdec_constant_pool_size		(SwfdecConstantPool *	pool);
+const char *	swfdec_constant_pool_get		(SwfdecConstantPool *	pool,
+							 guint			i);
+void		swfdec_constant_pool_attach_to_context	(SwfdecConstantPool *	pool,
+							 SwfdecAsContext *	context);
+
+SwfdecScript *	swfdec_script_new_from_bits   		(SwfdecBits *		bits,
+							 const char *		name,
+							 guint			version);
+
+gboolean	swfdec_script_foreach			(SwfdecScript *		script,
+							 SwfdecScriptForeachFunc func,
+							 gpointer		user_data);
+char *		swfdec_script_print_action		(guint			action,
+							 const guint8 *		data,
+							 guint			len);
+
+G_END_DECLS
+
+#endif
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index 1521e6f..3f67ebc 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -36,6 +36,7 @@
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
 #include "swfdec_script.h"
+#include "swfdec_script_internal.h"
 #include "swfdec_sprite.h"
 
 enum {
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index a8b77fc..82ac572 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -39,7 +39,7 @@
 #include "swfdec_movie.h" /* for SwfdecContent */
 #include "swfdec_pattern.h"
 #include "swfdec_player_internal.h"
-#include "swfdec_script.h"
+#include "swfdec_script_internal.h"
 #include "swfdec_shape.h"
 #include "swfdec_sound.h"
 #include "swfdec_sprite.h"
@@ -545,7 +545,7 @@ tag_func_do_init_action (SwfdecSwfDecode
     return SWFDEC_STATUS_OK;
   }
   name = g_strdup_printf ("InitAction %u", id);
-  sprite->init_action = swfdec_script_new (bits, name, s->version);
+  sprite->init_action = swfdec_script_new_from_bits (bits, name, s->version);
   g_free (name);
   if (sprite->init_action) {
     swfdec_script_ref (sprite->init_action);
@@ -594,7 +594,7 @@ tag_func_do_action (SwfdecSwfDecoder * s
 
   name = g_strdup_printf ("Sprite%u_Frame%u", SWFDEC_CHARACTER (s->parse_sprite)->id,
       s->parse_sprite->parse_frame);
-  script = swfdec_script_new (&s->b, name, s->version);
+  script = swfdec_script_new_from_bits (&s->b, name, s->version);
   g_free (name);
   if (script) {
     swfdec_swf_decoder_add_script (s, script);
diff --git a/libswfdec/swfdec_types.h b/libswfdec/swfdec_types.h
index 44edd85..907ac87 100644
--- a/libswfdec/swfdec_types.h
+++ b/libswfdec/swfdec_types.h
@@ -49,7 +49,6 @@ typedef struct _SwfdecShape SwfdecShape;
 typedef struct _SwfdecShapeVec SwfdecShapeVec;
 typedef struct _SwfdecRect SwfdecRect;
 typedef struct _SwfdecRootSprite SwfdecRootSprite;
-typedef struct _SwfdecScript SwfdecScript;
 typedef struct _SwfdecScriptable SwfdecScriptable;
 typedef struct _SwfdecSound SwfdecSound;
 typedef struct _SwfdecSoundChunk SwfdecSoundChunk;
diff --git a/player/swfdec_debug_scripts.c b/player/swfdec_debug_scripts.c
index 3877da8..14471c3 100644
--- a/player/swfdec_debug_scripts.c
+++ b/player/swfdec_debug_scripts.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "swfdec_debug_scripts.h"
+#include <libswfdec/swfdec_script_internal.h>
 
 G_DEFINE_TYPE (SwfdecDebugScripts, swfdec_debug_scripts, GTK_TYPE_TREE_VIEW)
 
diff --git a/player/swfdec_player_manager.c b/player/swfdec_player_manager.c
index 1ff9fbf..7eb1edc 100644
--- a/player/swfdec_player_manager.c
+++ b/player/swfdec_player_manager.c
@@ -26,6 +26,7 @@
 #include <libswfdec/swfdec_debugger.h>
 #include <libswfdec/swfdec_as_object.h>
 #include "swfdec_player_manager.h"
+#include <libswfdec/swfdec_script_internal.h>
 #include <libswfdec-gtk/swfdec_source.h>
 
 enum {
diff --git a/test/swfedit_tag.c b/test/swfedit_tag.c
index b2f887a..0b6b8c2 100644
--- a/test/swfedit_tag.c
+++ b/test/swfedit_tag.c
@@ -26,7 +26,7 @@
 
 #include <libswfdec/swfdec_bits.h>
 #include <libswfdec/swfdec_debug.h>
-#include <libswfdec/swfdec_script.h>
+#include <libswfdec/swfdec_script_internal.h>
 #include <libswfdec/swfdec_tag.h>
 #include "swfedit_tag.h"
 #include "swfdec_out.h"
@@ -217,7 +217,7 @@ swfedit_script_read (SwfeditToken *token
     token = token->parent;
   if (!SWFEDIT_IS_FILE (token))
     return NULL;
-  return swfdec_script_new (bits, "original script", swfedit_file_get_version (SWFEDIT_FILE (token)));
+  return swfdec_script_new_from_bits (bits, "original script", swfedit_file_get_version (SWFEDIT_FILE (token)));
 }
 
 static void
diff --git a/test/swfedit_token.c b/test/swfedit_token.c
index dfb55db..11bb485 100644
--- a/test/swfedit_token.c
+++ b/test/swfedit_token.c
@@ -26,7 +26,7 @@
 #include <gtk/gtk.h>
 #include <libswfdec/swfdec_buffer.h>
 #include <libswfdec/swfdec_color.h>
-#include <libswfdec/swfdec_script.h>
+#include <libswfdec/swfdec_script_internal.h>
 #include "swfedit_token.h"
 
 /*** CONVERTERS ***/
@@ -315,15 +315,13 @@ static gboolean
 swfedit_script_from_string (const char *s, gpointer* result)
 {
   gpointer buffer;
-  SwfdecBits bits;
   SwfdecScript *script;
   
   if (!swfedit_binary_from_string (s, &buffer)) {
     return FALSE;
   }
 
-  swfdec_bits_init (&bits, buffer);
-  script = swfdec_script_new (&bits, "unknown", 6 /* FIXME */);
+  script = swfdec_script_new (buffer, "unknown", 6 /* FIXME */);
   swfdec_buffer_unref (buffer);
   if (script != NULL) {
     *result = script;
diff --git a/test/swfscript.c b/test/swfscript.c
index e53a3d9..187aeb5 100644
--- a/test/swfscript.c
+++ b/test/swfscript.c
@@ -22,7 +22,7 @@
 #endif
 
 #include <gtk/gtk.h>
-#include "libswfdec/swfdec_script.h"
+#include "libswfdec/swfdec_script_internal.h"
 #include "swfdec_out.h"
 #include "swfedit_file.h"
 
@@ -162,7 +162,6 @@ modify_file (SwfeditToken *token, guint 
     SwfeditTokenType type, gconstpointer value, gpointer data)
 {
   Action end;
-  SwfdecBits bits;
   SwfdecScript *script;
   State state;
 
@@ -208,8 +207,7 @@ modify_file (SwfeditToken *token, guint 
   g_print ("got a new script in %u bytes - old script was %u bytes\n", 
       state.buffer->length, state.script->buffer->length);
 #endif
-  swfdec_bits_init (&bits, state.buffer);
-  script = swfdec_script_new (&bits, state.script->name, state.script->version);
+  script = swfdec_script_new (state.buffer, state.script->name, state.script->version);
   swfdec_buffer_unref (state.buffer);
   g_assert (script);
   swfedit_token_set (token, idx, script);
diff-tree 5c17c6e1324644006db930660e04ea910d6d4a6c (from a9149d4d660483affd985c5a854e2a55b0fdb923)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 17:07:53 2007 +0200

    make swfdec_gtk_player_new () take an optional debugger argument

diff --git a/libswfdec-gtk/swfdec_gtk_player.c b/libswfdec-gtk/swfdec_gtk_player.c
index 06a71c5..485f708 100644
--- a/libswfdec-gtk/swfdec_gtk_player.c
+++ b/libswfdec-gtk/swfdec_gtk_player.c
@@ -160,6 +160,7 @@ swfdec_gtk_player_init (SwfdecGtkPlayer 
 
 /**
  * swfdec_gtk_player_new:
+ * @debugger: %NULL or a #SwfdecAsDebugger to debug this player
  *
  * Creates a new Swfdec Gtk player.
  * This function calls swfdec_init () for you if it wasn't called before.
@@ -167,12 +168,12 @@ swfdec_gtk_player_init (SwfdecGtkPlayer 
  * Returns: The new player
  **/
 SwfdecPlayer *
-swfdec_gtk_player_new (void)
+swfdec_gtk_player_new (SwfdecAsDebugger *debugger)
 {
   SwfdecPlayer *player;
 
   swfdec_init ();
-  player = g_object_new (SWFDEC_TYPE_GTK_PLAYER, NULL);
+  player = g_object_new (SWFDEC_TYPE_GTK_PLAYER, "debugger", debugger, NULL);
 
   return player;
 }
@@ -198,8 +199,8 @@ swfdec_gtk_player_new_from_uri (const ch
 
   g_return_val_if_fail (uri != NULL, NULL);
 
+  player = swfdec_gtk_player_new (NULL);
   loader = swfdec_gtk_loader_new (uri);
-  player = swfdec_gtk_player_new ();
   swfdec_player_set_loader (player, loader);
 
   return player;
diff --git a/libswfdec-gtk/swfdec_gtk_player.h b/libswfdec-gtk/swfdec_gtk_player.h
index b040fe9..a8a9b30 100644
--- a/libswfdec-gtk/swfdec_gtk_player.h
+++ b/libswfdec-gtk/swfdec_gtk_player.h
@@ -36,7 +36,7 @@ typedef struct _SwfdecGtkPlayerClass Swf
 
 GType 		swfdec_gtk_player_get_type    	(void);
 
-SwfdecPlayer *	swfdec_gtk_player_new	      	(void);
+SwfdecPlayer *	swfdec_gtk_player_new	      	(SwfdecAsDebugger *	debugger);
 SwfdecPlayer *	swfdec_gtk_player_new_from_uri	(const char *		uri);
 
 void		swfdec_gtk_player_set_playing 	(SwfdecGtkPlayer *	player,
diff --git a/player/swfplay.c b/player/swfplay.c
index c4f8523..23e3f8f 100644
--- a/player/swfplay.c
+++ b/player/swfplay.c
@@ -136,7 +136,7 @@ main (int argc, char *argv[])
     g_object_unref (loader);
     return 1;
   }
-  player = swfdec_gtk_player_new ();
+  player = swfdec_gtk_player_new (NULL);
   if (trace)
     g_signal_connect (player, "trace", G_CALLBACK (print_trace), NULL);
   
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index a56ecab..dd85bc4 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -97,7 +97,7 @@ vivi_application_class_init (ViviApplica
 static void
 vivi_application_init (ViviApplication *app)
 {
-  app->player = swfdec_gtk_player_new ();
+  app->player = swfdec_gtk_player_new (NULL);
 }
 
 ViviApplication *
@@ -112,7 +112,7 @@ vivi_application_reset (ViviApplication 
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
   g_object_unref (app->player);
-  app->player = swfdec_gtk_player_new ();
+  app->player = swfdec_gtk_player_new (NULL);
 }
 
 void
diff-tree a9149d4d660483affd985c5a854e2a55b0fdb923 (from 510ecc39d83221ead3735a72c2ec044111ac299c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 17:05:14 2007 +0200

    make swfdec_player_new () take an optional debugger argument

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 98ded92..a1acf87 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1509,6 +1509,7 @@ swfdec_player_set_export_class (SwfdecPl
 
 /**
  * swfdec_player_new:
+ * @debugger: %NULL or a #SwfdecAsDebugger to use for debugging this player.
  *
  * Creates a new player.
  * This function calls swfdec_init () for you if it wasn't called before.
@@ -1516,12 +1517,12 @@ swfdec_player_set_export_class (SwfdecPl
  * Returns: The new player
  **/
 SwfdecPlayer *
-swfdec_player_new (void)
+swfdec_player_new (SwfdecAsDebugger *debugger)
 {
   SwfdecPlayer *player;
 
   swfdec_init ();
-  player = g_object_new (SWFDEC_TYPE_PLAYER, NULL);
+  player = g_object_new (SWFDEC_TYPE_PLAYER, "debugger", debugger, NULL);
 
   return player;
 }
@@ -1597,7 +1598,7 @@ swfdec_player_new_from_file (const char 
   g_return_val_if_fail (filename != NULL, NULL);
 
   loader = swfdec_file_loader_new (filename);
-  player = swfdec_player_new ();
+  player = swfdec_player_new (NULL);
   swfdec_player_set_loader (player, loader);
 
   return player;
diff --git a/libswfdec/swfdec_player.h b/libswfdec/swfdec_player.h
index 905235a..aba2b62 100644
--- a/libswfdec/swfdec_player.h
+++ b/libswfdec/swfdec_player.h
@@ -22,6 +22,7 @@
 
 #include <glib-object.h>
 #include <cairo.h>
+#include <libswfdec/swfdec_as_types.h>
 #include <libswfdec/swfdec_loader.h>
 
 G_BEGIN_DECLS
@@ -66,7 +67,7 @@ void		swfdec_init			(void);
 
 GType		swfdec_player_get_type		(void);
 
-SwfdecPlayer *	swfdec_player_new		(void);
+SwfdecPlayer *	swfdec_player_new		(SwfdecAsDebugger *	debugger);
 SwfdecPlayer *	swfdec_player_new_from_file	(const char *	filename);
 void		swfdec_player_set_loader	(SwfdecPlayer *	player,
 						 SwfdecLoader *	loader);
diff --git a/test/image/image.c b/test/image/image.c
index 70e6f43..e50c9c6 100644
--- a/test/image/image.c
+++ b/test/image/image.c
@@ -167,7 +167,7 @@ run_test (const char *filename)
     g_object_unref (loader);
     goto error;
   }
-  player = swfdec_player_new ();
+  player = swfdec_player_new (NULL);
   swfdec_player_set_loader (player, loader);
 
   for (i = 0; i < 10; i++) {
diff --git a/test/sound/sound.c b/test/sound/sound.c
index c962453..2053446 100644
--- a/test/sound/sound.c
+++ b/test/sound/sound.c
@@ -206,7 +206,7 @@ run_test (const char *filename)
     g_object_unref (loader);
     goto error;
   }
-  player = swfdec_player_new ();
+  player = swfdec_player_new (NULL);
   g_signal_connect (player, "audio-added", G_CALLBACK (audio_added), &data);
   g_signal_connect (player, "audio-removed", G_CALLBACK (audio_removed), &data);
   g_signal_connect (player, "advance", G_CALLBACK (render_all_streams), &data);
diff --git a/test/trace/trace.c b/test/trace/trace.c
index 0f986e5..99d6a5a 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -100,7 +100,7 @@ run_test (gpointer testp, gpointer unuse
     goto fail;
   }
   string = g_string_new ("");
-  player = swfdec_player_new ();
+  player = swfdec_player_new (NULL);
   g_signal_connect (player, "trace", G_CALLBACK (trace_cb), string);
   g_signal_connect (player, "fscommand", G_CALLBACK (fscommand_cb), &quit);
   swfdec_player_set_loader (player, loader);
diff-tree 510ecc39d83221ead3735a72c2ec044111ac299c (from 70d532781b8e404e33afe989d94d7d3fa14ad90c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 17:03:08 2007 +0200

    we use gtk players unconditionally

diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 496eadf..a56ecab 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -112,7 +112,7 @@ vivi_application_reset (ViviApplication 
   g_return_if_fail (VIVI_IS_APPLICATION (app));
 
   g_object_unref (app->player);
-  app->player = swfdec_player_new ();
+  app->player = swfdec_gtk_player_new ();
 }
 
 void
diff-tree 70d532781b8e404e33afe989d94d7d3fa14ad90c (from 260be3fc109be6884aba0d01a9f9429ab4099562)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 16:59:06 2007 +0200

    make the SwfdecAsContext have a debugger property

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 49ec05e..1a311e9 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -417,10 +417,47 @@ enum {
   LAST_SIGNAL
 };
 
+enum {
+  PROP_0,
+  PROP_DEBUGGER,
+};
+
 G_DEFINE_TYPE (SwfdecAsContext, swfdec_as_context, G_TYPE_OBJECT)
 static guint signals[LAST_SIGNAL] = { 0, };
 
 static void
+swfdec_as_context_get_property (GObject *object, guint param_id, GValue *value, 
+    GParamSpec * pspec)
+{
+  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
+
+  switch (param_id) {
+    case PROP_DEBUGGER:
+      g_value_set_object (value, context->debugger);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+swfdec_as_context_set_property (GObject *object, guint param_id, const GValue *value, 
+    GParamSpec * pspec)
+{
+  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
+
+  switch (param_id) {
+    case PROP_DEBUGGER:
+      context->debugger = g_value_dup_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
 swfdec_as_context_dispose (GObject *object)
 {
   SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
@@ -435,6 +472,10 @@ swfdec_as_context_dispose (GObject *obje
   g_hash_table_destroy (context->objects);
   g_hash_table_destroy (context->strings);
   g_rand_free (context->rand);
+  if (context->debugger) {
+    g_object_unref (context->debugger);
+    context->debugger = NULL;
+  }
 
   G_OBJECT_CLASS (swfdec_as_context_parent_class)->dispose (object);
 }
@@ -445,6 +486,12 @@ swfdec_as_context_class_init (SwfdecAsCo
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->dispose = swfdec_as_context_dispose;
+  object_class->get_property = swfdec_as_context_get_property;
+  object_class->set_property = swfdec_as_context_set_property;
+
+  g_object_class_install_property (object_class, PROP_DEBUGGER,
+      g_param_spec_object ("debugger", "debugger", "debugger used in this player",
+	  SWFDEC_TYPE_AS_DEBUGGER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
   /**
    * SwfdecAsContext::trace:
@@ -642,16 +689,19 @@ swfdec_as_context_run (SwfdecAsContext *
   guint action, len;
   guint8 *data;
   int version;
-  SwfdecAsContextClass *klass;
-  void (* step) (SwfdecAsContext *context);
+  void (* step) (SwfdecAsDebugger *debugger, SwfdecAsContext *context);
   gboolean check_scope; /* some opcodes avoid a scope check */
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
   if (context->frame == NULL || context->state == SWFDEC_AS_CONTEXT_ABORTED)
     return;
 
-  klass = SWFDEC_AS_CONTEXT_GET_CLASS (context);
-  step = klass->step;
+  if (context->debugger) {
+    SwfdecAsDebuggerClass *klass = SWFDEC_AS_DEBUGGER_GET_CLASS (context->debugger);
+    step = klass->step;
+  } else {
+    step = NULL;
+  }
 
   last_frame = context->last_frame;
   context->last_frame = context->frame->next;
@@ -737,7 +787,7 @@ start:
     /* invoke debugger if there is one */
     if (step) {
       frame->pc = pc;
-      (* step) (context);
+      (* step) (context->debugger, context);
       if (frame != context->frame || 
 	  frame->pc != pc) {
 	goto start;
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index d18fa62..fbcb6e9 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -76,6 +76,9 @@ struct _SwfdecAsContext {
   SwfdecAsObject *	Object;		/* Object */
   SwfdecAsObject *	Object_prototype;	/* Object.prototype */
   SwfdecAsObject *	Array;		/* Array */
+
+  /* debugging */
+  SwfdecAsDebugger *	debugger;	/* debugger (or NULL if none) */
 };
 
 struct _SwfdecAsContextClass {
@@ -83,8 +86,6 @@ struct _SwfdecAsContextClass {
 
   /* mark all objects that should not be collected */
   void			(* mark)		(SwfdecAsContext *	context);
-  /* debugging: call this function before executing a bytecode if non-NULL */
-  void			(* step)		(SwfdecAsContext *	context);
   /* overwrite if you want to report a different time than gettimeofday */
   void			(* get_time)		(SwfdecAsContext *      context,
 						 GTimeVal *		tv);
diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c
index 9b0fd2a..89adbf6 100644
--- a/libswfdec/swfdec_debugger.c
+++ b/libswfdec/swfdec_debugger.c
@@ -386,6 +386,7 @@ swfdec_debugger_dispose (GObject *object
   G_OBJECT_CLASS (swfdec_debugger_parent_class)->dispose (object);
 }
 
+#if 0
 static void
 swfdec_debugger_do_breakpoint (SwfdecDebugger *debugger, guint id)
 {
@@ -439,12 +440,12 @@ swfdec_debugger_step (SwfdecAsContext *c
     }
   }
 }
+#endif
 
 static void
 swfdec_debugger_class_init (SwfdecDebuggerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  SwfdecAsContextClass *context_class = SWFDEC_AS_CONTEXT_CLASS (klass);
 
   object_class->dispose = swfdec_debugger_dispose;
 
@@ -469,8 +470,6 @@ swfdec_debugger_class_init (SwfdecDebugg
   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);
-
-  context_class->step = swfdec_debugger_step;
 }
 
 static void
diff-tree 260be3fc109be6884aba0d01a9f9429ab4099562 (from dbbc914ef87434d4d1c9aa8332451441030ef655)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 15:55:58 2007 +0200

    add a debugger class that is not a subclass of SwfdecAsContext

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 2f48811..dd62712 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -23,6 +23,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_as_array.c \
 	swfdec_as_boolean.c \
 	swfdec_as_context.c \
+	swfdec_as_debugger.c \
 	swfdec_as_frame.c \
 	swfdec_as_function.c \
 	swfdec_as_interpret.c \
@@ -125,6 +126,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_LDFLAGS
 public_headers = \
 	swfdec.h \
 	swfdec_as_context.h \
+	swfdec_as_debugger.h \
 	swfdec_as_frame.h \
 	swfdec_as_object.h \
 	swfdec_as_types.h \
diff --git a/libswfdec/swfdec.h b/libswfdec/swfdec.h
index b4b9ab8..27e65e9 100644
--- a/libswfdec/swfdec.h
+++ b/libswfdec/swfdec.h
@@ -23,6 +23,7 @@
 #define __SWFDEC_H__
 
 #include <libswfdec/swfdec_as_context.h>
+#include <libswfdec/swfdec_as_debugger.h>
 #include <libswfdec/swfdec_as_frame.h>
 #include <libswfdec/swfdec_as_object.h>
 #include <libswfdec/swfdec_as_types.h>
diff --git a/libswfdec/swfdec_as_debugger.c b/libswfdec/swfdec_as_debugger.c
new file mode 100644
index 0000000..ac0c6a4
--- /dev/null
+++ b/libswfdec/swfdec_as_debugger.c
@@ -0,0 +1,72 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "swfdec_as_debugger.h"
+#include "swfdec_as_context.h"
+
+G_DEFINE_TYPE (SwfdecAsDebugger, swfdec_as_debugger, G_TYPE_OBJECT)
+
+/**
+ * SECTION:SwfdecAsDebugger
+ * @title: SwfdecAsDebugger
+ * @short_description: the debugger object
+ * @see also: SwfdecAsContext
+ *
+ * The debugger object is a special object that can be set on a #SwfdecAsContext
+ * upon creation. If that is done, the debugger can then be used to inspect the 
+ * running Actionscript application.
+ */
+
+/**
+ * SwfdecAsDebugger
+ *
+ * This is the type of the debugger object.
+ */
+
+/**
+ * SwfdecAsDebuggerClass
+ * @step: This function is called everytime just before a bytecode is executed by 
+ *        the script engine. So it's very powerful, but can also slow down the
+ *        script engine a lot.
+ * @frame_change: Called whenever the current frame changes. This happens either
+ *                when calling a function or when a function call returns. The
+ *                function call is called for any type of frame, even calls to
+ *                native functions.
+ *
+ * The class object for the debugger. You need to override these functions to 
+ * get useful functionality for the debugger.
+ */
+
+static void
+swfdec_as_debugger_class_init (SwfdecAsDebuggerClass *klass)
+{
+}
+
+static void
+swfdec_as_debugger_init (SwfdecAsDebugger *debugger)
+{
+}
+
diff --git a/libswfdec/swfdec_as_debugger.h b/libswfdec/swfdec_as_debugger.h
new file mode 100644
index 0000000..643ac53
--- /dev/null
+++ b/libswfdec/swfdec_as_debugger.h
@@ -0,0 +1,58 @@
+/* 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_AS_DEBUGGER_H_
+#define _SWFDEC_AS_DEBUGGER_H_
+
+#include <libswfdec/swfdec_as_object.h>
+#include <libswfdec/swfdec_as_types.h>
+#include <libswfdec/swfdec_script.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecAsDebuggerClass SwfdecAsDebuggerClass;
+
+#define SWFDEC_TYPE_AS_DEBUGGER                    (swfdec_as_debugger_get_type())
+#define SWFDEC_IS_AS_DEBUGGER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_DEBUGGER))
+#define SWFDEC_IS_AS_DEBUGGER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_DEBUGGER))
+#define SWFDEC_AS_DEBUGGER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_DEBUGGER, SwfdecAsDebugger))
+#define SWFDEC_AS_DEBUGGER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_DEBUGGER, SwfdecAsDebuggerClass))
+#define SWFDEC_AS_DEBUGGER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_DEBUGGER, SwfdecAsDebuggerClass))
+
+struct _SwfdecAsDebugger {
+  /*< private >*/
+  GObject		object;
+};
+
+struct _SwfdecAsDebuggerClass {
+  GObjectClass		object_class;
+
+  /* called before executing a bytecode */
+  void			(* step)	(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context);
+  /* called after adding or removing a frame from the function stack */
+  void			(* frame_change)(SwfdecAsDebugger *	debugger,
+					 SwfdecAsContext *	context);
+};
+
+GType		swfdec_as_debugger_get_type	(void);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index dbb9394..d435cb9 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -37,6 +37,7 @@ typedef enum {
 
 typedef struct _SwfdecAsArray SwfdecAsArray;
 typedef struct _SwfdecAsContext SwfdecAsContext;
+typedef struct _SwfdecAsDebugger SwfdecAsDebugger;
 typedef struct _SwfdecAsFrame SwfdecAsFrame;
 typedef struct _SwfdecAsFunction SwfdecAsFunction;
 typedef struct _SwfdecAsObject SwfdecAsObject;
diff-tree dbbc914ef87434d4d1c9aa8332451441030ef655 (from 6f1d4325411f14379a2f7fdfd4cec1ed0a166db0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 15:22:01 2007 +0200

    no need for swfdec_script.h here

diff --git a/libswfdec/swfdec_as_array.h b/libswfdec/swfdec_as_array.h
index a437301..7a06296 100644
--- a/libswfdec/swfdec_as_array.h
+++ b/libswfdec/swfdec_as_array.h
@@ -23,7 +23,6 @@
 
 #include <libswfdec/swfdec_as_object.h>
 #include <libswfdec/swfdec_as_types.h>
-#include <libswfdec/swfdec_script.h>
 
 G_BEGIN_DECLS
 
diff-tree 6f1d4325411f14379a2f7fdfd4cec1ed0a166db0 (from e506ea7bfceb2b1a0a9237141d6137cf39110233)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 15:12:08 2007 +0200

    get rid of the debugger pointer in SwfdecScript

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index ecc828a..90fd2e2 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1564,7 +1564,6 @@ swfdec_action_define_function (SwfdecAsC
   script->n_arguments = n_args;
   script->arguments = args;
   SWFDEC_AS_SCRIPT_FUNCTION (fun)->script = script;
-  swfdec_script_add_to_context (script, cx);
   /* attach the function */
   if (*function_name == '\0') {
     swfdec_as_stack_ensure_free (cx, 1);
diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c
index aa123ca..26c4dfb 100644
--- a/libswfdec/swfdec_event.c
+++ b/libswfdec/swfdec_event.c
@@ -202,7 +202,7 @@ swfdec_event_list_parse (SwfdecEventList
   event.key = key;
   name = g_strconcat (description, ".", 
       swfdec_event_list_condition_name (conditions), NULL);
-  event.script = swfdec_script_new_for_context (SWFDEC_AS_CONTEXT (list->player), bits, name, version);
+  event.script = swfdec_script_new (bits, name, version);
   g_free (name);
   if (event.script) 
     g_array_append_val (list->events, event);
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index eec940b..87f2010 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -111,15 +111,6 @@ swfdec_constant_pool_free (SwfdecConstan
 
 /*** SUPPORT FUNCTIONS ***/
 
-void
-swfdec_script_add_to_context (SwfdecScript *script, SwfdecAsContext *context)
-{
-  if (SWFDEC_IS_DEBUGGER (context)) {
-    swfdec_debugger_add_script (SWFDEC_DEBUGGER (context), script);
-    script->debugger = context;
-  }
-}
-
 char *
 swfdec_script_print_action (guint action, const guint8 *data, guint len)
 {
@@ -208,21 +199,6 @@ validate_action (gconstpointer bytecode,
 }
 
 SwfdecScript *
-swfdec_script_new_for_context (SwfdecAsContext *context, SwfdecBits *bits, 
-    const char *name, guint version)
-{
-  SwfdecScript *script;
-
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
-  g_return_val_if_fail (bits != NULL, NULL);
-
-  script = swfdec_script_new (bits, name, version);
-  if (script)
-    swfdec_script_add_to_context (script, context);
-  return script;
-}
-
-SwfdecScript *
 swfdec_script_new (SwfdecBits *bits, const char *name, guint version)
 {
   SwfdecScript *script;
@@ -280,11 +256,6 @@ swfdec_script_unref (SwfdecScript *scrip
   g_return_if_fail (script->refcount > 0);
 
   script->refcount--;
-  if (script->refcount == 1 && script->debugger) {
-    script->debugger = NULL;
-    swfdec_debugger_remove_script (script->debugger, script);
-    return;
-  }
   if (script->refcount > 0)
     return;
 
diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h
index 31ae882..6a0870b 100644
--- a/libswfdec/swfdec_script.h
+++ b/libswfdec/swfdec_script.h
@@ -53,7 +53,6 @@ struct _SwfdecScript {
   char *		name;			/* name identifying this script */
   guint			version;		/* version of the script */
   guint			n_registers;		/* number of registers */
-  gpointer		debugger;		/* debugger owning us or NULL */
   SwfdecBuffer *	constant_pool;		/* constant pool action */
   guint			flags;			/* SwfdecScriptFlags */
   guint			n_arguments;  		/* number of arguments */
@@ -82,12 +81,6 @@ void		swfdec_constant_pool_attach_to_con
 SwfdecScript *	swfdec_script_new			(SwfdecBits *		bits,
 							 const char *		name,
 							 guint			version);
-SwfdecScript *	swfdec_script_new_for_context	  	(SwfdecAsContext *	context,
-							 SwfdecBits *		bits,
-							 const char *		name,
-							 guint			version);
-void		swfdec_script_add_to_context		(SwfdecScript *		script,
-							 SwfdecAsContext *	context);
 SwfdecScript *	swfdec_script_ref			(SwfdecScript *		script);
 void		swfdec_script_unref			(SwfdecScript *		script);
 
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index b6acf1b..a8b77fc 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -545,8 +545,7 @@ tag_func_do_init_action (SwfdecSwfDecode
     return SWFDEC_STATUS_OK;
   }
   name = g_strdup_printf ("InitAction %u", id);
-  sprite->init_action = swfdec_script_new_for_context (SWFDEC_AS_CONTEXT (SWFDEC_DECODER (s)->player),
-      bits, name, s->version);
+  sprite->init_action = swfdec_script_new (bits, name, s->version);
   g_free (name);
   if (sprite->init_action) {
     swfdec_script_ref (sprite->init_action);
@@ -595,7 +594,7 @@ tag_func_do_action (SwfdecSwfDecoder * s
 
   name = g_strdup_printf ("Sprite%u_Frame%u", SWFDEC_CHARACTER (s->parse_sprite)->id,
       s->parse_sprite->parse_frame);
-  script = swfdec_script_new_for_context (SWFDEC_AS_CONTEXT (SWFDEC_DECODER (s)->player), &s->b, name, s->version);
+  script = swfdec_script_new (&s->b, name, s->version);
   g_free (name);
   if (script) {
     swfdec_swf_decoder_add_script (s, script);
diff-tree e506ea7bfceb2b1a0a9237141d6137cf39110233 (from 555b7cbb3f3edd2e9c5293e8c8d5d1f9b6012531)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 14:24:12 2007 +0200

    implement size_request, size_allocate and foreach
    
    why does GtkBin not implement this?

diff --git a/vivified/dock/vivi_docklet.c b/vivified/dock/vivi_docklet.c
index 42c8aa2..f6bc015 100644
--- a/vivified/dock/vivi_docklet.c
+++ b/vivified/dock/vivi_docklet.c
@@ -81,9 +81,34 @@ vivi_docklet_dispose (GObject *object)
 }
 
 static void
+vivi_docklet_size_request (GtkWidget *widget, GtkRequisition *req)
+{
+  GtkWidget *child = GTK_BIN (widget)->child;
+  
+  if (child) {
+    gtk_widget_size_request (child, req);
+  } else {
+    req->width = req->height = 0;
+  }
+}
+
+static void
+vivi_docklet_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+  GtkWidget *child = GTK_BIN (widget)->child;
+  
+  GTK_WIDGET_CLASS (vivi_docklet_parent_class)->size_allocate (widget, allocation);
+
+  if (child && GTK_WIDGET_VISIBLE (child)) {
+    gtk_widget_size_allocate (child, allocation);
+  }
+}
+
+static void
 vivi_docklet_class_init (ViviDockletClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
   object_class->dispose = vivi_docklet_dispose;
   object_class->get_property = vivi_docklet_get_property;
@@ -95,6 +120,9 @@ vivi_docklet_class_init (ViviDockletClas
   g_object_class_install_property (object_class, PROP_ICON,
       g_param_spec_string ("icon", "icon", "name of the icon to display",
 	  GTK_STOCK_MISSING_IMAGE, G_PARAM_READWRITE));
+
+  widget_class->size_request = vivi_docklet_size_request;
+  widget_class->size_allocate = vivi_docklet_size_allocate;
 }
 
 static void
diff --git a/vivified/dock/vivi_vdock.c b/vivified/dock/vivi_vdock.c
index 6ade29a..1559ec1 100644
--- a/vivified/dock/vivi_vdock.c
+++ b/vivified/dock/vivi_vdock.c
@@ -39,6 +39,30 @@ vivi_vdock_dispose (GObject *object)
 }
 
 static void
+vivi_vdock_size_request (GtkWidget *widget, GtkRequisition *req)
+{
+  GtkWidget *child = GTK_BIN (widget)->child;
+  
+  if (child) {
+    gtk_widget_size_request (child, req);
+  } else {
+    req->width = req->height = 0;
+  }
+}
+
+static void
+vivi_vdock_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+  GtkWidget *child = GTK_BIN (widget)->child;
+  
+  GTK_WIDGET_CLASS (vivi_vdock_parent_class)->size_allocate (widget, allocation);
+
+  if (child && GTK_WIDGET_VISIBLE (child)) {
+    gtk_widget_size_allocate (child, allocation);
+  }
+}
+
+static void
 vivi_vdock_add (GtkContainer *container, GtkWidget *widget)
 {
   ViviVDock *vdock = VIVI_VDOCK (container);
@@ -119,16 +143,37 @@ vivi_vdock_child_type (GtkContainer *con
 }
 
 static void
+vivi_vdock_forall (GtkContainer *container, gboolean include_internals,
+    GtkCallback callback, gpointer callback_data)
+{
+  if (include_internals) {
+    GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->forall (container, include_internals, 
+	callback, callback_data);
+  } else {
+    GList *walk;
+
+    for (walk = VIVI_VDOCK (container)->docklets; walk; walk = walk->next) {
+      callback (walk->data, callback_data);
+    }
+  }
+}
+
+static void
 vivi_vdock_class_init (ViviVDockClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
 
   object_class->dispose = vivi_vdock_dispose;
 
+  widget_class->size_request = vivi_vdock_size_request;
+  widget_class->size_allocate = vivi_vdock_size_allocate;
+
   container_class->add = vivi_vdock_add;
   container_class->remove = vivi_vdock_remove;
   container_class->child_type = vivi_vdock_child_type;
+  container_class->forall = vivi_vdock_forall;
 }
 
 static void
diff-tree 555b7cbb3f3edd2e9c5293e8c8d5d1f9b6012531 (from 5764ac047bfb06bcac2f20541dad99ad4423bace)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 14:21:48 2007 +0200

    use LDADD for including our own libraries

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 83d58f3..5509035 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -1,7 +1,8 @@
 noinst_PROGRAMS = vivified
 
 vivified_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS)
-vivified_LDFLAGS = $(SWFDEC_GTK_LIBS) \
+vivified_LDFLAGS = $(SWFDEC_GTK_LIBS)
+vivified_LDADD = \
 	$(top_builddir)/vivified/core/libvivified-core.la \
 	$(top_builddir)/vivified/dock/libvivified-dock.la
 
diff-tree 5764ac047bfb06bcac2f20541dad99ad4423bace (from 2e41ba5f7b9b9e1e2ae7b2e6301597b5295d186b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 14:21:26 2007 +0200

    show the newly added widgets

diff --git a/vivified/dock/vivi_docker.c b/vivified/dock/vivi_docker.c
index 77a3839..90a0de9 100644
--- a/vivified/dock/vivi_docker.c
+++ b/vivified/dock/vivi_docker.c
@@ -69,7 +69,9 @@ vivi_docker_set_docklet (ViviDocker *doc
   g_return_if_fail (VIVI_IS_DOCKLET (docklet));
 
   box = gtk_hbox_new (FALSE, 3);
+  gtk_widget_show (box);
   widget = gtk_label_new (vivi_docklet_get_title (docklet));
+  gtk_widget_show (widget);
   g_signal_connect (docklet, "notify::title", G_CALLBACK (vivi_docker_docklet_notify_title), widget);
   gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
   gtk_expander_set_label_widget (GTK_EXPANDER (docker), box);
diff-tree 2e41ba5f7b9b9e1e2ae7b2e6301597b5295d186b (from 3c9914ddfb97b6c3d9a25c1651337e85aa4e9c4c)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 13:53:49 2007 +0200

    add simple command line entry for testing the doc

diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index 05e37df..83d58f3 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -6,7 +6,9 @@ vivified_LDFLAGS = $(SWFDEC_GTK_LIBS) \
 	$(top_builddir)/vivified/dock/libvivified-dock.la
 
 vivified_SOURCES = \
+	vivi_commandline.c \
 	main.c
 
-noinst_HEADERS =
+noinst_HEADERS = \
+	vivi_commandline.h
 
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
index 7893e7e..1dd43e6 100644
--- a/vivified/ui/main.c
+++ b/vivified/ui/main.c
@@ -24,18 +24,8 @@
 #include <gtk/gtk.h>
 #include <libswfdec-gtk/swfdec-gtk.h>
 #include "vivified/core/vivified-core.h"
-
-static void
-entry_activate_cb (GtkEntry *entry, ViviApplication *app)
-{
-  const char *text = gtk_entry_get_text (entry);
-
-  if (text[0] == '\0')
-    return;
-
-  //swfdec_player_manager_execute (manager, text);
-  gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
-}
+#include "vivified/dock/vivified-dock.h"
+#include "vivi_commandline.h"
 
 static void
 setup (const char *filename)
@@ -45,15 +35,10 @@ setup (const char *filename)
 
   app = vivi_application_new ();
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  box = gtk_vbox_new (FALSE, 0);
+  box = vivi_vdock_new ();
   gtk_container_add (GTK_CONTAINER (window), box);
-  /* widget displaying the Flash */
-  widget = swfdec_gtk_widget_new (NULL);
-  gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
-  /* text entry */
-  widget = gtk_entry_new ();
-  g_signal_connect (widget, "activate", G_CALLBACK (entry_activate_cb), app);
-  gtk_box_pack_end (GTK_BOX (box), widget, FALSE, TRUE, 0);
+  widget = vivi_command_line_new (app);
+  gtk_container_add (GTK_CONTAINER (box), widget);
 
   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
   gtk_widget_show_all (window);
diff --git a/vivified/ui/vivi_commandline.c b/vivified/ui/vivi_commandline.c
new file mode 100644
index 0000000..ced3e15
--- /dev/null
+++ b/vivified/ui/vivi_commandline.c
@@ -0,0 +1,75 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_commandline.h"
+
+G_DEFINE_TYPE (ViviCommandLine, vivi_command_line, VIVI_TYPE_DOCKLET)
+
+static void
+vivi_command_line_dispose (GObject *object)
+{
+  //ViviCommandLine *command_line = VIVI_COMMAND_LINE (object);
+
+  G_OBJECT_CLASS (vivi_command_line_parent_class)->dispose (object);
+}
+
+static void
+vivi_command_line_class_init (ViviCommandLineClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_command_line_dispose;
+}
+
+static void
+command_line_entry_activate_cb (GtkEntry *entry, ViviCommandLine *command_line)
+{
+  const char *text = gtk_entry_get_text (entry);
+
+  if (text[0] == '\0')
+    return;
+
+  g_print ("%s\n", text);
+  //swfdec_player_manager_execute (manager, text);
+  gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
+}
+
+static void
+vivi_command_line_init (ViviCommandLine *command_line)
+{
+  GtkWidget *entry;
+
+  entry = gtk_entry_new ();
+  gtk_container_add (GTK_CONTAINER (command_line), entry);
+  g_signal_connect (entry, "activate", G_CALLBACK (command_line_entry_activate_cb), command_line);
+}
+
+GtkWidget *
+vivi_command_line_new (ViviApplication *app)
+{
+  GtkWidget *cl;
+
+  cl = g_object_new (VIVI_TYPE_COMMAND_LINE, "title", "Command Line", NULL);
+  return cl;
+}
+
diff --git a/vivified/ui/vivi_commandline.h b/vivified/ui/vivi_commandline.h
new file mode 100644
index 0000000..f38da32
--- /dev/null
+++ b/vivified/ui/vivi_commandline.h
@@ -0,0 +1,54 @@
+/* Vivified
+ * 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 _VIVI_COMMAND_LINE_H_
+#define _VIVI_COMMAND_LINE_H_
+
+#include <vivified/core/vivified-core.h>
+#include <vivified/dock/vivified-dock.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCommandLine ViviCommandLine;
+typedef struct _ViviCommandLineClass ViviCommandLineClass;
+
+#define VIVI_TYPE_COMMAND_LINE                    (vivi_command_line_get_type())
+#define VIVI_IS_COMMAND_LINE(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_COMMAND_LINE))
+#define VIVI_IS_COMMAND_LINE_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_COMMAND_LINE))
+#define VIVI_COMMAND_LINE(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_COMMAND_LINE, ViviCommandLine))
+#define VIVI_COMMAND_LINE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_COMMAND_LINE, ViviCommandLineClass))
+#define VIVI_COMMAND_LINE_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_COMMAND_LINE, ViviCommandLineClass))
+
+struct _ViviCommandLine {
+  ViviDocklet		docklet;
+};
+
+struct _ViviCommandLineClass
+{
+  ViviDockletClass    	docklet_class;
+};
+
+GType			vivi_command_line_get_type   	(void);
+
+GtkWidget *		vivi_command_line_new		(ViviApplication *	app);
+
+
+G_END_DECLS
+#endif
diff-tree 3c9914ddfb97b6c3d9a25c1651337e85aa4e9c4c (from d16bed72235542b5d4ce5172e0718072f6d340f0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 13:53:26 2007 +0200

    add vdock widget
    
    This is supposed to be a vertical dock.

diff --git a/vivified/dock/Makefile.am b/vivified/dock/Makefile.am
index 114a137..590e5cf 100644
--- a/vivified/dock/Makefile.am
+++ b/vivified/dock/Makefile.am
@@ -4,8 +4,12 @@ libvivified_dock_la_CFLAGS = $(GLOBAL_CF
 libvivified_dock_la_LDFLAGS = $(GTK_LIBS)
 
 libvivified_dock_la_SOURCES = \
-	vivi_docklet.c
+	vivi_docker.c \
+	vivi_docklet.c \
+	vivi_vdock.c
 
 noinst_HEADERS = \
+	vivi_docker.h \
 	vivi_docklet.h \
+	vivi_vdock.h \
 	vivified-dock.h
diff --git a/vivified/dock/vivi_docker.c b/vivified/dock/vivi_docker.c
new file mode 100644
index 0000000..77a3839
--- /dev/null
+++ b/vivified/dock/vivi_docker.c
@@ -0,0 +1,91 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_docker.h"
+
+enum {
+  REQUEST_CLOSE,
+  LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE (ViviDocker, vivi_docker, GTK_TYPE_EXPANDER)
+
+static void
+vivi_docker_dispose (GObject *object)
+{
+  //ViviDocker *docker = VIVI_DOCKER (object);
+
+  G_OBJECT_CLASS (vivi_docker_parent_class)->dispose (object);
+}
+
+static void
+vivi_docker_class_init (ViviDockerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_docker_dispose;
+
+  signals[REQUEST_CLOSE] = 0;
+}
+
+static void
+vivi_docker_init (ViviDocker *docker)
+{
+}
+
+static void
+vivi_docker_docklet_notify_title (ViviDocklet *docklet, GParamSpec *pspec, GtkLabel *label)
+{
+  gtk_label_set_text (label, vivi_docklet_get_title (docklet));
+}
+
+static void
+vivi_docker_set_docklet (ViviDocker *docker, ViviDocklet *docklet)
+{
+  GtkWidget *box, *widget;
+
+  g_return_if_fail (VIVI_IS_DOCKER (docker));
+  g_return_if_fail (VIVI_IS_DOCKLET (docklet));
+
+  box = gtk_hbox_new (FALSE, 3);
+  widget = gtk_label_new (vivi_docklet_get_title (docklet));
+  g_signal_connect (docklet, "notify::title", G_CALLBACK (vivi_docker_docklet_notify_title), widget);
+  gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
+  gtk_expander_set_label_widget (GTK_EXPANDER (docker), box);
+  gtk_container_add (GTK_CONTAINER (docker), GTK_WIDGET (docklet));
+}
+
+GtkWidget *
+vivi_docker_new (ViviDocklet *docklet)
+{
+  GtkWidget *widget;
+
+  g_return_val_if_fail (VIVI_IS_DOCKLET (docklet), NULL);
+
+  widget = g_object_new (VIVI_TYPE_DOCKER, "expanded", TRUE, NULL);
+  vivi_docker_set_docklet (VIVI_DOCKER (widget), docklet);
+  return widget;
+}
+
+
diff --git a/vivified/dock/vivi_docker.h b/vivified/dock/vivi_docker.h
new file mode 100644
index 0000000..3baaf8d
--- /dev/null
+++ b/vivified/dock/vivi_docker.h
@@ -0,0 +1,55 @@
+/* Vivified
+ * 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 _VIVI_DOCKER_H_
+#define _VIVI_DOCKER_H_
+
+#include <gtk/gtk.h>
+#include <vivified/dock/vivi_docklet.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviDocker ViviDocker;
+typedef struct _ViviDockerClass ViviDockerClass;
+
+#define VIVI_TYPE_DOCKER                    (vivi_docker_get_type())
+#define VIVI_IS_DOCKER(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_DOCKER))
+#define VIVI_IS_DOCKER_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_DOCKER))
+#define VIVI_DOCKER(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_DOCKER, ViviDocker))
+#define VIVI_DOCKER_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_DOCKER, ViviDockerClass))
+#define VIVI_DOCKER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_DOCKER, ViviDockerClass))
+
+struct _ViviDocker {
+  GtkExpander		bin;
+};
+
+struct _ViviDockerClass
+{
+  GtkExpanderClass	bin_class;
+
+  void			(* request_close)	(ViviDocker *	docker);
+};
+
+GType			vivi_docker_get_type   	(void);
+
+GtkWidget *		vivi_docker_new		(ViviDocklet *	docklet);
+
+G_END_DECLS
+#endif
diff --git a/vivified/dock/vivi_vdock.c b/vivified/dock/vivi_vdock.c
new file mode 100644
index 0000000..6ade29a
--- /dev/null
+++ b/vivified/dock/vivi_vdock.c
@@ -0,0 +1,145 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_vdock.h"
+#include "vivi_docker.h"
+#include "vivi_docklet.h"
+
+G_DEFINE_TYPE (ViviVDock, vivi_vdock, GTK_TYPE_BIN)
+
+static void
+vivi_vdock_dispose (GObject *object)
+{
+  ViviVDock *vdock = VIVI_VDOCK (object);
+
+  g_list_free (vdock->docklets);
+  vdock->docklets = NULL;
+
+  G_OBJECT_CLASS (vivi_vdock_parent_class)->dispose (object);
+}
+
+static void
+vivi_vdock_add (GtkContainer *container, GtkWidget *widget)
+{
+  ViviVDock *vdock = VIVI_VDOCK (container);
+  GtkWidget *docker;
+  
+  docker = vivi_docker_new (VIVI_DOCKLET (widget));
+  gtk_widget_show (docker);
+
+  g_object_ref (widget);
+  if (vdock->docklets == NULL) {
+    GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->add (container, docker);
+  } else {
+    /* docklet is in docker */
+    GtkWidget *last = gtk_widget_get_parent (vdock->docklets->data);
+    GtkWidget *parent = gtk_widget_get_parent (last);
+    GtkWidget *paned;
+
+    g_object_ref (parent);
+    if (parent == (GtkWidget *) container) {
+      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, last);
+    } else {
+      gtk_container_remove (GTK_CONTAINER (parent), last);
+    }
+    paned = gtk_vpaned_new ();
+    gtk_paned_pack1 (GTK_PANED (paned), docker, TRUE, FALSE);
+    gtk_paned_pack2 (GTK_PANED (paned), last, TRUE, FALSE);
+    g_object_unref (last);
+    gtk_widget_show (paned);
+    if (parent == (GtkWidget *) container) {
+      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->add (container, paned);
+    } else {
+      gtk_paned_pack1 (GTK_PANED (parent), paned, TRUE, FALSE);
+    }
+  }
+  vdock->docklets = g_list_prepend (vdock->docklets, widget);
+}
+
+static void
+vivi_vdock_remove (GtkContainer *container, GtkWidget *widget)
+{
+  ViviVDock *vdock = VIVI_VDOCK (container);
+  GtkWidget *docker, *parent;
+
+  g_return_if_fail (g_list_find (vdock->docklets, widget));
+
+  docker = gtk_widget_get_parent (widget);
+  parent = gtk_widget_get_parent (docker);
+  if (parent == (GtkWidget *) container) {
+    GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, docker);
+  } else {
+    GtkWidget *other;
+    GtkWidget *paned_parent;
+    g_assert (GTK_IS_PANED (parent));
+    paned_parent = gtk_widget_get_parent (parent);
+    other = gtk_paned_get_child1 (GTK_PANED (parent));
+    if (other == docker)
+      other = gtk_paned_get_child2 (GTK_PANED (parent));
+    g_object_ref (other);
+    gtk_container_remove (GTK_CONTAINER (parent), docker);
+    gtk_container_remove (GTK_CONTAINER (parent), other);
+    if (paned_parent == (GtkWidget *) container) {
+      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, parent);
+      GTK_CONTAINER_CLASS (vivi_vdock_parent_class)->remove (container, other);
+    } else {
+      gtk_container_remove (GTK_CONTAINER (paned_parent), parent);
+      gtk_paned_pack1 (GTK_PANED (parent), other, TRUE, FALSE);
+    }
+    g_object_unref (other);
+  }
+  vdock->docklets = g_list_remove (vdock->docklets, widget);
+  g_object_unref (widget);
+}
+
+static GType
+vivi_vdock_child_type (GtkContainer *container)
+{
+  return VIVI_TYPE_DOCKLET;
+}
+
+static void
+vivi_vdock_class_init (ViviVDockClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+  object_class->dispose = vivi_vdock_dispose;
+
+  container_class->add = vivi_vdock_add;
+  container_class->remove = vivi_vdock_remove;
+  container_class->child_type = vivi_vdock_child_type;
+}
+
+static void
+vivi_vdock_init (ViviVDock *vdock)
+{
+}
+
+GtkWidget *
+vivi_vdock_new (void)
+{
+  return g_object_new (VIVI_TYPE_VDOCK, NULL);
+}
+
+
diff --git a/vivified/dock/vivi_vdock.h b/vivified/dock/vivi_vdock.h
new file mode 100644
index 0000000..ec3527f
--- /dev/null
+++ b/vivified/dock/vivi_vdock.h
@@ -0,0 +1,54 @@
+/* Vivified
+ * 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 _VIVI_VDOCK_H_
+#define _VIVI_VDOCK_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviVDock ViviVDock;
+typedef struct _ViviVDockClass ViviVDockClass;
+
+#define VIVI_TYPE_VDOCK                    (vivi_vdock_get_type())
+#define VIVI_IS_VDOCK(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_VDOCK))
+#define VIVI_IS_VDOCK_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_VDOCK))
+#define VIVI_VDOCK(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_VDOCK, ViviVDock))
+#define VIVI_VDOCK_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_VDOCK, ViviVDockClass))
+#define VIVI_VDOCK_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_VDOCK, ViviVDockClass))
+
+struct _ViviVDock {
+  GtkBin		bin;
+
+  GList *		docklets;	/* all the docklets that got added to us */
+};
+
+struct _ViviVDockClass
+{
+  GtkBinClass		bin_class;
+};
+
+GType			vivi_vdock_get_type   	(void);
+
+GtkWidget *		vivi_vdock_new		(void);
+
+G_END_DECLS
+#endif
diff --git a/vivified/dock/vivified-dock.h b/vivified/dock/vivified-dock.h
index 401d6c5..244aad8 100644
--- a/vivified/dock/vivified-dock.h
+++ b/vivified/dock/vivified-dock.h
@@ -21,5 +21,6 @@
 #define __VIVIFIED_DOCK_H__
 
 #include <vivified/dock/vivi_docklet.h>
+#include <vivified/dock/vivi_vdock.h>
 
 #endif
diff-tree d16bed72235542b5d4ce5172e0718072f6d340f0 (from d416dd57fbf03e1601e10675dee252259b10f762)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 9 11:47:06 2007 +0200

    add dock library
    
    let' hope that there'll be a GtkDock at some point so we can throw this away.
    Or someone makes a GtkDock lib out of this :)

diff --git a/configure.ac b/configure.ac
index 207e360..e9996f4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -326,6 +326,7 @@ test/trace/Makefile
 test/various/Makefile
 vivified/Makefile
 vivified/core/Makefile
+vivified/dock/Makefile
 vivified/ui/Makefile
 swfdec.pc
 swfdec-gtk.pc
diff --git a/vivified/Makefile.am b/vivified/Makefile.am
index fd20116..8289102 100644
--- a/vivified/Makefile.am
+++ b/vivified/Makefile.am
@@ -1 +1 @@
-SUBDIRS = core ui
+SUBDIRS = core dock ui
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
index 47a9d96..496eadf 100644
--- a/vivified/core/vivi_application.c
+++ b/vivified/core/vivi_application.c
@@ -85,6 +85,13 @@ vivi_application_class_init (ViviApplica
   object_class->dispose = vivi_application_dispose;
   object_class->get_property = vivi_application_get_property;
   object_class->set_property = vivi_application_set_property;
+
+  g_object_class_install_property (object_class, PROP_FILENAME,
+      g_param_spec_string ("filename", "filename", "name of file to play",
+	  NULL, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_PLAYER,
+      g_param_spec_object ("player", "player", "Flash player in use",
+	  SWFDEC_TYPE_PLAYER, G_PARAM_READABLE));
 }
 
 static void
diff --git a/vivified/dock/.gitignore b/vivified/dock/.gitignore
new file mode 100644
index 0000000..b580c89
--- /dev/null
+++ b/vivified/dock/.gitignore
@@ -0,0 +1,12 @@
+*~
+CVS
+.cvsignore
+.deps
+.libs
+
+Makefile
+Makefile.in
+*.o
+*.la
+*.lo
+*.loT
diff --git a/vivified/dock/Makefile.am b/vivified/dock/Makefile.am
new file mode 100644
index 0000000..114a137
--- /dev/null
+++ b/vivified/dock/Makefile.am
@@ -0,0 +1,11 @@
+noinst_LTLIBRARIES = libvivified-dock.la
+
+libvivified_dock_la_CFLAGS = $(GLOBAL_CFLAGS) $(GTK_CFLAGS)
+libvivified_dock_la_LDFLAGS = $(GTK_LIBS)
+
+libvivified_dock_la_SOURCES = \
+	vivi_docklet.c
+
+noinst_HEADERS = \
+	vivi_docklet.h \
+	vivified-dock.h
diff --git a/vivified/dock/vivi_docklet.c b/vivified/dock/vivi_docklet.c
new file mode 100644
index 0000000..42c8aa2
--- /dev/null
+++ b/vivified/dock/vivi_docklet.c
@@ -0,0 +1,144 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_docklet.h"
+
+enum {
+  PROP_0,
+  PROP_TITLE,
+  PROP_ICON
+};
+
+G_DEFINE_ABSTRACT_TYPE (ViviDocklet, vivi_docklet, GTK_TYPE_BIN)
+
+static void
+vivi_docklet_get_property (GObject *object, guint param_id, GValue *value, 
+    GParamSpec * pspec)
+{
+  ViviDocklet *docklet = VIVI_DOCKLET (object);
+  
+  switch (param_id) {
+    case PROP_TITLE:
+      g_value_set_string (value, docklet->title);
+      break;
+    case PROP_ICON:
+      g_value_set_string (value, docklet->icon);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_docklet_set_property (GObject *object, guint param_id, const GValue *value,
+    GParamSpec *pspec)
+{
+  ViviDocklet *docklet = VIVI_DOCKLET (object);
+
+  switch (param_id) {
+    case PROP_TITLE:
+      vivi_docklet_set_title (docklet, g_value_get_string (value));
+      break;
+    case PROP_ICON:
+      vivi_docklet_set_title (docklet, g_value_get_string (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_docklet_dispose (GObject *object)
+{
+  ViviDocklet *docklet = VIVI_DOCKLET (object);
+
+  g_free (docklet->title);
+  g_free (docklet->icon);
+
+  G_OBJECT_CLASS (vivi_docklet_parent_class)->dispose (object);
+}
+
+static void
+vivi_docklet_class_init (ViviDockletClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_docklet_dispose;
+  object_class->get_property = vivi_docklet_get_property;
+  object_class->set_property = vivi_docklet_set_property;
+
+  g_object_class_install_property (object_class, PROP_TITLE,
+      g_param_spec_string ("title", "title", "title of this docklet",
+	  "Unnamed", G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_ICON,
+      g_param_spec_string ("icon", "icon", "name of the icon to display",
+	  GTK_STOCK_MISSING_IMAGE, G_PARAM_READWRITE));
+}
+
+static void
+vivi_docklet_init (ViviDocklet *docklet)
+{
+  docklet->title = g_strdup ("Unnamed");
+  docklet->icon = g_strdup (GTK_STOCK_MISSING_IMAGE);
+}
+
+void
+vivi_docklet_set_title (ViviDocklet *docklet, const char *title)
+{
+  g_return_if_fail (VIVI_IS_DOCKLET (docklet));
+  g_return_if_fail (title != NULL);
+
+  g_free (docklet->title);
+  docklet->title = g_strdup (title);
+  g_object_notify (G_OBJECT (docklet), "title");
+}
+
+const char *
+vivi_docklet_get_title (ViviDocklet *docklet)
+{
+  g_return_val_if_fail (VIVI_IS_DOCKLET (docklet), NULL);
+
+  return docklet->title;
+}
+
+void
+vivi_docklet_set_icon (ViviDocklet *docklet, const char *icon)
+{
+  g_return_if_fail (VIVI_IS_DOCKLET (docklet));
+  g_return_if_fail (icon != NULL);
+
+  g_free (docklet->icon);
+  docklet->icon = g_strdup (icon);
+  g_object_notify (G_OBJECT (docklet), "icon");
+}
+
+const char *
+vivi_docklet_get_icon (ViviDocklet *docklet)
+{
+  g_return_val_if_fail (VIVI_IS_DOCKLET (docklet), NULL);
+
+  return docklet->icon;
+}
+
diff --git a/vivified/dock/vivi_docklet.h b/vivified/dock/vivi_docklet.h
new file mode 100644
index 0000000..1088252
--- /dev/null
+++ b/vivified/dock/vivi_docklet.h
@@ -0,0 +1,61 @@
+/* Vivified
+ * 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 _VIVI_DOCKLET_H_
+#define _VIVI_DOCKLET_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviDocklet ViviDocklet;
+typedef struct _ViviDockletClass ViviDockletClass;
+
+#define VIVI_TYPE_DOCKLET                    (vivi_docklet_get_type())
+#define VIVI_IS_DOCKLET(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_DOCKLET))
+#define VIVI_IS_DOCKLET_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_DOCKLET))
+#define VIVI_DOCKLET(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_DOCKLET, ViviDocklet))
+#define VIVI_DOCKLET_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_DOCKLET, ViviDockletClass))
+#define VIVI_DOCKLET_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_DOCKLET, ViviDockletClass))
+
+struct _ViviDocklet {
+  GtkBin		bin;
+
+  char *		title;		/* title to be used */
+  char *		icon;		/* name of icon for docklet or "gtk-missing-image" */
+};
+
+struct _ViviDockletClass
+{
+  GtkBinClass		bin_class;
+};
+
+GType			vivi_docklet_get_type   	(void);
+
+void			vivi_docklet_set_title		(ViviDocklet *	docklet,
+							 const char *	titlename);
+const char *		vivi_docklet_get_title		(ViviDocklet *	docklet);
+void			vivi_docklet_set_icon		(ViviDocklet *	docklet,
+							 const char *	titlename);
+const char *		vivi_docklet_get_icon		(ViviDocklet *	docklet);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/dock/vivified-dock.h b/vivified/dock/vivified-dock.h
new file mode 100644
index 0000000..401d6c5
--- /dev/null
+++ b/vivified/dock/vivified-dock.h
@@ -0,0 +1,25 @@
+/* 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 __VIVIFIED_DOCK_H__
+#define __VIVIFIED_DOCK_H__
+
+#include <vivified/dock/vivi_docklet.h>
+
+#endif
diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
index af6ddbd..05e37df 100644
--- a/vivified/ui/Makefile.am
+++ b/vivified/ui/Makefile.am
@@ -2,7 +2,8 @@ noinst_PROGRAMS = vivified
 
 vivified_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS)
 vivified_LDFLAGS = $(SWFDEC_GTK_LIBS) \
-	$(top_builddir)/vivified/core/libvivified-core.la
+	$(top_builddir)/vivified/core/libvivified-core.la \
+	$(top_builddir)/vivified/dock/libvivified-dock.la
 
 vivified_SOURCES = \
 	main.c
diff-tree d416dd57fbf03e1601e10675dee252259b10f762 (from parents)
Merge: db55a9dadd530e0e218cd63516e22b337605224f a52e6ff4dd2e308c031da0434bcdf194b66bbb83
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 8 23:30:49 2007 +0200

    Merge branch 'master' into vivi

diff-tree db55a9dadd530e0e218cd63516e22b337605224f (from eeb38d493a9682147c36977e031c1a064e18591a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Aug 8 23:29:43 2007 +0200

    initial checkin of code that is supposed to become the new debugger

diff --git a/Makefile.am b/Makefile.am
index c90dd0f..4a20c24 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,9 +7,16 @@ else
 GTK_SUBDIRS =
 endif
 
+if HAVE_VIVI
+VIVI_SUBDIRS = vivified
+else
+VIVI_SUBDIRS =
+endif
+
 SUBDIRS= \
 	libswfdec \
 	$(GTK_SUBDIRS) \
+	$(VIVI_SUBDIRS) \
 	test
 
 ACLOCAL_FLAGS = -I m4
diff --git a/autogen.sh b/autogen.sh
index fee343b..2d1f22f 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
 autoreconf -i -f &&
-./configure --enable-maintainer-mode --disable-static --enable-gtk-doc $@
+./configure --enable-maintainer-mode --disable-static --enable-gtk-doc --enable-vivified $@
diff --git a/configure.ac b/configure.ac
index a7b5767..207e360 100644
--- a/configure.ac
+++ b/configure.ac
@@ -264,6 +264,25 @@ else
 fi
 AM_CONDITIONAL(HAVE_HTTP, [test "x$HAVE_HTTP" = xyes])
 
+AC_ARG_ENABLE(vivified,
+	AS_HELP_STRING([--enable-vivified],
+			[enable Vivified Flash debugger (default=no)])],
+	enable_vivi=$enableval,
+	enable_vivi="no")
+if test "$enable_vivi" = "yes"; then
+	MING_REQUIRED=0.4.0.beta5
+	PKG_CHECK_MODULES(VIVI, libming >= $MING_REQUIRED, HAVE_VIVI=yes, HAVE_VIVI=no)
+	if test "x$HAVE_VIVI" = xyes; then
+	  AC_DEFINE(HAVE_VIVI, 1, [Define if Vivified is enabled])
+	else
+	  AC_MSG_ERROR([Vivified requirements not met. You need at libming >= $MING_REQUIRED.])
+	fi
+else
+	AC_MSG_WARN([*** Vivified was not enabled. ***])
+fi
+AM_CONDITIONAL(HAVE_VIVI, [test "x$HAVE_VIVI" = xyes])
+
+
 AC_SUBST(GLOBAL_CFLAGS)
 AC_SUBST(GLOBAL_CFLAGS)
 
@@ -305,6 +324,9 @@ test/image/Makefile
 test/sound/Makefile
 test/trace/Makefile
 test/various/Makefile
+vivified/Makefile
+vivified/core/Makefile
+vivified/ui/Makefile
 swfdec.pc
 swfdec-gtk.pc
 swfdec.spec
diff --git a/vivified/.gitignore b/vivified/.gitignore
new file mode 100644
index 0000000..282522d
--- /dev/null
+++ b/vivified/.gitignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/vivified/Makefile.am b/vivified/Makefile.am
new file mode 100644
index 0000000..fd20116
--- /dev/null
+++ b/vivified/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = core ui
diff --git a/vivified/core/.gitignore b/vivified/core/.gitignore
new file mode 100644
index 0000000..b580c89
--- /dev/null
+++ b/vivified/core/.gitignore
@@ -0,0 +1,12 @@
+*~
+CVS
+.cvsignore
+.deps
+.libs
+
+Makefile
+Makefile.in
+*.o
+*.la
+*.lo
+*.loT
diff --git a/vivified/core/Makefile.am b/vivified/core/Makefile.am
new file mode 100644
index 0000000..dc15041
--- /dev/null
+++ b/vivified/core/Makefile.am
@@ -0,0 +1,11 @@
+noinst_LTLIBRARIES = libvivified-core.la
+
+libvivified_core_la_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS)
+libvivified_core_la_LDFLAGS = $(SWFDEC_GTK_LIBS)
+
+libvivified_core_la_SOURCES = \
+	vivi_application.c
+
+noinst_HEADERS = \
+	vivi_application.h \
+	vivified-core.h
diff --git a/vivified/core/vivi_application.c b/vivified/core/vivi_application.c
new file mode 100644
index 0000000..47a9d96
--- /dev/null
+++ b/vivified/core/vivi_application.c
@@ -0,0 +1,138 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_application.h"
+#include <libswfdec-gtk/swfdec-gtk.h>
+
+enum {
+  PROP_0,
+  PROP_FILENAME,
+  PROP_PLAYER
+};
+
+G_DEFINE_TYPE (ViviApplication, vivi_application, SWFDEC_TYPE_AS_CONTEXT)
+
+static void
+vivi_application_get_property (GObject *object, guint param_id, GValue *value, 
+    GParamSpec * pspec)
+{
+  ViviApplication *app = VIVI_APPLICATION (object);
+  
+  switch (param_id) {
+    case PROP_FILENAME:
+      g_value_set_string (value, app->filename);
+      break;
+    case PROP_PLAYER:
+      g_value_set_object (value, app->player);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_application_set_property (GObject *object, guint param_id, const GValue *value,
+    GParamSpec *pspec)
+{
+  ViviApplication *app = VIVI_APPLICATION (object);
+
+  switch (param_id) {
+    case PROP_FILENAME:
+      vivi_application_set_filename (app, g_value_get_string (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+vivi_application_dispose (GObject *object)
+{
+  ViviApplication *app = VIVI_APPLICATION (object);
+
+  g_object_unref (app->player);
+
+  G_OBJECT_CLASS (vivi_application_parent_class)->dispose (object);
+}
+
+static void
+vivi_application_class_init (ViviApplicationClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = vivi_application_dispose;
+  object_class->get_property = vivi_application_get_property;
+  object_class->set_property = vivi_application_set_property;
+}
+
+static void
+vivi_application_init (ViviApplication *app)
+{
+  app->player = swfdec_gtk_player_new ();
+}
+
+ViviApplication *
+vivi_application_new (void)
+{
+  return g_object_new (VIVI_TYPE_APPLICATION, NULL);
+}
+
+void
+vivi_application_reset (ViviApplication *app)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+
+  g_object_unref (app->player);
+  app->player = swfdec_player_new ();
+}
+
+void
+vivi_application_set_filename (ViviApplication *app, const char *filename)
+{
+  g_return_if_fail (VIVI_IS_APPLICATION (app));
+  g_return_if_fail (filename != NULL);
+
+  g_free (app->filename);
+  app->filename = g_strdup (filename);
+  vivi_application_reset (app);
+  g_object_notify (G_OBJECT (app), "filename");
+}
+
+const char *
+vivi_application_get_filename (ViviApplication *app)
+{
+  g_return_val_if_fail (VIVI_IS_APPLICATION (app), NULL);
+
+  return app->filename;
+}
+
+SwfdecPlayer *
+vivi_application_get_player (ViviApplication *app)
+{
+  g_return_val_if_fail (VIVI_IS_APPLICATION (app), NULL);
+
+  return app->player;
+}
+
diff --git a/vivified/core/vivi_application.h b/vivified/core/vivi_application.h
new file mode 100644
index 0000000..6e0df41
--- /dev/null
+++ b/vivified/core/vivi_application.h
@@ -0,0 +1,63 @@
+/* Vivified
+ * 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 _VIVI_APPLICATION_H_
+#define _VIVI_APPLICATION_H_
+
+#include <libswfdec/swfdec.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviApplication ViviApplication;
+typedef struct _ViviApplicationClass ViviApplicationClass;
+
+#define VIVI_TYPE_APPLICATION                    (vivi_application_get_type())
+#define VIVI_IS_APPLICATION(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_APPLICATION))
+#define VIVI_IS_APPLICATION_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_APPLICATION))
+#define VIVI_APPLICATION(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_APPLICATION, ViviApplication))
+#define VIVI_APPLICATION_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_APPLICATION, ViviApplicationClass))
+#define VIVI_APPLICATION_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_APPLICATION, ViviApplicationClass))
+
+struct _ViviApplication
+{
+  SwfdecAsContext	context;
+
+  char *		filename;	/* name of the file we play back or NULL if none set yet */
+  SwfdecPlayer *	player;		/* the current player */
+};
+
+struct _ViviApplicationClass
+{
+  SwfdecAsContextClass	context_class;
+};
+
+GType			vivi_application_get_type   	(void);
+
+ViviApplication *	vivi_application_new		(void);
+
+void			vivi_application_set_filename	(ViviApplication *	app,
+							 const char *		filename);
+const char *		vivi_application_get_filename	(ViviApplication *	app);
+SwfdecPlayer *	      	vivi_application_get_player	(ViviApplication *	app);
+
+void			vivi_application_reset		(ViviApplication *	app);
+
+G_END_DECLS
+#endif
diff --git a/vivified/core/vivified-core.h b/vivified/core/vivified-core.h
new file mode 100644
index 0000000..34a3fca
--- /dev/null
+++ b/vivified/core/vivified-core.h
@@ -0,0 +1,25 @@
+/* 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 __VIVIFIED_CORE_H__
+#define __VIVIFIED_CORE_H__
+
+#include <vivified/core/vivi_application.h>
+
+#endif
diff --git a/vivified/ui/.gitignore b/vivified/ui/.gitignore
new file mode 100644
index 0000000..1adfd14
--- /dev/null
+++ b/vivified/ui/.gitignore
@@ -0,0 +1,14 @@
+*~
+CVS
+.cvsignore
+.deps
+.libs
+
+Makefile
+Makefile.in
+*.o
+*.la
+*.lo
+*.loT
+
+vivified
diff --git a/vivified/ui/Makefile.am b/vivified/ui/Makefile.am
new file mode 100644
index 0000000..af6ddbd
--- /dev/null
+++ b/vivified/ui/Makefile.am
@@ -0,0 +1,11 @@
+noinst_PROGRAMS = vivified
+
+vivified_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_GTK_CFLAGS)
+vivified_LDFLAGS = $(SWFDEC_GTK_LIBS) \
+	$(top_builddir)/vivified/core/libvivified-core.la
+
+vivified_SOURCES = \
+	main.c
+
+noinst_HEADERS =
+
diff --git a/vivified/ui/main.c b/vivified/ui/main.c
new file mode 100644
index 0000000..7893e7e
--- /dev/null
+++ b/vivified/ui/main.c
@@ -0,0 +1,76 @@
+/* Vivified
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <libswfdec-gtk/swfdec-gtk.h>
+#include "vivified/core/vivified-core.h"
+
+static void
+entry_activate_cb (GtkEntry *entry, ViviApplication *app)
+{
+  const char *text = gtk_entry_get_text (entry);
+
+  if (text[0] == '\0')
+    return;
+
+  //swfdec_player_manager_execute (manager, text);
+  gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
+}
+
+static void
+setup (const char *filename)
+{
+  GtkWidget *window, *box, *widget;
+  ViviApplication *app;
+
+  app = vivi_application_new ();
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  box = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), box);
+  /* widget displaying the Flash */
+  widget = swfdec_gtk_widget_new (NULL);
+  gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
+  /* text entry */
+  widget = gtk_entry_new ();
+  g_signal_connect (widget, "activate", G_CALLBACK (entry_activate_cb), app);
+  gtk_box_pack_end (GTK_BOX (box), widget, FALSE, TRUE, 0);
+
+  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+  gtk_widget_show_all (window);
+}
+
+int
+main (int argc, char **argv)
+{
+  gtk_init (&argc, &argv);
+
+  if (argc != 2) {
+    g_print ("usage: %s FILE\n", argv[0]);
+    return 0;
+  }
+
+  setup (argv[1]);
+  gtk_main ();
+
+  return 0;
+}


More information about the Swfdec mailing list