[gjs] GI: handle G_SIGNAL_TYPE_STATIC_SCOPE in JS signal handlers
- From: Johan Bilien <jobi src gnome org>
- To: svn-commits-list gnome org
- Subject: [gjs] GI: handle G_SIGNAL_TYPE_STATIC_SCOPE in JS signal handlers
- Date: Tue, 24 Mar 2009 13:01:15 -0400 (EDT)
commit 9eabf87ff79a25f0b6c2aabe79ca5f8c43b078c9
Author: Johan Bilien <jobi litl com>
Date: Tue Mar 24 15:20:56 2009 +0000
GI: handle G_SIGNAL_TYPE_STATIC_SCOPE in JS signal handlers
gi/value.[ch]:
. allow converting C -> JS boxed without copy
. add a gjs_closure_new_for_signal for signal closures,
which will not copy when G_SIGNAL_TYPE_STATIC_SCOPE is set
gi/object.c:
. use the new gjs_closure_new_for_signal
---
gi/object.c | 10 +++-----
gi/value.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
gi/value.h | 4 +++
3 files changed, 73 insertions(+), 12 deletions(-)
diff --git a/gi/object.c b/gi/object.c
index 07bfca3..b4ee367 100644
--- a/gi/object.c
+++ b/gi/object.c
@@ -917,13 +917,8 @@ real_connect_func(JSContext *context,
return JS_FALSE;
}
- closure = gjs_closure_new_marshaled(context, JSVAL_TO_OBJECT(argv[1]), "signal callback");
- if (closure == NULL)
- return JS_FALSE;
-
signal_name = gjs_string_get_ascii_checked(context, argv[0]);
if (signal_name == NULL) {
- g_closure_sink(closure);
return JS_FALSE;
}
@@ -932,10 +927,13 @@ real_connect_func(JSContext *context,
gjs_throw(context, "No signal %s on object of type %s",
signal_name,
g_base_info_get_name((GIBaseInfo*) priv->info));
- g_closure_sink(closure);
return JS_FALSE;
}
+ closure = gjs_closure_new_for_signal(context, JSVAL_TO_OBJECT(argv[1]), "signal callback", signal_id);
+ if (closure == NULL)
+ return JS_FALSE;
+
id = g_signal_connect_closure(priv->gobj,
signal_name,
closure,
diff --git a/gi/value.c b/gi/value.c
index d7f6499..590da8a 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -36,6 +36,11 @@
#include <girepository.h>
+static JSBool gjs_value_from_g_value_internal(JSContext *context,
+ jsval *value_p,
+ const GValue *gvalue,
+ gboolean no_copy);
+
static void
closure_marshal(GClosure *closure,
GValue *return_value,
@@ -49,6 +54,7 @@ closure_marshal(GClosure *closure,
jsval *argv;
jsval rval;
int i;
+ GSignalQuery signal_query = { 0, };
gjs_debug_marshal(GJS_DEBUG_GCLOSURE,
"Marshal closure %p",
@@ -68,9 +74,38 @@ closure_marshal(GClosure *closure,
gjs_root_value_locations(context, argv, argc);
JS_AddRoot(context, &rval);
+ if (marshal_data) {
+ /* we are used for a signal handler */
+ guint signal_id;
+
+ signal_id = GPOINTER_TO_UINT(marshal_data);
+
+ g_signal_query(signal_id, &signal_query);
+
+ if (!signal_query.signal_id) {
+ gjs_debug(GJS_DEBUG_GCLOSURE,
+ "Signal handler being called on invalid signal");
+ goto cleanup;
+ }
+
+ if (signal_query.n_params + 1 != n_param_values) {
+ gjs_debug(GJS_DEBUG_GCLOSURE,
+ "Signal handler being called with wrong number of parameters");
+ goto cleanup;
+ }
+ }
+
for (i = 0; i < argc; ++i) {
const GValue *gval = ¶m_values[i];
- if (!gjs_value_from_g_value(context, &argv[i], gval)) {
+ gboolean no_copy;
+
+ no_copy = FALSE;
+
+ if (i >= 1 && signal_query.signal_id) {
+ no_copy = signal_query.param_types[i - 1] & G_SIGNAL_TYPE_STATIC_SCOPE;
+ }
+
+ if (!gjs_value_from_g_value_internal(context, &argv[i], gval, no_copy)) {
gjs_debug(GJS_DEBUG_GCLOSURE,
"Unable to convert arg %d in order to invoke closure",
i);
@@ -101,6 +136,21 @@ closure_marshal(GClosure *closure,
}
GClosure*
+gjs_closure_new_for_signal(JSContext *context,
+ JSObject *callable,
+ const char *description,
+ guint signal_id)
+{
+ GClosure *closure;
+
+ closure = gjs_closure_new(context, callable, description);
+
+ g_closure_set_meta_marshal(closure, GUINT_TO_POINTER(signal_id), closure_marshal);
+
+ return closure;
+}
+
+GClosure*
gjs_closure_new_marshaled (JSContext *context,
JSObject *callable,
const char *description)
@@ -429,10 +479,11 @@ gjs_value_to_g_value(JSContext *context,
return JS_TRUE;
}
-JSBool
-gjs_value_from_g_value(JSContext *context,
- jsval *value_p,
- const GValue *gvalue)
+static JSBool
+gjs_value_from_g_value_internal(JSContext *context,
+ jsval *value_p,
+ const GValue *gvalue,
+ gboolean no_copy)
{
GType gtype;
@@ -510,7 +561,7 @@ gjs_value_from_g_value(JSContext *context,
switch (g_base_info_get_type(info)) {
case GI_INFO_TYPE_BOXED:
case GI_INFO_TYPE_STRUCT:
- obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)info, gboxed, FALSE);
+ obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)info, gboxed, no_copy);
break;
case GI_INFO_TYPE_UNION:
obj = gjs_union_from_c_union(context, (GIUnionInfo *)info, gboxed);
@@ -570,3 +621,11 @@ gjs_value_from_g_value(JSContext *context,
return JS_TRUE;
}
+
+JSBool
+gjs_value_from_g_value(JSContext *context,
+ jsval *value_p,
+ const GValue *gvalue)
+{
+ return gjs_value_from_g_value_internal(context, value_p, gvalue, FALSE);
+}
diff --git a/gi/value.h b/gi/value.h
index da76b6b..460c5ed 100644
--- a/gi/value.h
+++ b/gi/value.h
@@ -39,6 +39,10 @@ JSBool gjs_value_from_g_value (JSContext *context,
GClosure* gjs_closure_new_marshaled (JSContext *context,
JSObject *callable,
const char *description);
+GClosure* gjs_closure_new_for_signal(JSContext *context,
+ JSObject *callable,
+ const char *description,
+ guint signal_id);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]