Origin: upstream, other, *
Description: Applied patches. See Vcs-* headers in debian/control.

--- gxine-0.5.905.orig/mime.default
+++ gxine-0.5.905/mime.default
@@ -75,3 +75,6 @@ video/x-ms-wvx
 video/x-msvideo
 video/x-ogg
 video/x-quicktime
+x-content/video-dvd
+x-content/video-svcd
+x-content/video-vcd
--- gxine-0.5.905.orig/m4/_js.m4
+++ gxine-0.5.905/m4/_js.m4
@@ -41,6 +41,8 @@ AC_DEFUN([GXINE_PATH_SPIDERMONKEY],
 		[AS_HELP_STRING([--with-spidermonkey],[prefix where libjs/libsmjs is installed (optional)])],
 		[JS_CFLAGS="-I$withval"], [])
 
+    AC_ARG_ENABLE([mozjs185],
+        [AS_HELP_STRING([--disable-mozjs185],[don't look for system libmozjs185])])
     AC_ARG_ENABLE([mozjs],
 	[AS_HELP_STRING([--disable-mozjs],[don't look for Mozilla libmozjs])])
     AC_ARG_ENABLE([ffjs],
@@ -51,11 +53,20 @@ AC_DEFUN([GXINE_PATH_SPIDERMONKEY],
     if test x"$JS_CFLAGS" = x; then
       AC_MSG_NOTICE([looking for the Spidermonkey Javascript library in various places.])
 
-      # Try libmozjs (xulrunner)
+      JSLIB=mozjs185
+      AC_MSG_NOTICE([trying mozjs via pkgconfig mozjs185])
+      PKG_CHECK_MODULES([JS],[mozjs185],[],[:])
 
-      HAVE_JS=xulrunner
-      AC_MSG_NOTICE([trying mozjs via pkgconfig xulrunner-js])
-      PKG_CHECK_MODULES([JS],[xulrunner-js],[],[:])
+      if test x"$JS_CFLAGS" = x; then
+        JSLIB=mozjs
+      fi
+
+      # Try libmozjs (xulrunner)
+      if test x"$JS_CFLAGS" = x; then
+        HAVE_JS=xulrunner
+        AC_MSG_NOTICE([trying mozjs via pkgconfig xulrunner-js])
+        PKG_CHECK_MODULES([JS],[xulrunner-js],[],[:])
+      fi
 
       # Try Mozilla
 
@@ -118,6 +129,7 @@ AC_DEFUN([GXINE_PATH_SPIDERMONKEY],
 			  echo moz
 			  ;;
 		   esac`"
+         JSLIB="${JS_LIBS}js"
 	 JS_LIBS="`spidermonkey_locate_lib([$JS_LIBS])`js"
 	 AC_DEFINE(HAVE_LIBSMJS, 1, [Define if you have jsapi.h])
 	],
@@ -125,6 +137,43 @@ AC_DEFUN([GXINE_PATH_SPIDERMONKEY],
 	[#define XP_UNIX])
       CFLAGS="$saved_CFLAGS"
     fi
+
+    SAVED_LIBS="$LIBS"
+    LIBS="$JS_LIBS $LIBS"
+    SAVED_CFLAGS="$CFLAGS"
+    CFLAGS="$JS_CFLAGS $CFLAGS"
+    AC_CHECK_LIB([$JSLIB], [JS_NewCompartmentAndGlobalObject],
+      AC_DEFINE([HAVE_COMPARTMENTS], [1], [Define whether we have compartments]))
+
+    AC_CHECK_LIB([$JSLIB], [JS_GetStringBytes],
+      AC_DEFINE([HAVE_JS_GET_STRING_BYTES], [1], [Define whether we have JS_GetStringBytes]))
+
+    AC_CHECK_LIB([$JSLIB], [JS_NewDouble],
+      AC_DEFINE([HAVE_JS_NEW_DOUBLE], [1], [Define whether we have JS_NewDouble]))
+
+    AC_CHECK_LIB([$JSLIB], [JS_StrictPropertyStub],
+      AC_DEFINE([HAVE_JS_STRICT_PROPERTY_OP], [1], [Define whether we have the JSStrictPropertyOp prototype]))
+
+    AC_COMPILE_IFELSE(
+      [AC_LANG_PROGRAM(
+        [[#include <jsapi.h>]],
+        [[jsval v; jsdouble *d = JSVAL_TO_DOUBLE(v);]]
+      )],
+      AC_DEFINE([JSVAL_TO_DOUBLE_RETURNS_POINTER], [1], [Define whether the JSVAL_TO_DOUBLE function or macro returns a pointer to jsdouble])
+    )
+
+    CFLAGS="$JS_CFLAGS -Werror -Wno-attributes"
+    AC_COMPILE_IFELSE(
+      [AC_LANG_PROGRAM(
+        [[#include <jsapi.h>
+          static JSBool op(JSContext* cx, JSObject* obj, jsid id, jsval* vp) {}]],
+        [[JSPropertyOp func = op;]]
+      )],
+      AC_DEFINE([JS_PROPERTY_OP_HAS_ID_AS_JSID], [1], [Define whether the type of id in the prototype for JSPropertyOp is a jsid])
+    )
+    LIBS="$SAVED_LIBS"
+    CFLAGS="$SAVED_CFLAGS"
+
     AC_SUBST(JS_CFLAGS)
     AC_SUBST(JS_LIBS)
    ])
--- gxine-0.5.905.orig/src/script_engine.c
+++ gxine-0.5.905/src/script_engine.c
@@ -34,7 +34,6 @@
 #include <stdarg.h>
 
 #include <gdk/gdkkeysyms.h>
-#include <jsstr.h>
 
 #include "script_engine.h"
 #include "ui.h"
@@ -53,6 +52,7 @@
 #include "snapshot.h"
 #include "engine.h"
 #include "history.h"
+
 /*
 #define LOG
 */
@@ -194,7 +194,10 @@ gchar *se_result_str (se_t *se)
     return NULL;
 
   se->str = JS_ValueToString (se->cx, se->rval);
-  return JS_GetStringBytes (se->str);
+  char *encoded = SE_JS_ENCODE_STRING(se->cx, se->str);
+  char *res = strdup(encoded);
+  SE_JS_FREE_ENCODED_STRING(se->cx, encoded);
+  return res;
 }
 
 int se_result_int (se_t *se, JSInt32 *num)
@@ -253,8 +256,7 @@ se_js_string_val (JSContext *cx, const c
  * methods
  */
 
-static JSBool controls_exit (JSContext *cx, JSObject *obj, uintN argc,
-			     jsval *argv, jsval *rval)
+static JSBool controls_exit (JSContext *cx, uintN argc, jsval *vp)
 {
   gchar *fname;
 
@@ -299,8 +301,7 @@ static JSBool controls_exit (JSContext *
   exit (0);
 }
 
-static JSBool show_js_console (JSContext *cx, JSObject *obj, uintN argc,
-			       jsval *argv, jsval *rval)
+static JSBool show_js_console (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("show_js_console");
   if (GTK_WIDGET_VISIBLE (se_window))
@@ -311,85 +312,93 @@ static JSBool show_js_console (JSContext
     se_prop_set_int (gse, js_icon_obj, "v", 0);
   }
 
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 static JSBool
-js_callback (JSContext *cx, JSObject *obj,
-	     uintN argc, jsval *argv, jsval *rval)
+js_callback (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_t *se = (se_t *) JS_GetContextPrivate (cx);
   se_log_fncall ("callback");
   se_argc_check_range (1, 2, "callback");
   se_arg_is_string (0, "callback");
   if (argc > 1)
     se_arg_is_object (1, "callback");
-  engine_queue_push (JS_GetStringBytes (JS_ValueToString (cx, argv[0])),
-		     JS_GetPrivate (cx, argc > 1 ? JSVAL_TO_OBJECT (argv[1])
-						 : se->global),
-		     NULL, NULL, NULL, _("JS callback"));
-  *rval = JSVAL_VOID;
+  char *str = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[0]));
+  engine_queue_push (str,
+ 		     JS_GetPrivate (cx, argc > 1 ? JSVAL_TO_OBJECT (argv[1])
+ 						 : se->global),
+ 		     NULL, NULL, NULL, _("JS callback"));
+  SE_JS_FREE_ENCODED_STRING (cx, str);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 static JSBool
-js_xine_cfg_get (JSContext *cx, JSObject *obj,
-		 uintN argc, jsval *argv, jsval *rval)
+js_xine_cfg_get (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall ("xine_cfg_get");
   se_argc_check (1, "xine_cfg_get");
   se_arg_is_string (0, "xine_cfg_get");
 
   xine_cfg_entry_t entry;
-  char *cfg = JS_GetStringBytes (JS_ValueToString (cx, argv[0]));
+  char *cfg = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[0]));
   if (!xine_config_lookup_entry (xine, cfg, &entry))
   {
-    *rval = JSVAL_NULL;
+    JS_SET_RVAL (cx, vp, JSVAL_NULL);
+    SE_JS_FREE_ENCODED_STRING (cx, cfg);
     return JS_TRUE;
   }
 
+  SE_JS_FREE_ENCODED_STRING(cx, cfg);
+
   switch (entry.type)
   {
   case XINE_CONFIG_TYPE_RANGE:
   case XINE_CONFIG_TYPE_NUM:
-    *rval = INT_TO_JSVAL (entry.num_value);
+    JS_SET_RVAL (cx, vp, INT_TO_JSVAL (entry.num_value));
     return JS_TRUE;
 
   case XINE_CONFIG_TYPE_BOOL:
-    *rval = BOOLEAN_TO_JSVAL (entry.num_value);
+    JS_SET_RVAL (cx, vp, BOOLEAN_TO_JSVAL (entry.num_value));
     return JS_TRUE;
 
   case XINE_CONFIG_TYPE_STRING:
-    *rval = se_js_string_val (cx, entry.str_value ? : entry.str_default);
+    JS_SET_RVAL (cx, vp, se_js_string_val (cx, entry.str_value ? : entry.str_default));
     return JS_TRUE;
 
   case XINE_CONFIG_TYPE_ENUM:
-    *rval = se_js_string_val (cx, entry.enum_values[entry.num_value]);
+    JS_SET_RVAL (cx, vp, se_js_string_val (cx, entry.enum_values[entry.num_value]));
     return JS_TRUE;
 
   default:
-    *rval = JSVAL_NULL;
+    JS_SET_RVAL (cx, vp, JSVAL_NULL);
     return JS_TRUE;
   }
 }
 
 static JSBool
-js_xine_cfg_set (JSContext *cx, JSObject *obj,
-		 uintN argc, jsval *argv, jsval *rval)
+js_xine_cfg_set (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall ("xine_cfg_set");
   se_argc_check (2, "xine_cfg_set");
   se_arg_is_string (0, "xine_cfg_set");
 
   xine_cfg_entry_t entry;
-  char *cfg = JS_GetStringBytes (JS_ValueToString (cx, argv[0]));
+  char *cfg = SE_JS_ENCODE_STRING (cx, JS_ValueToString(cx, argv[0]));
   if (!xine_config_lookup_entry (xine, cfg, &entry))
   {
-    *rval = JSVAL_VOID;
+    JS_SET_RVAL (cx, vp, JSVAL_VOID);
+    SE_JS_FREE_ENCODED_STRING (cx, cfg);
     return JS_TRUE;
   }
 
+  SE_JS_FREE_ENCODED_STRING (cx, cfg);
+
   int32 num;
   switch (entry.type)
   {
@@ -413,28 +422,34 @@ js_xine_cfg_set (JSContext *cx, JSObject
 
   case XINE_CONFIG_TYPE_STRING:
     se_arg_is_string (1, "xine_cfg_set");
-    entry.str_value = JS_GetStringBytes (JS_ValueToString (cx, argv[1]));
+    entry.str_value = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[1]));
     break;
 
   case XINE_CONFIG_TYPE_ENUM:
     se_arg_is_string (1, "xine_cfg_set");
-    char *v = JS_GetStringBytes (JS_ValueToString (cx, argv[1]));
+    char *v = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[1]));
     int i;
     for (i = 0; entry.enum_values[i]; ++i)
-      if (!strcmp (v, entry.enum_values[i]))
+      if (!strcmp (v, entry.enum_values[i])) {
+        SE_JS_FREE_ENCODED_STRING (cx, v);
 	break;
+      }
     if (entry.enum_values[i])
       entry.num_value = i;
+    SE_JS_FREE_ENCODED_STRING (cx, v);
     break;
 
   default:
-    *rval = JSVAL_VOID;
+    JS_SET_RVAL (cx, vp, JSVAL_VOID);
     return JS_TRUE;
   }
 
   preferences_update_entry (&entry);
 
-  *rval = JSVAL_VOID;
+  if (entry.type == XINE_CONFIG_TYPE_STRING)
+    SE_JS_FREE_ENCODED_STRING (cx, entry.str_value);
+
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -476,8 +491,7 @@ static char *show_help_int (se_t *se, se
   return help;
 }
 
-static JSBool show_help (JSContext *cx, JSObject *obj, uintN argc,
-			  jsval *argv, jsval *rval)
+static JSBool show_help (JSContext *cx, uintN argc, jsval *vp)
 {
   static char *const group_id[] = {
     NULL,
@@ -530,7 +544,7 @@ static JSBool show_help (JSContext *cx,
    * int get_time ();
    * int get_length ();
    */
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -652,8 +666,9 @@ static jsval get_prop_jsval (se_t *se, s
 
   case SE_TYPE_DOUBLE:
     {
-      jsdouble *d = JS_NewDouble (se->cx, get_prop_double (se, o, p));
-      return DOUBLE_TO_JSVAL (d);
+      jsval rval;
+      SE_JS_NEW_NUMBER_VAL (se->cx, get_prop_double (se, o, p), rval);
+      return rval;
     }
 
   case SE_TYPE_BOOL:
@@ -692,7 +707,7 @@ static void set_prop_jsval (se_t *se, se
 
   case SE_TYPE_DOUBLE:
     if (JSVAL_IS_NUMBER(*v))
-      se_prop_set_double (se, o, p->id, *JSVAL_TO_DOUBLE(*v));
+      se_prop_set_double (se, o, p->id, SE_JSVAL_TO_DOUBLE(*v));
     else
       se->print_cb (se->print_cb_data, _("\n%s.%s: value must be numeric\n"),
 		    o->id, p->id);
@@ -709,8 +724,9 @@ static void set_prop_jsval (se_t *se, se
   case SE_TYPE_STRING:
     {
       JSString *str = JSVAL_TO_STRING(*v);
-      char     *string = JS_GetStringBytes (str);
+      char     *string = SE_JS_ENCODE_STRING (se->cx, str);
       se_prop_set (se, o, p->id, string);
+      SE_JS_FREE_ENCODED_STRING (se->cx, str);
     }
     return;
 
@@ -725,17 +741,17 @@ static void set_prop_jsval (se_t *se, se
  * function to create and maintain js objects
  */
 
-static JSBool
-generic_JSGetProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+SE_JS_PROPERTY_GETTER_DECLARE (generic_JSGetProperty)
 {
+  SE_JS_PROPERTY_GETTER_INIT_VARIABLES (id_val);
   se_t   *se = (se_t *) JS_GetContextPrivate(cx);
   se_log_fncall ("generic get property");
   se_o_t *o = JS_GetPrivate (cx, obj);
 
-  if (JSVAL_IS_STRING (id))
+  if (JSVAL_IS_STRING (id_val))
   {
-    JSString *str = JS_ValueToString (cx, id);
-    char     *prop = str ? JS_GetStringBytes (str) : "";
+    JSString *str = JS_ValueToString (cx, id_val);
+    char     *prop = str ? SE_JS_ENCODE_STRING (cx, str) : "";
     GList    *n;
 
     logprintf ("script_engine: looking for generic property '%s' in '%s'\n",
@@ -749,6 +765,9 @@ generic_JSGetProperty (JSContext *cx, JS
       if (!strcasecmp (p->id, prop))
       {
 	*vp = get_prop_jsval (se, o, p);
+        if (str)
+          SE_JS_FREE_ENCODED_STRING (cx, prop);
+
 	return JS_TRUE;
       }
     }
@@ -760,18 +779,25 @@ generic_JSGetProperty (JSContext *cx, JS
       se_o_t *p = (se_o_t *) n->data;
       if (!strcasecmp (p->id, prop))
       {
-	static jsval prop = 0;
-	if (!prop)
-	  prop = se_js_string_val (cx, ".");
-	if (!generic_JSGetProperty (cx, p->obj, prop, vp))
+	jsval prop_val = se_js_string_val (cx, ".");
+        if (!SE_JS_CALL_PROPERTY_GETTER_WITH_JSVAL (generic_JSGetProperty, cx, p->obj, prop_val, vp))
 	  *vp = OBJECT_TO_JSVAL (p->obj);
+        if (str)
+          SE_JS_FREE_ENCODED_STRING (cx, prop);
+
 	return JS_TRUE;
       }
     }
 
-    if (*prop && o->parent)
-      return generic_JSGetProperty (cx, o->parent->obj, id, vp);
+    if (*prop && o->parent) {
+      JSBool ret = generic_JSGetProperty (cx, o->parent->obj, id, vp);
+      if (str)
+        SE_JS_FREE_ENCODED_STRING (cx, prop);
+      return ret;
+    }
 
+    if (str)
+      SE_JS_FREE_ENCODED_STRING (cx, prop);
     return JS_TRUE;
   }
 
@@ -780,9 +806,9 @@ generic_JSGetProperty (JSContext *cx, JS
   return JS_FALSE;
 }
 
-static JSBool
-generic_JSSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+SE_JS_PROPERTY_SETTER_DECLARE(generic_JSSetProperty)
 {
+  SE_JS_PROPERTY_SETTER_INIT_VARIABLES (id_val);
   se_t   *se = (se_t *) JS_GetContextPrivate(cx);
   se_o_t *o;
 
@@ -790,10 +816,10 @@ generic_JSSetProperty(JSContext *cx, JSO
 
   o = JS_GetPrivate (cx, obj);
 
-  if (JSVAL_IS_STRING (id))
+  if (JSVAL_IS_STRING (id_val))
   {
-    JSString *str = JS_ValueToString (cx, id);
-    char     *prop = JS_GetStringBytes (str);
+    JSString *str = JS_ValueToString (cx, id_val);
+    char     *prop = SE_JS_ENCODE_STRING (cx, str);
     GList    *n;
 
     logprintf ("script_engine: looking for generic property '%s' in '%s'\n",
@@ -808,6 +834,7 @@ generic_JSSetProperty(JSContext *cx, JSO
       {
 	if (!p->constant)
 	  set_prop_jsval (se, o, p, vp);
+        SE_JS_FREE_ENCODED_STRING (cx, prop);
 	return JS_TRUE;
       }
     }
@@ -819,15 +846,21 @@ generic_JSSetProperty(JSContext *cx, JSO
       se_o_t *p = (se_o_t *) n->data;
       if (!strcasecmp (p->id, prop))
       {
-	if (!generic_JSSetProperty (cx, p->obj, STRING_TO_JSVAL("."), vp))
+        jsval prop_val = STRING_TO_JSVAL(".");
+        if (!SE_JS_CALL_PROPERTY_SETTER_WITH_JSVAL (generic_JSSetProperty, cx, p->obj, prop_val, vp))
 	  *vp = OBJECT_TO_JSVAL (p->obj);
+        SE_JS_FREE_ENCODED_STRING (cx, prop);
 	return JS_TRUE;
       }
     }
 
-    if (*prop && o->parent)
-      return generic_JSSetProperty (cx, o->parent->obj, id, vp);
+    if (*prop && o->parent) {
+      JSBool ret = SE_JS_CALL_PROPERTY_SETTER_WITH_JSVAL (generic_JSSetProperty, cx, o->parent->obj, id_val, vp);
+      SE_JS_FREE_ENCODED_STRING (cx, prop);
+      return ret;
+    }
 
+    SE_JS_FREE_ENCODED_STRING (cx, prop);
     return JS_TRUE;
   }
 
@@ -841,14 +874,35 @@ static void generic_JSDestructor (JSCont
   se_log_fncall ("generic destructor");
 }
 
+#ifdef JSFUN_CONSTRUCTOR
+static JSBool generic_Constructor (JSContext* cx, uintN argc, jsval* vp)
+{
+  JSObject* obj = JS_NewObjectForConstructor (cx, vp);
+  if (!obj) {
+    JS_ReportError (cx, "Failed to create 'this' object");
+    return JS_FALSE;
+  }
+
+  JS_SET_RVAL (cx, vp, OBJECT_TO_JSVAL (obj));
+  return JS_TRUE;
+}
+#endif
+
 static JSClass generic_JSClass =
   {
     "view", JSCLASS_HAS_PRIVATE,
     JS_PropertyStub, JS_PropertyStub,
     generic_JSGetProperty, generic_JSSetProperty,
     JS_EnumerateStub, JS_ResolveStub,
+#ifndef JSFUN_CONSTRUCTOR
     JS_ConvertStub, generic_JSDestructor
   };
+#else
+    JS_ConvertStub, generic_JSDestructor,
+    NULL, NULL, NULL, generic_Constructor,
+    NULL, NULL, NULL, NULL
+  };
+#endif
 
 se_o_t *se_create_object (se_t *se, se_o_t *parent /* may be NULL */,
 			  const gchar *name, void *user_data,
@@ -1542,7 +1596,7 @@ se_t *se_new (void)
 {
   se_t    *se;
   static JSClass global_class = {
-    "global", JSCLASS_HAS_PRIVATE,
+    "global", JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
     JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
   };
@@ -1564,7 +1618,13 @@ se_t *se_new (void)
   se = malloc (sizeof (se_t));
 
   se->cx       = JS_NewContext (rt, 0x1000);
+#ifdef HAVE_COMPARTMENTS
+  se->global   = JS_NewCompartmentAndGlobalObject (se->cx, &global_class, NULL);
+  /* Select the compartment our global object is in */
+  JS_EnterCrossCompartmentCall (se->cx, se->global);
+#else
   se->global   = JS_NewObject (se->cx, &global_class, NULL, NULL);
+#endif
 
   pthread_mutexattr_t attr;
   pthread_mutexattr_init (&attr);
@@ -1596,12 +1656,12 @@ se_t *se_new (void)
 
   {
     static const se_f_def_t defs[] = {
-      { "exit", controls_exit, 0, 0, SE_GROUP_ENGINE, NULL, NULL },
-      { "js_console_show", show_js_console, 0, 0, SE_GROUP_DIALOGUE, NULL, NULL },
-      { "help", show_help, 0, 0, SE_GROUP_HIDDEN, NULL, NULL },
-      { "callback", js_callback, 0, 0, SE_GROUP_ENGINE, N_("Javascript"), NULL },
-      { "xine_cfg_get", js_xine_cfg_get, 0, 0, SE_GROUP_PROPERTIES, NULL, NULL },
-      { "xine_cfg_set", js_xine_cfg_set, 0, 0, SE_GROUP_PROPERTIES, NULL, NULL },
+      { "exit", controls_exit, 0, JSFUN_FAST_NATIVE, SE_GROUP_ENGINE, NULL, NULL },
+      { "js_console_show", show_js_console, 0, JSFUN_FAST_NATIVE, SE_GROUP_DIALOGUE, NULL, NULL },
+      { "help", show_help, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL },
+      { "callback", js_callback, 0, JSFUN_FAST_NATIVE, SE_GROUP_ENGINE, N_("Javascript"), NULL },
+      { "xine_cfg_get", js_xine_cfg_get, 0, JSFUN_FAST_NATIVE, SE_GROUP_PROPERTIES, NULL, NULL },
+      { "xine_cfg_set", js_xine_cfg_set, 0, JSFUN_FAST_NATIVE, SE_GROUP_PROPERTIES, NULL, NULL },
       { NULL }
     };
     se_defuns (se, se->g, defs);
--- gxine-0.5.905.orig/src/ui.c
+++ gxine-0.5.905/src/ui.c
@@ -490,14 +490,14 @@ static void set_fs_toolbar_top (int v)
 
 #ifdef WITH_DEPRECATED
 
-static JSBool js_fs_toolbar_show (JSContext *cx, JSObject *obj, uintN argc,
-				  jsval *argv, jsval *rval)
+static JSBool js_fs_toolbar_show (JSContext *cx, uintN argc, jsval *vp)
 {
   JSBool show;
 
   se_log_fncall_deprecated ("toolbar_show");
   se_argc_check_max (1, "toolbar_show");
 
+  jsval *argv = JS_ARGV (cx, vp);
   if (argc == 1)
   {
     se_arg_is_int_or_bool (0, "toolbar_show");
@@ -508,19 +508,20 @@ static JSBool js_fs_toolbar_show (JSCont
 
   window_fs_toolbar_show (show);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 #ifdef WITH_OBSOLETE
 
-static JSBool js_fs_toolbar_position (JSContext *cx, JSObject *obj, uintN argc,
-				      jsval *argv, jsval *rval)
+static JSBool js_fs_toolbar_position (JSContext *cx, uintN argc, jsval *vp)
 {
   JSBool top;
 
   se_log_fncall_obsolete ("set_toolbar_position");
   se_argc_check_max (1, "set_toolbar_position");
 
+  jsval *argv = JS_ARGV (cx, vp);
   if (argc == 1)
   {
     se_arg_is_int_or_bool (0, "set_toolbar_position");
@@ -532,6 +533,7 @@ static JSBool js_fs_toolbar_position (JS
   set_fs_toolbar_top
     (gtk_radio_action_get_current_value (action_items.fs_toolbar_pos->data));
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -549,23 +551,21 @@ static int ui_lookup_js_obj (const JSObj
   abort (); /* can't happen */
 }
 
-static JSBool js_control_revert (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_control_revert (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall ("<control>.revert");
   se_argc_check (0, "<control>.revert");
-  ui_revert_control_adjustment (ui_lookup_js_obj (obj));
-  *rval = JSVAL_VOID;
+  ui_revert_control_adjustment (ui_lookup_js_obj (JS_THIS_OBJECT (cx, vp)));
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_control_reset (JSContext *cx, JSObject *obj, uintN argc,
-				jsval *argv, jsval *rval)
+static JSBool js_control_reset (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall ("<control>.reset");
   se_argc_check (0, "<control>.reset");
-  ui_clear_control_adjustment (ui_lookup_js_obj (obj));
-  *rval = JSVAL_VOID;
+  ui_clear_control_adjustment (ui_lookup_js_obj (JS_THIS_OBJECT (cx, vp)));
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -654,13 +654,12 @@ static int ui_prop_set_bool (void *data,
   return ui_prop_set_internal (data, !!value.i);
 }
 
-static JSBool ui_prop_toggle_bool (JSContext *cx, JSObject *obj,
-				   uintN argc, jsval *argv, jsval *rval)
+static JSBool ui_prop_toggle_bool (JSContext *cx, uintN argc, jsval *vp)
 {
   se_t *se = (se_t *) JS_GetContextPrivate(cx);
-  se_o_t *o = JS_GetPrivate (cx, obj);
+  se_o_t *o = JS_GetPrivate (cx, JS_THIS_OBJECT (cx, vp));
   JSBool v = !se_prop_get_bool (se, o, "v");
-  *rval = BOOLEAN_TO_JSVAL (v);
+  JS_SET_RVAL (cx, vp, BOOLEAN_TO_JSVAL (v));
   se_prop_set_bool (se, o, "v", v);
   return JS_TRUE;
 }
@@ -699,7 +698,7 @@ void ui_create_properties (const ui_prop
       se_prop_create_int (gse, obj, "max", prop[i].max, TRUE);
       break;
     case SE_TYPE_BOOL:
-      se_defun (gse, obj, "toggle", ui_prop_toggle_bool, 0, 0,
+      se_defun (gse, obj, "toggle", ui_prop_toggle_bool, 0, JSFUN_FAST_NATIVE,
 		SE_GROUP_HIDDEN, NULL, NULL);
       break;
     default:; /* we don't handle string and float */
@@ -1044,10 +1043,10 @@ void ui_init (void)
 
 #ifdef WITH_DEPRECATED
   static const se_f_def_t defs[] = {
-    { "toolbar_show", js_fs_toolbar_show, 0, 0,
+    { "toolbar_show", js_fs_toolbar_show, 0, JSFUN_FAST_NATIVE,
       SE_GROUP_HIDDEN, N_("[bool]"), NULL },
 #ifdef WITH_OBSOLETE
-    { "set_toolbar_position", js_fs_toolbar_position, 0, 0,
+    { "set_toolbar_position", js_fs_toolbar_position, 0, JSFUN_FAST_NATIVE,
       SE_GROUP_HIDDEN, N_("bool"), N_("at top if true") },
 #endif
     { NULL }
@@ -1091,8 +1090,8 @@ void ui_init (void)
     if (ranges[i].setting)
     {
       static const se_f_def_t defs[] = {
-	{ "revert", js_control_revert, 0, 0, SE_GROUP_HIDDEN, NULL, NULL },
-	{ "reset", js_control_reset, 0, 0, SE_GROUP_HIDDEN, NULL, NULL },
+	{ "revert", js_control_revert, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL },
+	{ "reset", js_control_reset, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL },
 	{ NULL }
       };
       jsobjs[i] =
--- gxine-0.5.905.orig/src/player.c
+++ gxine-0.5.905/src/player.c
@@ -302,6 +302,7 @@ void player_stop (void)
   play_thread = 0;
   if (thread)
     pthread_cancel (thread);
+  gtk_video_in_spu_button (gtv, 0);
   xine_stop (stream);
 }
 
@@ -405,37 +406,36 @@ static void update_postproc_chain (const
 }
 
 static JSBool set_postproc_chain (const char *func, const char *pref,
-				  JSContext *cx, JSObject *obj,
-				  uintN argc, jsval *argv, jsval *rval)
+				  JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall (func);
   se_argc_check (1, func);
   se_arg_is_string (0, func);
-  update_postproc_chain (pref,
-			 JS_GetStringBytes (JS_ValueToString (cx, argv[0])));
+  char *value = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[0]));
+  update_postproc_chain (pref, value);
+  SE_JS_FREE_ENCODED_STRING(cx, value);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 
-static JSBool set_vo_postproc_chain (JSContext *cx, JSObject *obj,
-				     uintN argc, jsval *argv, jsval *rval)
+static JSBool set_vo_postproc_chain (JSContext *cx, uintN argc, jsval *vp)
 {
   return set_postproc_chain ("vo_postproc.set_chain", "gui.post_plugins.video",
-			     cx, obj, argc, argv, rval);
+			     cx, argc, vp);
 }
 
-static JSBool set_deint_postproc_chain (JSContext *cx, JSObject *obj,
-					uintN argc, jsval *argv, jsval *rval)
+static JSBool set_deint_postproc_chain (JSContext *cx, uintN argc, jsval *vp)
 {
   return set_postproc_chain ("vo_deinterlace.set_chain", "gui.post_plugins.deinterlace",
-			     cx, obj, argc, argv, rval);
+			     cx, argc, vp);
 }
 
-static JSBool set_ao_postproc_chain (JSContext *cx, JSObject *obj,
-				     uintN argc, jsval *argv, jsval *rval)
+static JSBool set_ao_postproc_chain (JSContext *cx, uintN argc, jsval *vp)
 {
   return set_postproc_chain ("ao_postproc.set_chain", "gui.post_plugins.audio",
-			     cx, obj, argc, argv, rval);
+			     cx, argc, vp);
 }
 
 static int listen_postproc_chain (void *pref, se_t *se, se_o_t *obj,
@@ -445,89 +445,82 @@ static int listen_postproc_chain (void *
   return 0;
 }
 
-static JSBool get_time (JSContext *cx, JSObject *obj, uintN argc,
-		     jsval *argv, jsval *rval)
+static JSBool get_time (JSContext *cx, uintN argc, jsval *vp)
 {
   int   pos, pos_time, len;
   se_log_fncall ("get_time");
   xine_get_pos_length (stream, &pos, &pos_time, &len);
-  *rval = INT_TO_JSVAL (pos_time);
+  JS_SET_RVAL (cx, vp, INT_TO_JSVAL (pos_time));
   return JS_TRUE;
 }
 
-static JSBool get_pos (JSContext *cx, JSObject *obj, uintN argc,
-		       jsval *argv, jsval *rval)
+static JSBool get_pos (JSContext *cx, uintN argc, jsval *vp)
 {
   int pos, pos_time, len;
   se_log_fncall ("get_pos");
   xine_get_pos_length (stream, &pos, &pos_time, &len);
 
-  jsdouble *pos_percent = JS_NewDouble (cx, pos / 655.35);
-  *rval = DOUBLE_TO_JSVAL (pos_percent);
+  jsval rval = JS_RVAL (cx, vp);
+  SE_JS_NEW_NUMBER_VAL (cx, pos / 655.35, rval);
   return JS_TRUE;
 }
 
-static JSBool has_time (JSContext *cx, JSObject *obj, uintN argc,
-			jsval *argv, jsval *rval)
+static JSBool has_time (JSContext *cx, uintN argc, jsval *vp)
 {
   int pos, pos_time, len;
   se_log_fncall ("has_time");
   xine_get_pos_length (stream, &pos, &pos_time, &len);
-  *rval = BOOLEAN_TO_JSVAL (len != 0);
+  JS_SET_RVAL (cx, vp, BOOLEAN_TO_JSVAL (len != 0));
   return JS_TRUE;
 }
 
 #ifdef WITH_OBSOLETE
 
-static JSBool js_get_speed (JSContext *cx, JSObject *obj, uintN argc,
-			    jsval *argv, jsval *rval)
+static JSBool js_get_speed (JSContext *cx, uintN argc, jsval *vp)
 {
   se_prop_read_t speed;
   se_log_fncall_obsolete ("get_speed");
   get_speed (NULL, &speed);
-  *rval = INT_TO_JSVAL (speed.i);
+  JS_SET_RVAL (cx, vp, INT_TO_JSVAL (speed.i));
   return JS_TRUE;
 }
 
-static JSBool js_get_volume (JSContext *cx, JSObject *obj, uintN argc,
-			    jsval *argv, jsval *rval)
+static JSBool js_get_volume (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   int   volume;
   se_log_fncall_obsolete ("get_volume");
   volume = xine_get_param (stream, XINE_PARAM_AUDIO_VOLUME);
-  *rval = INT_TO_JSVAL (volume);
+  JS_SET_RVAL (cx, vp, INT_TO_JSVAL (volume));
   return JS_TRUE;
 }
 
-static JSBool js_get_mute (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_get_mute (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   int mute;
   se_log_fncall_obsolete ("get_mute");
   mute = xine_get_param (stream, XINE_PARAM_AUDIO_MUTE);
-  *rval = BOOLEAN_TO_JSVAL (mute);
+  JS_SET_RVAL (cx, vp, BOOLEAN_TO_JSVAL (mute));
   return JS_TRUE;
 }
 
-static JSBool js_get_zoom (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_get_zoom (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   int   zoom;
   se_log_fncall_obsolete ("get_zoom");
   zoom = xine_get_param (stream, XINE_PARAM_VO_ZOOM_X);
-  *rval = INT_TO_JSVAL (zoom);
+  JS_SET_RVAL (cx, vp, INT_TO_JSVAL (zoom));
   return JS_TRUE;
 }
 
 #endif /* WITH_OBSOLETE */
 
-static JSBool controls_pause (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool controls_pause (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 pause_state=-1;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_checkinit ("pause");
   se_argc_check_max (1, "pause");
@@ -553,21 +546,21 @@ static JSBool controls_pause (JSContext
       set_speed (XINE_SPEED_NORMAL);
   }
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool controls_stop (JSContext *cx, JSObject *obj, uintN argc,
-			     jsval *argv, jsval *rval)
+static JSBool controls_stop (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("stop");
   player_stop ();
   playlist_logo (NULL);
   ui_set_control_adjustment (Control_SEEKER, 0);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool controls_eject (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool controls_eject (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("eject");
   if (xine_get_status (stream) == XINE_STATUS_PLAY)
@@ -576,17 +569,18 @@ static JSBool controls_eject (JSContext
   playlist_logo (cx); /* doesn't matter so long as it's not NULL */
   gdk_threads_enter ();
   ui_set_control_adjustment (Control_SEEKER, 0);
+  gtk_video_in_spu_button (gtv, 0);
   int ret = xine_eject (stream);
-  *rval = BOOLEAN_TO_JSVAL (ret);
+  JS_SET_RVAL (cx, vp, BOOLEAN_TO_JSVAL (ret));
   return JS_TRUE;
 }
 
 #ifdef WITH_OBSOLETE
 
-static JSBool js_set_speed (JSContext *cx, JSObject *obj, uintN argc,
-			    jsval *argv, jsval *rval)
+static JSBool js_set_speed (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 speed;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_speed");
 
@@ -599,13 +593,14 @@ static JSBool js_set_speed (JSContext *c
     speed = 0;
   set_speed (calc_speed (speed));
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_volume (JSContext *cx, JSObject *obj, uintN argc,
-			    jsval *argv, jsval *rval)
+static JSBool js_set_volume (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 volume;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_volume");
   se_argc_check (1, "set_volume");
@@ -618,13 +613,14 @@ static JSBool js_set_volume (JSContext *
   ui_set_control_adjustment (Control_VOLUME, volume);
   ui_xine_set_param_from_adjustment (Control_VOLUME);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_mute (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_set_mute (JSContext *cx, uintN argc, jsval *vp)
 {
   JSBool mute;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_mute");
   se_argc_check_max (1, "set_mute");
@@ -639,13 +635,14 @@ static JSBool js_set_mute (JSContext *cx
 
   set_mute (mute);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_zoom (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_set_zoom (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 zoom;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_zoom");
   se_argc_check (1, "set_zoom");
@@ -654,6 +651,7 @@ static JSBool js_set_zoom (JSContext *cx
   JS_ValueToInt32 (cx, argv[0], &zoom);
   set_zoom (zoom);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -684,9 +682,9 @@ static gboolean set_video_size_cb (gpoin
   return FALSE;
 }
 
-static JSBool js_set_video_size (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_set_video_size (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall ("set_video_size");
   se_argc_check (1, "set_video_size");
   se_arg_is_int (0, "set_video_size");
@@ -704,15 +702,16 @@ static JSBool js_set_video_size (JSConte
     g_source_remove (zoomcb_id);
   zoomcb_id = g_idle_add ((GSourceFunc) set_video_size_cb, NULL);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 #ifdef WITH_DEPRECATED
 
-static JSBool js_set_fullscreen (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_set_fullscreen (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 fs;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_deprecated ("set_fullscreen");
   se_argc_check_max (1, "set_fullscreen");
@@ -728,15 +727,16 @@ static JSBool js_set_fullscreen (JSConte
   if (gtk_toggle_action_get_active (action_items.fullscreen) != fs)
     gtk_action_activate (GTK_ACTION (action_items.fullscreen));
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 #ifdef WITH_OBSOLETE
 
-static JSBool js_set_deinterlace (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_set_deinterlace (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 di;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_deinterlace");
   se_argc_check_max (1, "set_deinterlace");
@@ -750,14 +750,15 @@ static JSBool js_set_deinterlace (JSCont
     di = !gtk_video_get_use_post_plugins_deinterlace ((GtkVideo *)gtv);
 
   set_deinterlace (di);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_postproc_video (JSContext *cx, JSObject *obj,
-				     uintN argc, jsval *argv, jsval *rval)
+static JSBool js_set_postproc_video (JSContext *cx, uintN argc, jsval *vp)
 {
   se_t *se = (se_t *) JS_GetContextPrivate(cx);
   int32 di;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_postproc_video");
   se_argc_check_max (1, "set_postproc_video");
@@ -767,26 +768,28 @@ static JSBool js_set_postproc_video (JSC
     if (JSVAL_IS_INT (argv[0]))
       JS_ValueToInt32 (cx, argv[0], &di);
     else if (JSVAL_IS_STRING (argv[0]))
-      return set_vo_postproc_chain (cx, obj, argc, argv, rval);
+      return set_vo_postproc_chain (cx, argc, vp);
     else
     {
       se->print_cb (se->print_cb_data,
 		   _("error: %s() argument %d is neither int nor string\n"),
 		   "set_postproc_video", 1);
+      JS_SET_RVAL (cx, vp, JSVAL_VOID);
       return JS_TRUE;
     }
   } else
     di = !gtk_video_get_use_post_plugins_video ((GtkVideo *)gtv);
 
   set_vo_postproc (di);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_postproc_audio (JSContext *cx, JSObject *obj,
-				     uintN argc, jsval *argv, jsval *rval)
+static JSBool js_set_postproc_audio (JSContext *cx, uintN argc, jsval *vp)
 {
   se_t *se = (se_t *) JS_GetContextPrivate(cx);
   int32 di;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_postproc_audio");
   se_argc_check_max (1, "set_postproc_audio");
@@ -796,25 +799,27 @@ static JSBool js_set_postproc_audio (JSC
     if (JSVAL_IS_INT (argv[0]))
       JS_ValueToInt32 (cx, argv[0], &di);
     else if (JSVAL_IS_STRING (argv[0]))
-      return set_ao_postproc_chain (cx, obj, argc, argv, rval);
+      return set_ao_postproc_chain (cx, argc, vp);
     else
     {
       se->print_cb (se->print_cb_data,
 		   _("error: %s() argument %d is neither int nor string\n"),
 		   "set_postproc_audio", 1);
+      JS_SET_RVAL (cx, vp, JSVAL_VOID);
       return JS_TRUE;
     }
   } else
     di = !gtk_video_get_use_post_plugins_audio ((GtkVideo *)gtv);
 
   set_ao_postproc (di);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_auto_resize (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_set_auto_resize (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 ar;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_auto_resize");
   se_argc_check_max (1, "set_auto_resize");
@@ -828,13 +833,14 @@ static JSBool js_set_auto_resize (JSCont
     ar = !gtk_video_get_auto_resize ((GtkVideo *)gtv);
 
   set_auto_resize (ar);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_auto_rescale (JSContext *cx, JSObject *obj, uintN argc,
-				   jsval *argv, jsval *rval)
+static JSBool js_set_auto_rescale (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 ar;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_auto_rescale");
   se_argc_check_max (1, "set_auto_rescale");
@@ -848,13 +854,14 @@ static JSBool js_set_auto_rescale (JSCon
     ar = !gtk_video_get_auto_rescale ((GtkVideo *)gtv);
 
   set_auto_rescale (ar);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_set_aspect (JSContext *cx, JSObject *obj, uintN argc,
-			     jsval *argv, jsval *rval)
+static JSBool js_set_aspect (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 aspect;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_obsolete ("set_aspect");
   se_argc_check_max (1, "set_aspect");
@@ -868,18 +875,19 @@ static JSBool js_set_aspect (JSContext *
     aspect = xine_get_param (stream, XINE_PARAM_VO_ASPECT_RATIO) + 1;
 
   set_aspect (aspect);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 #endif /* WITH_OBSOLETE */
 #endif /* WITH_DEPRECATED */
 
-static JSBool js_snapshot (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_snapshot (JSContext *cx, uintN argc, jsval *vp)
 {
   JSString *str;
   char     *fname = NULL;
   int32	    scale = -1, blend = -1;
+  jsval    *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_checkinit ("snapshot");
   se_argc_check_range (0, 3, "snapshot");
@@ -895,18 +903,20 @@ static JSBool js_snapshot (JSContext *cx
   case 1:
     se_arg_is_string (0, "snapshot");
     str = JS_ValueToString (cx, argv[0]);
-    fname = JS_GetStringBytes (str);
+    fname = SE_JS_ENCODE_STRING (cx, str);
   }
 
   make_snapshot (fname, scale, blend);
 
+  SE_JS_FREE_ENCODED_STRING (cx, fname);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 
-static JSBool controls_play (JSContext *cx, JSObject *obj, uintN argc,
-			     jsval *argv, jsval *rval)
+static JSBool controls_play (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall_checkinit ("play");
   se_argc_check_max (3, "play");
 
@@ -925,7 +935,7 @@ static JSBool controls_play (JSContext *
 
       str = JS_ValueToString (cx, argv[0]);
 
-      mrl = JS_GetStringBytes (str);
+      mrl = SE_JS_ENCODE_STRING (cx, str);
       se_log ("playing '%s' from start\n", mrl);
     }
     break;
@@ -935,9 +945,10 @@ static JSBool controls_play (JSContext *
       se_arg_is_number (0, "play");
       se_arg_is_int (1, "play");
 
-      jsdouble *posv = JS_NewDouble (cx, 0); /* when is this freed? */
-      JS_ValueToNumber (cx, argv[0], posv);
-      pos = (*posv >= 0 && *posv < 100) ? *posv * 655.35 : -1;
+      jsdouble posv;
+      JS_ValueToNumber (cx, argv[0], &posv);
+      pos = (posv >= 0 && posv < 100) ? posv * 655.35 : -1;
+
       JS_ValueToInt32 (cx, argv[1], &pos_time);
       mrl = NULL;
       se_log ("playing from %d, %d\n", pos, pos_time);
@@ -951,18 +962,23 @@ static JSBool controls_play (JSContext *
       se_arg_is_int (2, "play");
 
       JSString *str = JS_ValueToString (cx, argv[0]);
-      jsdouble *posv = JS_NewDouble (cx, 0); /* when is this freed? */
-      JS_ValueToNumber (cx, argv[1], posv);
-      pos = (*posv >= 0 && *posv < 100) ? *posv * 655.35 : -1;
+
+      jsdouble posv;
+      JS_ValueToNumber (cx, argv[1], &posv);
+      pos = (posv >= 0 && posv < 100) ? posv * 655.35 : -1;
+
       JS_ValueToInt32 (cx, argv[2], &pos_time);
-      mrl = JS_GetStringBytes (str);
+      mrl = SE_JS_ENCODE_STRING (cx, str);
       se_log ("playing '%s' from %d, %d\n", mrl, pos, pos_time);
     }
     break;
   }
 
   if (mrl)
+  {
     playlist_play_from (playlist_add_mrl (mrl, -1), pos, pos_time);
+    SE_JS_FREE_ENCODED_STRING (cx, mrl);
+  }
   else
   {
     play_item_t *item = playlist_get_current_item ();
@@ -990,15 +1006,16 @@ static JSBool controls_play (JSContext *
   }
   set_speed (XINE_SPEED_NORMAL);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 /* Crude hack to allow combined play/pause function.
  * (Useful on some keyboards with CD/DVD control keys.)
  */
-static JSBool controls_play_pause (JSContext *cx, JSObject *obj, uintN argc,
-				  jsval *argv, jsval *rval)
+static JSBool controls_play_pause (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall_checkinit ("play_pause");
   se_argc_check_max (1, "play_pause");
 
@@ -1009,22 +1026,21 @@ static JSBool controls_play_pause (JSCon
   {
   case XINE_STATUS_STOP:
   case XINE_STATUS_IDLE:
-    return controls_play (cx, obj, 0, 0, rval);
+    return controls_play (cx, argc, vp);
   default:
-    return controls_pause (cx, obj, argc, argv, rval);
+    return controls_pause (cx, argc, vp);
   }
 }
 
-static JSBool js_is_live_stream (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_is_live_stream (JSContext *cx, uintN argc, jsval *vp)
 {
-  *rval = JSVAL_FALSE;
+  JS_SET_RVAL(cx, vp, JSVAL_FALSE);
 
   se_log_fncall ("is_live_stream");
   se_argc_check_max (0, "is_live_stream");
 
   if (player_live_stream ())
-    *rval = JSVAL_TRUE;
+    JS_SET_RVAL (cx, vp, JSVAL_TRUE);
 
   return JS_TRUE;
 }
@@ -1087,12 +1103,11 @@ static xine_audio_port_t *load_audio_out
 /* Properties */
 
 static void add_chain_funcs (const char *prop, const char *config,
-			     JSBool (*set_chain) (JSContext *, JSObject *,
-						  uintN, jsval *, jsval *))
+			     JSBool (*set_chain) (JSContext *, uintN, jsval *))
 {
   se_o_t *obj = se_find_object (gse, NULL, prop);
   if (set_chain)
-    se_defun (gse, obj, "set_chain", set_chain, 0, 0, SE_GROUP_HIDDEN, NULL, NULL);
+    se_defun (gse, obj, "set_chain", set_chain, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL);
   se_prop_create_xine_id (gse, obj, "chain", config);
   se_prop_add_listener (gse, obj, "chain",
 			listen_postproc_chain, (void *)config);
@@ -1194,69 +1209,69 @@ void player_init (void)
 
   {
     static const se_f_def_t defs[] = {
-      { "play", controls_play, 0, 0,
+      { "play", controls_play, 0, JSFUN_FAST_NATIVE,
 	/* help text describes function parameters */
 	SE_GROUP_ENGINE, N_("[mrl] [, pos, time]"),
 	N_("time in milliseconds") },
-      { "get_time", get_time, 0, 0,
+      { "get_time", get_time, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, NULL, N_("stream time index") },
-      { "get_pos", get_pos, 0, 0,
+      { "get_pos", get_pos, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, NULL, N_("stream position (%)") },
-      { "has_time", has_time, 0, 0,
+      { "has_time", has_time, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, NULL, N_("whether the stream has a time index") },
-      { "pause", controls_pause, 0, 0,
+      { "pause", controls_pause, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, N_("[bool]"), NULL },
-      { "stop", controls_stop, 0, 0,
+      { "stop", controls_stop, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, NULL, NULL },
-      { "eject", controls_eject, 0, 0,
+      { "eject", controls_eject, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, NULL, NULL },
-      { "play_pause", controls_play_pause, 0, 0,
+      { "play_pause", controls_play_pause, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_ENGINE, N_("[bool]"), NULL },
-      { "snapshot", js_snapshot, 0, 0,
+      { "snapshot", js_snapshot, 0, JSFUN_FAST_NATIVE,
 	/* these correspond to the options in the snapshot-save dialogue box */
 	SE_GROUP_ENGINE, N_("[file name [, scale, blend]]"), NULL },
 
-      { "set_video_size", js_set_video_size, 0, 0,
+      { "set_video_size", js_set_video_size, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PROPERTIES, N_("int"), NULL },
 
 #ifdef WITH_DEPRECATED
 #ifdef WITH_OBSOLETE
-      { "set_speed", js_set_speed, 0, 0,
+      { "set_speed", js_set_speed, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "get_speed", js_get_speed, 0, 0,
+      { "get_speed", js_get_speed, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_volume", js_set_volume, 0, 0,
+      { "set_volume", js_set_volume, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "get_volume", js_get_volume, 0, 0,
+      { "get_volume", js_get_volume, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_mute", js_set_mute, 0, 0,
+      { "set_mute", js_set_mute, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "get_mute", js_get_mute, 0, 0,
+      { "get_mute", js_get_mute, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_zoom", js_set_zoom, 0, 0,
+      { "set_zoom", js_set_zoom, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "get_zoom", js_get_zoom, 0, 0,
+      { "get_zoom", js_get_zoom, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
 #endif /* WITH_OBSOLETE */
-      { "set_fullscreen", js_set_fullscreen, 0, 0,
+      { "set_fullscreen", js_set_fullscreen, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
 #ifdef WITH_OBSOLETE
-      { "set_aspect", js_set_aspect, 0, 0,
+      { "set_aspect", js_set_aspect, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_deinterlace", js_set_deinterlace, 0, 0,
+      { "set_deinterlace", js_set_deinterlace, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_postproc_video", js_set_postproc_video, 0, 0,
+      { "set_postproc_video", js_set_postproc_video, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_postproc_audio", js_set_postproc_audio, 0, 0,
+      { "set_postproc_audio", js_set_postproc_audio, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_auto_resize", js_set_auto_resize, 0, 0,
+      { "set_auto_resize", js_set_auto_resize, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
-      { "set_auto_rescale", js_set_auto_rescale, 0, 0,
+      { "set_auto_rescale", js_set_auto_rescale, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
 #endif /* WITH_OBSOLETE */
 #endif /* WITH_DEPRECATED */
 
-      { "is_live_stream", js_is_live_stream, 0, 0,
+      { "is_live_stream", js_is_live_stream, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PROPERTIES, NULL, NULL },
       { NULL }
     };
--- gxine-0.5.905.orig/src/wizards.c
+++ gxine-0.5.905/src/wizards.c
@@ -414,17 +414,17 @@ void run_wizards (gboolean requested)
   }
 }
 
-static JSBool js_run_wizards (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool js_run_wizards (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("run_wizards");
   run_wizards (TRUE);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 void wizards_init (void)
 {
-  se_defun (gse, NULL, "run_wizards", js_run_wizards, 0, 0,
+  se_defun (gse, NULL, "run_wizards", js_run_wizards, 0, JSFUN_FAST_NATIVE,
 	    SE_GROUP_HIDDEN, NULL, NULL);
 }
--- gxine-0.5.905.orig/src/open_mrl.c
+++ gxine-0.5.905/src/open_mrl.c
@@ -88,21 +88,21 @@ static void open_mrl_response_cb (GtkDia
   }
 }
 
-static JSBool js_open_show (JSContext *cx, JSObject *obj, uintN argc,
-			    jsval *argv, jsval *rval)
+static JSBool js_open_show (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("open_show");
   file_dialog_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_open_mrl_show (JSContext *cx, JSObject *obj, uintN argc,
-				jsval *argv, jsval *rval)
+static JSBool js_open_mrl_show (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("open_mrl_show");
   open_mrl_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -142,8 +142,8 @@ void open_mrl_init (void)
 
   {
     static const se_f_def_t defs[] = {
-      { "open_show", js_open_show, 0, 0, SE_GROUP_FILE, NULL, NULL },
-      { "open_mrl_show", js_open_mrl_show, 0, 0, SE_GROUP_FILE, NULL, NULL },
+      { "open_show", js_open_show, 0, JSFUN_FAST_NATIVE, SE_GROUP_FILE, NULL, NULL },
+      { "open_mrl_show", js_open_mrl_show, 0, JSFUN_FAST_NATIVE, SE_GROUP_FILE, NULL, NULL },
       { NULL }
     };
     se_defuns (gse, NULL, defs);
--- gxine-0.5.905.orig/src/key_events.c
+++ gxine-0.5.905/src/key_events.c
@@ -1041,10 +1041,13 @@ static JSBool js_xine_event (int type
 #endif
 
 #define JS_XINE_EVENT(L,T) \
-  static JSBool js_##L (JSContext *cx, JSObject *obj, uintN argc, \
-			jsval *argv, jsval *rval) \
+  static JSBool js_##L (JSContext *cx, uintN argc, jsval *vp) \
   { \
-    return js_xine_event (XINE_EVENT_##T, #L); \
+    JSBool ret = js_xine_event (XINE_EVENT_##T, #L); \
+    if (ret) { \
+      JS_SET_RVAL (cx, vp, JSVAL_VOID); \
+    } \
+    return ret; \
   }
 
 JS_XINE_EVENT (input_up, INPUT_UP);
@@ -1091,16 +1094,15 @@ JS_XINE_EVENT (input_menu3, INPUT_MENU3)
 JS_XINE_EVENT (input_previous, INPUT_PREVIOUS);
 JS_XINE_EVENT (input_next, INPUT_NEXT);
 
-static JSBool js_keybindings_show (JSContext *cx, JSObject *obj, uintN argc,
-				   jsval *argv, jsval *rval)
+static JSBool js_keybindings_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("keybindings_show");
   kb_edit_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_keypad_show (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool js_keypad_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("keypad_show");
   if (keypad)
@@ -1110,6 +1112,7 @@ static JSBool js_keypad_show (JSContext
     else
       window_show (keypad, NULL);
   }
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -1247,8 +1250,8 @@ static const kb_xine_event_map_t xine_vd
   }
 };
 
-JSBool js_event_generic (JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
-			 jsval *rval, const char *func, const char *const *prefix,
+JSBool js_event_generic (JSContext *cx, uintN argc, jsval *vp,
+                         const char *func, const char *const *prefix,
 			 ...)
 {
   se_t *se = (se_t *) JS_GetContextPrivate(cx);
@@ -1257,8 +1260,9 @@ JSBool js_event_generic (JSContext *cx,
   char *evstr;
   va_list ap;
   const kb_xine_event_map_t *evlist;
+  jsval *argv = JS_ARGV (cx, vp);
 
-  *rval = JSVAL_TRUE;
+  JS_SET_RVAL (cx, vp, JSVAL_TRUE);
 
   se_log_fncall (func);
   se_argc_check_max (1, func);
@@ -1275,7 +1279,7 @@ JSBool js_event_generic (JSContext *cx,
 
   se_arg_is_string (0, func);
 
-  *rval = JSVAL_FALSE;
+  JS_SET_RVAL (cx, vp, JSVAL_FALSE);
 
   if (prefix)
   {
@@ -1294,7 +1298,7 @@ JSBool js_event_generic (JSContext *cx,
   }
 
   str = JS_ValueToString (cx, argv[0]);
-  evstr = JS_GetStringBytes (str);
+  evstr = SE_JS_ENCODE_STRING (cx, str);
   event.type = 0;
 
   va_start (ap, prefix);
@@ -1306,8 +1310,10 @@ JSBool js_event_generic (JSContext *cx,
     event.type = kb_xine_event_lookup (NULL, evstr);
 
   if (!event.type)
+  {
+    SE_JS_FREE_ENCODED_STRING (cx, evstr);
     return JS_TRUE;
-
+  }
   if (event.type != -1)
   {
     event.data = NULL;
@@ -1316,21 +1322,20 @@ JSBool js_event_generic (JSContext *cx,
     xine_event_send (stream, &event);
   }
 
-  *rval = JSVAL_TRUE;
+  SE_JS_FREE_ENCODED_STRING (cx, evstr);
+  JS_SET_RVAL (cx, vp, JSVAL_TRUE);
   return JS_TRUE;
 }
 
-static JSBool js_event (JSContext *cx, JSObject *obj, uintN argc,
-		      jsval *argv, jsval *rval)
+static JSBool js_event (JSContext *cx, uintN argc, jsval *vp)
 {
-  return js_event_generic (cx, obj, argc, argv, rval, "event", NULL, NULL);
+  return js_event_generic (cx, argc, vp, "event", NULL, NULL);
 }
 
-static JSBool js_vdr (JSContext *cx, JSObject *obj, uintN argc,
-		      jsval *argv, jsval *rval)
+static JSBool js_vdr (JSContext *cx, uintN argc, jsval *vp)
 {
   const char *const prefixes[] = { "vdr:/", "netvdr:/", NULL };
-  return js_event_generic (cx, obj, argc, argv, rval, "vdr", prefixes,
+  return js_event_generic (cx, argc, vp, "vdr", prefixes,
 			   &xine_vdr, NULL);
 }
 
@@ -1528,25 +1533,25 @@ void key_events_init (void)
 
   {
     static const se_f_def_t defs[] = {
-      { "input_up", js_input_up, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_down", js_input_down, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_left", js_input_left, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_right", js_input_right, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_select", js_input_select, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_menu", js_input_menu, 0, 0,
+      { "input_up", js_input_up, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_down", js_input_down, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_left", js_input_left, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_right", js_input_right, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_select", js_input_select, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_menu", js_input_menu, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_INPUT, N_("int"), N_("range is 1 to 7") },
-      { "input_menu1", js_input_menu1, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_menu2", js_input_menu2, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_menu3", js_input_menu3, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_previous", js_input_previous, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "input_next", js_input_next, 0, 0, SE_GROUP_INPUT, NULL, NULL },
-      { "keybindings_show", js_keybindings_show, 0, 0,
+      { "input_menu1", js_input_menu1, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_menu2", js_input_menu2, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_menu3", js_input_menu3, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_previous", js_input_previous, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "input_next", js_input_next, 0, JSFUN_FAST_NATIVE, SE_GROUP_INPUT, NULL, NULL },
+      { "keybindings_show", js_keybindings_show, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_DIALOGUE, NULL, NULL },
-      { "keypad_show", js_keypad_show, 0, 0,
+      { "keypad_show", js_keypad_show, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_DIALOGUE, NULL, NULL },
-      { "event", js_event, 0, 0,
+      { "event", js_event, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_INPUT, N_("string"), N_("event; returns true if sent") },
-      { "vdr", js_vdr, 0, 0,
+      { "vdr", js_vdr, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_EXTERNAL, N_("string"), N_("VDR event; returns true if sent") },
       { NULL }
     };
--- gxine-0.5.905.orig/src/preferences.c
+++ gxine-0.5.905/src/preferences.c
@@ -1106,12 +1106,12 @@ static void response_cb (GtkDialog *dbox
   }
 }
 
-static JSBool js_preferences_show (JSContext *cx, JSObject *obj, uintN argc,
-				   jsval *argv, jsval *rval)
+static JSBool js_preferences_show (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("preferences_show");
   preferences_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -1171,7 +1171,7 @@ void preferences_init (void)
 {
   is_visible = FALSE;
   /* script engine functions */
-  se_defun (gse, NULL, "preferences_show", js_preferences_show, 0, 0,
+  se_defun (gse, NULL, "preferences_show", js_preferences_show, 0, JSFUN_FAST_NATIVE,
 	    SE_GROUP_DIALOGUE, NULL, NULL);
 
   preferences_init_dbox ();
--- gxine-0.5.905.orig/src/lirc.c
+++ gxine-0.5.905/src/lirc.c
@@ -212,8 +212,7 @@ void gxine_lirc_quit (void)
 #endif
 }
 
-static JSBool js_reload_lirc (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool js_reload_lirc (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall ("reload_lirc");
   se_argc_check_max (0, "reload_lirc");
@@ -221,13 +220,13 @@ static JSBool js_reload_lirc (JSContext
   if (gxine_lirc_thread)
     pthread_join (gxine_lirc_thread, NULL);
   gxine_lirc_start ();
-  *rval = gxine_lirc_thread ? JSVAL_TRUE : JSVAL_FALSE;
+  JS_SET_RVAL (cx, vp, gxine_lirc_thread ? JSVAL_TRUE : JSVAL_FALSE);
   return JS_TRUE;
 }
 
 void gxine_lirc_init (void)
 {
-  se_defun (gse, NULL, "reload_lirc", js_reload_lirc, 0, 0,
+  se_defun (gse, NULL, "reload_lirc", js_reload_lirc, 0, JSFUN_FAST_NATIVE,
 	    SE_GROUP_HIDDEN, NULL, NULL);
   gxine_lirc_start ();
 }
--- gxine-0.5.905.orig/src/script_engine.h
+++ gxine-0.5.905/src/script_engine.h
@@ -34,6 +34,97 @@
 #include <jsapi.h>
 #include <pthread.h>
 
+#ifndef JSFUN_FAST_NATIVE
+// All natives are JSFastNative
+#define JSFUN_FAST_NATIVE 0
+#endif
+
+#ifdef HAVE_JS_GET_STRING_BYTES
+# define SE_JS_ENCODE_STRING(cx, str) JS_GetStringBytes(str)
+# define SE_JS_FREE_ENCODED_STRING(cx, str)
+#else
+# define SE_JS_ENCODE_STRING(cx, str) JS_EncodeString(cx, str)
+# define SE_JS_FREE_ENCODED_STRING(cx, str) JS_free(cx, str)
+#endif
+
+#ifdef HAVE_JS_NEW_DOUBLE
+# define SE_JS_NEW_NUMBER_VAL(cx, d, rval) \
+    jsdouble *new_d = JS_NewDouble (cx, d); \
+    rval = DOUBLE_TO_JSVAL (new_d)
+#else
+# define SE_JS_NEW_NUMBER_VAL(cx, d, rval) \
+    JS_NewNumberValue (cx, d, &rval)
+#endif
+
+#ifdef JS_PROPERTY_OP_HAS_ID_AS_JSID
+# define SE_JS_PROPERTY_GETTER_DECLARE(name) \
+    static JSBool \
+    name(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+# define SE_JS_PROPERTY_GETTER_INIT_VARIABLES(idval) \
+    jsval idval; \
+    JS_IdToValue (cx, id, &idval)
+# define SE_JS_CALL_PROPERTY_GETTER_WITH_JSVAL(getter, cx, obj, propval, vp) __extension__ ({ \
+    jsid propid; \
+    JS_ValueToId (cx, propval, &propid); \
+    JSBool ret = getter (cx, obj, propid, vp); \
+    ret; \
+})
+#else
+# define SE_JS_PROPERTY_GETTER_DECLARE(name) \
+    static JSBool \
+    name(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+# define SE_JS_PROPERTY_GETTER_INIT_VARIABLES(idval) \
+    jsval idval = id
+# define SE_JS_CALL_PROPERTY_GETTER_WITH_JSVAL(getter, cx, obj, propval, vp) __extension__ ({ \
+    JSBool ret = getter (cx, obj, propval, vp); \
+    ret; \
+})
+#endif
+
+#ifdef HAVE_JS_STRICT_PROPERTY_OP
+# define SE_JS_PROPERTY_SETTER_DECLARE(name) \
+    static JSBool \
+    name(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
+# define SE_JS_PROPERTY_SETTER_INIT_VARIABLES(idval) \
+    jsval idval; \
+    JS_IdToValue (cx, id, &idval)
+# define SE_JS_CALL_PROPERTY_SETTER_WITH_JSVAL(setter, cx, obj, propval, vp) __extension__ ({ \
+    jsid propid; \
+    JS_ValueToId (cx, propval, &propid); \
+    JSBool ret = setter (cx, obj, propid, JS_FALSE, vp); \
+    ret; \
+})
+#elif JS_PROPERTY_OP_HAS_ID_AS_JSID
+# define SE_JS_PROPERTY_SETTER_DECLARE(name) \
+    static JSBool \
+    name(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+# define SE_JS_PROPERTY_SETTER_INIT_VARIABLES(idval) \
+    jsval idval; \
+    JS_IdToValue (cx, id, &idval)
+# define SE_JS_CALL_PROPERTY_SETTER_WITH_JSVAL(setter, cx, obj, propval, vp) __extension__ ({ \
+    jsid propid; \
+    JS_ValueToId (cx, propval, &propid); \
+    JSBool ret = setter (cx, obj, propid, vp); \
+    ret; \
+})
+#else
+# define SE_JS_PROPERTY_SETTER_DECLARE(name) \
+    static JSBool \
+    name(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+# define SE_JS_PROPERTY_SETTER_INIT_VARIABLES(idval) \
+    jsval idval = id
+# define SE_JS_CALL_PROPERTY_SETTER_WITH_JSVAL(setter, cx, obj, propval, vp) __extension__ ({ \
+    JSBool ret = setter (cx, obj, propval, vp); \
+    ret; \
+})
+#endif
+
+#ifdef JSVAL_TO_DOUBLE_RETURNS_POINTER
+# define SE_JSVAL_TO_DOUBLE(v) *JSVAL_TO_DOUBLE(v)
+#else
+# define SE_JSVAL_TO_DOUBLE(v) JSVAL_TO_DOUBLE(v)
+#endif
+
 typedef int (*se_prop_int_cb_t) (void *user_data, char *property, int *num);
 typedef void (*se_print_cb_t) (void *user_data, const char *str, ...)
   __attribute__ ((format (printf, 2, 3)));
--- gxine-0.5.905.orig/src/systray.c
+++ gxine-0.5.905/src/systray.c
@@ -214,10 +214,10 @@ button_cb (GtkWidget *widget, GdkEventBu
   return TRUE;
 }
 
-static JSBool js_minimise (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool js_minimise (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 tray_state=-1;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_checkinit ("set_minimised");
   se_argc_check_max (1, "set_minimised");
@@ -239,13 +239,14 @@ static JSBool js_minimise (JSContext *cx
       app_show ();
   }
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 void systray_init (void)
 {
   static const se_f_def_t defs[] = {
-    { "set_minimised", js_minimise, 0, 0,
+    { "set_minimised", js_minimise, 0, JSFUN_FAST_NATIVE,
       SE_GROUP_ENGINE, N_("[bool]"),
       N_("true to hide, false to show") },
     { NULL }
--- gxine-0.5.905.orig/src/settings.c
+++ gxine-0.5.905/src/settings.c
@@ -129,10 +129,10 @@ get_sliders (const struct slider_window_
   }
 
 #define JSFUNC(OBJ,FUNC) \
-  static JSBool js_##OBJ##_##FUNC (JSContext *cx, JSObject *obj, uintN argc, \
-				   jsval *argv, jsval *rval) \
+  static JSBool js_##OBJ##_##FUNC (JSContext *cx, uintN argc, jsval *vp) \
   { \
     int page = -1; \
+    jsval *argv = JS_ARGV (cx, vp); \
     se_log_fncall_checkinit (#OBJ"_"#FUNC); \
     se_argc_check_max (1, #OBJ"_"#FUNC); \
     if (argc) \
@@ -141,11 +141,14 @@ get_sliders (const struct slider_window_
       JS_ValueToInt32 (cx, argv[0], &page); \
     } \
     sliders_##FUNC (&OBJ##_window, page, TRUE); \
+    if (vp) { \
+      JS_SET_RVAL (cx, vp, JSVAL_VOID); \
+    } \
     return JS_TRUE; \
   }
 
 #define JSDECL(OBJ,FUNC) \
-  { #OBJ"_"#FUNC, js_##OBJ##_##FUNC, 0, 0,SE_GROUP_DIALOGUE, NULL, NULL }
+  { #OBJ"_"#FUNC, js_##OBJ##_##FUNC, 0, JSFUN_FAST_NATIVE,SE_GROUP_DIALOGUE, NULL, NULL }
 
 static void sliders_show (struct slider_window_s *window, guint page,
 			  gboolean unused)
@@ -331,5 +334,5 @@ void settings_init (void)
 
 void settings_clear (void)
 {
-  js_settings_clear (gse->cx, NULL, 0, NULL, NULL);
+  js_settings_clear (gse->cx, 0, NULL);
 }
--- gxine-0.5.905.orig/src/post.c
+++ gxine-0.5.905/src/post.c
@@ -1079,38 +1079,47 @@ post_config_post_chain_window (gxine_cha
 }
 
 static JSBool
-js_deinterlace_show (JSContext *cx, JSObject *obj, uintN argc,
-		     jsval *argv, jsval *rval)
+js_deinterlace_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("deinterlace_show");
-  return post_config_post_chain_window (&chains[POST_CHAIN_DEINTERLACE]);
+  JSBool ret = post_config_post_chain_window (&chains[POST_CHAIN_DEINTERLACE]);
+  if (ret) {
+    JS_SET_RVAL (cx, vp, JSVAL_VOID);
+  }
+  return ret;
 }
 
 static JSBool
-js_pp_video_show (JSContext *cx, JSObject *obj, uintN argc,
-		  jsval *argv, jsval *rval)
+js_pp_video_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("postproc_video_show");
-  return post_config_post_chain_window (&chains[POST_CHAIN_VIDEO]);
+  JSBool ret = post_config_post_chain_window (&chains[POST_CHAIN_VIDEO]);
+  if (ret) {
+    JS_SET_RVAL (cx, vp, JSVAL_VOID);
+  }
+  return ret;
 }
 
 static JSBool
-js_pp_audio_show (JSContext *cx, JSObject *obj, uintN argc,
-		  jsval *argv, jsval *rval)
+js_pp_audio_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("postproc_audio_show");
-  return post_config_post_chain_window (&chains[POST_CHAIN_AUDIO]);
+  JSBool ret = post_config_post_chain_window (&chains[POST_CHAIN_AUDIO]);
+  if (ret) {
+    JS_SET_RVAL (cx, vp, JSVAL_VOID);
+  }
+  return ret;
 }
 
 void
 post_init (void)
 {
   static const se_f_def_t defs[] = {
-    { "deinterlace_show", js_deinterlace_show, 0, 0,
+    { "deinterlace_show", js_deinterlace_show, 0, JSFUN_FAST_NATIVE,
       SE_GROUP_DIALOGUE, NULL, NULL },
-    { "postproc_video_show", js_pp_video_show, 0, 0,
+    { "postproc_video_show", js_pp_video_show, 0, JSFUN_FAST_NATIVE,
       SE_GROUP_DIALOGUE, NULL, NULL },
-    { "postproc_audio_show", js_pp_audio_show, 0, 0,
+    { "postproc_audio_show", js_pp_audio_show, 0, JSFUN_FAST_NATIVE,
       SE_GROUP_DIALOGUE, NULL, NULL },
     { NULL }
   };
--- gxine-0.5.905.orig/src/playlist.c
+++ gxine-0.5.905/src/playlist.c
@@ -2123,71 +2123,70 @@ static void drop_cb (GtkTreeView	*widget
  * js functions
  */
 
-static JSBool js_playlist_get_item (JSContext *cx, JSObject *obj, uintN argc,
-				    jsval *argv, jsval *rval)
+static JSBool js_playlist_get_item (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall ("playlist_get_item");
-  *rval = INT_TO_JSVAL (playlist_get_list_pos());
+  JS_SET_RVAL (cx, vp, INT_TO_JSVAL (playlist_get_list_pos()));
   return JS_TRUE;
 }
 
-static JSBool js_playlist_clear (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_playlist_clear (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("playlist_clear");
   playlist_clear ();
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_playlist_flush (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_playlist_flush (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("playlist_flush");
   playlist_flush (PLAY_ITEM_NORMAL);
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_playlist_load (JSContext *cx, JSObject *obj, uintN argc,
-				jsval *argv, jsval *rval)
+static JSBool js_playlist_load (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall_checkinit ("playlist_load");
 
   se_argc_check (1, "playlist_load");
   se_arg_is_string_or_null (0, "playlist_load");
 
-  char *mrl = JS_GetStringBytes (JS_ValueToString (cx, argv[0]));
+  char *mrl = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[0]));
 
   logprintf ("playlist_load: file=%s\n", mrl);
   playlist_load_any (mrl);
 
-  *rval = JSVAL_VOID;
+  SE_JS_FREE_ENCODED_STRING (cx, mrl);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_playlist_add (JSContext *cx, JSObject *obj, uintN argc,
-			       jsval *argv, jsval *rval)
+static JSBool js_playlist_add (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_checkinit ("playlist_add");
 
   se_argc_check_range (1, 2, "playlist_add");
   se_arg_is_string (0, "playlist_add");
 
-  char *mrl = JS_GetStringBytes (JS_ValueToString (cx, argv[0]));
+  char *mrl = SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[0]));
   int item;
 
   if (argc > 1)
   {
     se_arg_is_string_or_null (1, "playlist_add");
     char *title = JSVAL_IS_STRING (argv[1])
-		  ? JS_GetStringBytes (JS_ValueToString (cx, argv[1]))
+                  ? SE_JS_ENCODE_STRING (cx, JS_ValueToString (cx, argv[1]))
 		  : NULL;
     logprintf ("playlist_add: MRL=%s title=%s\n", mrl, title);
     play_item_t *play_item = play_item_new (title, mrl, 0, 0);
     item = playlist_add (play_item, -1);
+    SE_JS_FREE_ENCODED_STRING (cx, title);
   }
   else
   {
@@ -2195,14 +2194,15 @@ static JSBool js_playlist_add (JSContext
     item = playlist_add_mrl (mrl, -1);
   }
 
-  *rval = INT_TO_JSVAL (item);
+  SE_JS_FREE_ENCODED_STRING (cx, mrl);
+  JS_SET_RVAL (cx, vp, INT_TO_JSVAL (item));
 
   return JS_TRUE;
 }
 
-static JSBool js_playlist_delete (JSContext *cx, JSObject *obj, uintN argc,
-				  jsval *argv, jsval *rval)
+static JSBool js_playlist_delete (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall_checkinit ("playlist_remove");
 
   se_argc_check_range (1, 2, "playlist_remove");
@@ -2227,14 +2227,14 @@ static JSBool js_playlist_delete (JSCont
     gtk_list_store_remove (pl_store, &iter);
   }
 
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_playlist_play (JSContext *cx, JSObject *obj, uintN argc,
-				jsval *argv, jsval *rval)
+static JSBool js_playlist_play (JSContext *cx, uintN argc, jsval *vp)
 {
   int32 item;
+  jsval *argv = JS_ARGV (cx, vp);
 
   se_log_fncall_checkinit ("playlist_play");
 
@@ -2245,21 +2245,19 @@ static JSBool js_playlist_play (JSContex
 
   playlist_play (item);
 
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_playlist_show (JSContext *cx, JSObject *obj, uintN argc,
-				jsval *argv, jsval *rval)
+static JSBool js_playlist_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall_checkinit ("playlist_show");
   playlist_show ();
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_mrl_browser_refresh (JSContext *cx, JSObject *obj, uintN argc,
-				      jsval *argv, jsval *rval)
+static JSBool js_mrl_browser_refresh (JSContext *cx, uintN argc, jsval *vp)
 {
   GtkTreeIter iter;
   se_log_fncall_checkinit ("mrl_browser_refresh");
@@ -2270,14 +2268,14 @@ static JSBool js_mrl_browser_refresh (JS
       || !item_marked_current (&iter))
   {
     playlist_flush (PLAY_ITEM_BROWSER);
-    *rval = JSVAL_VOID;
+    JS_SET_RVAL (cx, vp, JSVAL_VOID);
     return JS_TRUE;
   }
 
   CUR_ITEM_LOCK ();
   playlist_browse_set (cur_item ? : playlist_get_item (cur_list_pos));
   CUR_ITEM_UNLOCK ();
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -2604,23 +2602,23 @@ void playlist_init (void)
 
   {
     static const se_f_def_t defs[] = {
-      { "playlist_show", js_playlist_show, 0, 0,
+      { "playlist_show", js_playlist_show, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_DIALOGUE, NULL, NULL },
-      { "playlist_clear", js_playlist_clear, 0, 0,
+      { "playlist_clear", js_playlist_clear, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, NULL, NULL },
-      { "playlist_flush", js_playlist_flush, 0, 0,
+      { "playlist_flush", js_playlist_flush, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, NULL, NULL },
-      { "playlist_load", js_playlist_load, 0, 0,
+      { "playlist_load", js_playlist_load, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, N_("file"), NULL },
-      { "playlist_add", js_playlist_add, 0, 0,
+      { "playlist_add", js_playlist_add, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, N_("MRL[, title]"), NULL },
-      { "playlist_delete", js_playlist_delete, 0, 0,
+      { "playlist_delete", js_playlist_delete, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, N_("int"), NULL },
-      { "playlist_play", js_playlist_play, 0, 0,
+      { "playlist_play", js_playlist_play, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, N_("int"), N_("playlist entry number") },
-      { "playlist_get_item", js_playlist_get_item, 0, 0,
+      { "playlist_get_item", js_playlist_get_item, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_PLAYLIST, NULL, NULL },
-      { "mrl_browser_refresh", js_mrl_browser_refresh, 0, 0,
+      { "mrl_browser_refresh", js_mrl_browser_refresh, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_HIDDEN, NULL, NULL },
       { NULL }
     };
--- gxine-0.5.905.orig/src/key_events.h
+++ gxine-0.5.905/src/key_events.h
@@ -52,8 +52,7 @@ void save_key_bindings (void);
 /* returns xine event number (XINE_EVENT_*) or 0 on failure */
 int kb_xine_event_lookup (const kb_xine_event_map_t *, const char *);
 
-JSBool js_event_generic (JSContext *, JSObject *, uintN argc, jsval *argv,
-			 jsval *rval, const char *func,
+JSBool js_event_generic (JSContext *, uintN argc, jsval *vp, const char *func,
 			 const char *const *mrlprefix, ...)
 			 __attribute__ ((sentinel));
 
--- gxine-0.5.905.orig/src/xml_widgets.c
+++ gxine-0.5.905/src/xml_widgets.c
@@ -186,13 +186,13 @@ stock_toggle_cb (GtkToggleButton *button
     ui_set_status (UI_CURRENT_STATE);
 }
 
-#define JS_WIDGET() ((se_o_t *)JS_GetPrivate (cx, obj))->user_data
+#define JS_WIDGET() ((se_o_t *)JS_GetPrivate (cx, JS_THIS_OBJECT (cx, vp)))->user_data
 
 static JSBool
-js_set_show (JSContext *cx, JSObject *obj,
-	     uintN argc, jsval *argv, jsval *rval)
+js_set_show (JSContext *cx, uintN argc, jsval *vp)
 {
   int v, all = 0;
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall ("<widget>.set_show");
   se_argc_check_range (1, 2, "<widget>.set_show");
   se_arg_is_int_or_bool (0, "<widget>.set_show");
@@ -210,28 +210,30 @@ js_set_show (JSContext *cx, JSObject *ob
     gtk_widget_show (JS_WIDGET ());
   else
     gtk_widget_hide (JS_WIDGET ());
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 static JSBool
-js_set_sensitive (JSContext *cx, JSObject *obj,
-		  uintN argc, jsval *argv, jsval *rval)
+js_set_sensitive (JSContext *cx, uintN argc, jsval *vp)
 {
   int v;
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall ("<widget>.set_sensitive");
   se_argc_check (1, "<widget>.set_sensitive");
   se_arg_is_int_or_bool (0, "<widget>.set_sensitive");
   JS_ValueToBoolean (cx, argv[0], &v);
   gtk_widget_set_sensitive (JS_WIDGET (), v);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 static JSBool
-js_activate (JSContext *cx, JSObject *obj,
-	     uintN argc, jsval *argv, jsval *rval)
+js_activate (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall ("<widget>.activate");
   gtk_widget_activate (JS_WIDGET ());
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -1257,9 +1259,9 @@ widget_parse (xml_node_t *node)
       se_o_t *se_widget;
       char *se_name, *se_dot;
       static const se_f_def_t defs[] = {
-	{ "set_show", js_set_show, 0, 0, SE_GROUP_HIDDEN, NULL, NULL },
-	{ "set_sensitive", js_set_sensitive, 0, 0, SE_GROUP_HIDDEN, NULL, NULL },
-	{ "activate", js_activate, 0, 0, SE_GROUP_HIDDEN, NULL, NULL },
+	{ "set_show", js_set_show, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL },
+	{ "set_sensitive", js_set_sensitive, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL },
+	{ "activate", js_activate, 0, JSFUN_FAST_NATIVE, SE_GROUP_HIDDEN, NULL, NULL },
 	{ NULL }
       };
       if (!se_widget_space)
--- gxine-0.5.905.orig/src/mediamarks.c
+++ gxine-0.5.905/src/mediamarks.c
@@ -680,30 +680,30 @@ void mm_save (void)
   g_free(fname);
 }
 
-static JSBool js_mm_add_show (JSContext *cx, JSObject *obj, uintN argc,
-			      jsval *argv, jsval *rval)
+static JSBool js_mm_add_show (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("mm_add_show");
   mm_add_show (NULL);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_mm_manage_show (JSContext *cx, JSObject *obj, uintN argc,
-				 jsval *argv, jsval *rval)
+static JSBool js_mm_manage_show (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("mm_manage_show");
   mm_manage_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
-static JSBool js_import_mediamarks (JSContext *cx, JSObject *obj, uintN argc,
-				    jsval *argv, jsval *rval)
+static JSBool js_import_mediamarks (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("import_mediamarks");
   mm_import ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -950,11 +950,11 @@ void mediamarks_init (void)
 
   {
     static const se_f_def_t defs[] = {
-      { "mm_add_show", js_mm_add_show, 0, 0,
+      { "mm_add_show", js_mm_add_show, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_DIALOGUE, NULL, NULL },
-      { "mm_manage_show", js_mm_manage_show, 0, 0,
+      { "mm_manage_show", js_mm_manage_show, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_DIALOGUE, NULL, NULL },
-      { "import_mediamarks", js_import_mediamarks, 0, 0,
+      { "import_mediamarks", js_import_mediamarks, 0, JSFUN_FAST_NATIVE,
 	SE_GROUP_FILE, NULL, NULL },
       { NULL }
     };
--- gxine-0.5.905.orig/src/engine.c
+++ gxine-0.5.905/src/engine.c
@@ -30,7 +30,7 @@
 #include <errno.h>
 #include <unistd.h>
 
-#include <glib/gthread.h>
+#include <glib.h>
 
 #include "engine.h"
 #include "ui.h"
@@ -56,7 +56,7 @@ GAsyncQueue *js_queue;
 static gboolean queue_available = FALSE;
 
 static JSBool
-show_about (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+show_about (JSContext *cx, uintN argc, jsval *vp)
 {
   static const gchar *const authors[] = {
     "Darren Salt <dsalt@users.sourceforge.net>",
@@ -126,7 +126,7 @@ show_about (JSContext *cx, JSObject *obj
   }
 
   window_show (about, NULL);
-  *rval = JSVAL_VOID;
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -184,8 +184,10 @@ int engine_exec_obj (const char *cmd, se
   if ((str = se_result_str (gse)))
   {
     /* JS output. Could end up in a terminal or the JS console. */
+    char *free_str = str;
     str = g_strdup_printf (_("result: %s"), str);
     cb (cb_data, "%s", str);
+    free (free_str);
     free (str);
   }
   else if (se_result_double (gse, &num.d))
@@ -405,12 +407,12 @@ se_startup_response_cb (GtkWidget *widge
 }
 
 static JSBool
-show_startup (JSContext *cx, JSObject *obj, uintN argc,
-	      jsval *argv, jsval *rval)
+show_startup (JSContext *cx, uintN argc, jsval *vp)
 {
   if (!GTK_WIDGET_VISIBLE (se_startup_window))
     reset_startup_buffer (se_startup_cmds);
   window_show (se_startup_window, NULL);
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -439,8 +441,8 @@ void engine_init (void)
   gse = se_new ();
 
   static const se_f_def_t defs[] = {
-    { "about_show", show_about, 0, 0, SE_GROUP_DIALOGUE, NULL, NULL },
-    { "startup_cmds_show", show_startup, 0, 0, SE_GROUP_DIALOGUE, NULL, NULL },
+    { "about_show", show_about, 0, JSFUN_FAST_NATIVE, SE_GROUP_DIALOGUE, NULL, NULL },
+    { "startup_cmds_show", show_startup, 0, JSFUN_FAST_NATIVE, SE_GROUP_DIALOGUE, NULL, NULL },
     { NULL }
   };
   se_defuns (gse, gse->g, defs);
--- gxine-0.5.905.orig/src/log_window.c
+++ gxine-0.5.905/src/log_window.c
@@ -220,11 +220,11 @@ static void switch_cb (GtkNotebook *note
   gtk_dialog_set_response_sensitive ((GtkDialog *) win, GTK_RESPONSE_YES, !is_cp);
 }
 
-static JSBool js_log_show (JSContext *cx, JSObject *obj, uintN argc,
-			   jsval *argv, jsval *rval)
+static JSBool js_log_show (JSContext *cx, uintN argc, jsval *vp)
 {
   se_log_fncall ("log_show");
   log_window_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -379,7 +379,7 @@ void log_window_init (void)
 
   /* script engine functions */
 
-  se_defun (gse, NULL, "log_show", js_log_show, 0, 0,
+  se_defun (gse, NULL, "log_show", js_log_show, 0, JSFUN_FAST_NATIVE,
 	    SE_GROUP_DIALOGUE, NULL, NULL);
 }
 
--- gxine-0.5.905.orig/src/vis.c
+++ gxine-0.5.905/src/vis.c
@@ -66,23 +66,26 @@ void vis_set (const char *str)
     gtk_action_activate (action->data);
 }
 
-static JSBool js_set_vis (JSContext *cx, JSObject *obj, uintN argc,
-			  jsval *argv, jsval *rval)
+static JSBool js_set_vis (JSContext *cx, uintN argc, jsval *vp)
 {
+  jsval *argv = JS_ARGV (cx, vp);
   se_log_fncall ("js_set_vis");
   se_argc_check (1, "set_vis");
   se_arg_is_string (0, "set_vis");
 
   JSString *str = JS_ValueToString (cx, argv[0]);
-  vis_set (JS_GetStringBytes (str));
+  char *cstr = SE_JS_ENCODE_STRING (cx, str);
+  vis_set (cstr);
+  SE_JS_FREE_ENCODED_STRING (cx, cstr);
 
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
 void vis_init (void)
 {
   xine_cfg_entry_t entry;
-  se_defun (gse, NULL, "set_vis", js_set_vis, 0, 0,
+  se_defun (gse, NULL, "set_vis", js_set_vis, 0, JSFUN_FAST_NATIVE,
 	    SE_GROUP_ENGINE, N_("string"), N_("visualisation name"));
   if (xine_config_lookup_entry (xine, "post_audio_plugin", &entry))
     gtk_video_select_vis ((GtkVideo *)gtv, entry.str_value, &audio_port);
--- gxine-0.5.905.orig/src/stream_info.c
+++ gxine-0.5.905/src/stream_info.c
@@ -180,12 +180,12 @@ static void response_cb (GtkDialog *dbox
   }
 }
 
-static JSBool js_stream_info_show (JSContext *cx, JSObject *obj, uintN argc,
-				   jsval *argv, jsval *rval)
+static JSBool js_stream_info_show (JSContext *cx, uintN argc, jsval *vp)
 {
   /* se_t *se = (se_t *) JS_GetContextPrivate(cx); */
   se_log_fncall_checkinit ("stream_info_show");
   stream_info_show ();
+  JS_SET_RVAL (cx, vp, JSVAL_VOID);
   return JS_TRUE;
 }
 
@@ -235,6 +235,6 @@ void stream_info_init (void)
 
   is_visible = FALSE;
 
-  se_defun (gse, NULL, "stream_info_show", js_stream_info_show, 0, 0,
+  se_defun (gse, NULL, "stream_info_show", js_stream_info_show, 0, JSFUN_FAST_NATIVE,
 	    SE_GROUP_DIALOGUE, N_("[bool]"), NULL);
 }
--- gxine-0.5.905.orig/src/console_output.h
+++ gxine-0.5.905/src/console_output.h
@@ -21,7 +21,7 @@
 #ifndef GXINE_CONSOLE_OUTPUT_H
 #define GXINE_CONSOLE_OUTPUT_H
 
-#include <glib/gmessages.h>
+#include <glib.h>
 
 void console_output_init (void);
 
--- gxine-0.5.905.orig/src/main.c
+++ gxine-0.5.905/src/main.c
@@ -45,7 +45,6 @@
 #include <gdk/gdkx.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib.h>
-#include <glib/gmessages.h>
 
 #include "desktop_integration.h"
 #include "engine.h"
