/* Creates marshaller closure for specified fundamental object type. If specified object does not have custom setvalue/getvalue functions registered, returns nil. Signature is: marshaller = marshal.fundamental(gtype) */ static int marshal_fundamental (lua_State *L) { /* Find associated baseinfo. */ GIBaseInfo *info = g_irepository_find_by_gtype (NULL, lgi_type_get_gtype (L, 1)); if (info) { lgi_gi_info_new (L, info); if (GI_IS_OBJECT_INFO (info) && g_object_info_get_fundamental (info)) { GIObjectInfoGetValueFunction get_value = lgi_object_get_function_ptr (info, g_object_info_get_get_value_function); GIObjectInfoSetValueFunction set_value = lgi_object_get_function_ptr (info, g_object_info_get_set_value_function); if (get_value && set_value) { lua_pushlightuserdata (L, get_value); lua_pushlightuserdata (L, set_value); lua_pushcclosure (L, marshal_fundamental_marshaller, 2); return 1; } } } lua_pushnil (L); return 1; }
static JSBool convert_int_to_enum (JSContext *context, jsval *value_p, GType gtype, int v) { double v_double; if (v > 0 && v < G_MAXINT) { /* Optimize the unambiguous case */ v_double = v; } else { GIBaseInfo *info; /* Need to distinguish between negative integers and unsigned integers */ info = g_irepository_find_by_gtype(g_irepository_get_default(), gtype); if (info == NULL) /* hope for the best */ v_double = v; else v_double = _gjs_enum_from_int ((GIEnumInfo *)info, v); g_base_info_unref(info); } return JS_NewNumberValue(context, v_double, value_p); }
bool gjs_lookup_interface_constructor(JSContext *context, GType gtype, JS::MutableHandleValue value_p) { JSObject *constructor; GIBaseInfo *interface_info; interface_info = g_irepository_find_by_gtype(NULL, gtype); if (interface_info == NULL) { gjs_throw(context, "Cannot expose non introspectable interface %s", g_type_name(gtype)); return false; } g_assert(g_base_info_get_type(interface_info) == GI_INFO_TYPE_INTERFACE); constructor = gjs_lookup_generic_constructor(context, interface_info); if (G_UNLIKELY (constructor == NULL)) return false; g_base_info_unref(interface_info); value_p.setObject(*constructor); return true; }
GICallableInfo * peas_gi_get_method_info (GType iface_type, const gchar *method_name) { GIRepository *repo; GIBaseInfo *iface_info; GIFunctionInfo *func_info; repo = g_irepository_get_default (); iface_info = g_irepository_find_by_gtype (repo, iface_type); if (iface_info == NULL) { g_warning ("Type not found in introspection: '%s'", g_type_name (iface_type)); return NULL; } switch (g_base_info_get_type (iface_info)) { case GI_INFO_TYPE_OBJECT: func_info = g_object_info_find_method ((GIObjectInfo *) iface_info, method_name); break; case GI_INFO_TYPE_INTERFACE: func_info = g_interface_info_find_method ((GIInterfaceInfo *) iface_info, method_name); break; default: func_info = NULL; } g_base_info_unref (iface_info); return (GICallableInfo *) func_info; }
/* * The *resolved out parameter, on success, should be false to indicate that id * was not resolved; and true if id was resolved. */ static bool param_resolve(JSContext *context, JS::HandleObject obj, JS::HandleId id, bool *resolved) { GIObjectInfo *info = NULL; GIFunctionInfo *method_info; Param *priv; bool ret = false; priv = priv_from_js(context, obj); if (priv != NULL) { /* instance, not prototype */ *resolved = false; return true; } GjsAutoJSChar name; if (!gjs_get_string_id(context, id, &name)) { *resolved = false; return true; /* not resolved, but no error */ } info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM); method_info = g_object_info_find_method(info, name); if (method_info == NULL) { *resolved = false; ret = true; goto out; } #if GJS_VERBOSE_ENABLE_GI_USAGE _gjs_log_info_usage((GIBaseInfo*) method_info); #endif if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { gjs_debug(GJS_DEBUG_GOBJECT, "Defining method %s in prototype for GObject.ParamSpec", g_base_info_get_name( (GIBaseInfo*) method_info)); if (gjs_define_function(context, obj, G_TYPE_PARAM, method_info) == NULL) { g_base_info_unref( (GIBaseInfo*) method_info); goto out; } *resolved = true; /* we defined the prop in obj */ } g_base_info_unref( (GIBaseInfo*) method_info); ret = true; out: if (info != NULL) g_base_info_unref( (GIBaseInfo*)info); return ret; }
void lgi_type_get_repotype (lua_State *L, GType gtype, GIBaseInfo *info) { luaL_checkstack (L, 4, ""); /* Get repo-index table. */ lua_pushlightuserdata (L, &repo_index); lua_rawget (L, LUA_REGISTRYINDEX); /* Prepare gtype, if not given directly. */ if (gtype == G_TYPE_INVALID && info && GI_IS_REGISTERED_TYPE_INFO (info)) { gtype = g_registered_type_info_get_g_type (info); if (gtype == G_TYPE_NONE) gtype = G_TYPE_INVALID; } /* First of all, check direct indexing of repo-index by gtype, should be fastest. */ if (gtype != G_TYPE_INVALID) { lua_pushlightuserdata (L, (gpointer) gtype); lua_rawget (L, -2); } else lua_pushnil (L); if (lua_isnil (L, -1)) { /* Not indexed yet. Try to lookup by name - this works when lazy-loaded repo tables are not loaded yet. */ if (!info && gtype != G_TYPE_INVALID) { info = g_irepository_find_by_gtype (NULL, gtype); lgi_gi_info_new (L, info); } else /* Keep stack balanced as in the previous 'if' branch. */ lua_pushnil (L); if (info) { lua_pushlightuserdata (L, &repo); lua_rawget (L, LUA_REGISTRYINDEX); lua_getfield (L, -1, g_base_info_get_namespace (info)); lua_getfield (L, -1, g_base_info_get_name (info)); lua_replace (L, -5); lua_pop (L, 3); } else lua_pop (L, 1); } lua_replace (L, -2); }
static JSBool fundamental_instance_new_resolve_interface(JSContext *context, JS::HandleObject obj, JS::MutableHandleObject objp, Fundamental *proto_priv, char *name) { GIFunctionInfo *method_info; JSBool ret; GType *interfaces; guint n_interfaces; guint i; ret = JS_TRUE; interfaces = g_type_interfaces(proto_priv->gtype, &n_interfaces); for (i = 0; i < n_interfaces; i++) { GIBaseInfo *base_info; GIInterfaceInfo *iface_info; base_info = g_irepository_find_by_gtype(g_irepository_get_default(), interfaces[i]); if (base_info == NULL) continue; /* An interface GType ought to have interface introspection info */ g_assert(g_base_info_get_type(base_info) == GI_INFO_TYPE_INTERFACE); iface_info = (GIInterfaceInfo *) base_info; method_info = g_interface_info_find_method(iface_info, name); g_base_info_unref(base_info); if (method_info != NULL) { if (g_function_info_get_flags (method_info) & GI_FUNCTION_IS_METHOD) { if (gjs_define_function(context, obj, proto_priv->gtype, (GICallableInfo *) method_info)) { objp.set(obj); } else { ret = JS_FALSE; } } g_base_info_unref((GIBaseInfo *) method_info); } } g_free(interfaces); return ret; }
static JSObject* gjs_lookup_fundamental_prototype_from_gtype(JSContext *context, GType gtype) { GIObjectInfo *info; JSObject *proto; info = (GIObjectInfo *) g_irepository_find_by_gtype(g_irepository_get_default(), gtype); proto = gjs_lookup_fundamental_prototype(context, info, gtype); if (info) g_base_info_unref((GIBaseInfo*)info); return proto; }
void gjs_define_param_class(JSContext *context, JS::HandleObject in_object) { const char *constructor_name; JS::RootedObject prototype(context), constructor(context); GIObjectInfo *info; constructor_name = "ParamSpec"; if (!gjs_init_class_dynamic(context, in_object, nullptr, "GObject", constructor_name, &gjs_param_class, gjs_param_constructor, 0, /* props of prototype */ &gjs_param_proto_props[0], /* funcs of prototype */ &gjs_param_proto_funcs[0], /* props of constructor, MyConstructor.myprop */ NULL, /* funcs of constructor, MyConstructor.myfunc() */ gjs_param_constructor_funcs, &prototype, &constructor)) { g_error("Can't init class %s", constructor_name); } JS::RootedObject gtype_obj(context, gjs_gtype_create_gtype_wrapper(context, G_TYPE_PARAM)); JS_DefineProperty(context, constructor, "$gtype", gtype_obj, JSPROP_PERMANENT); info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), G_TYPE_PARAM); gjs_object_define_static_methods(context, constructor, G_TYPE_PARAM, info); g_base_info_unref( (GIBaseInfo*) info); gjs_debug(GJS_DEBUG_GPARAM, "Defined class %s prototype is %p class %p in object %p", constructor_name, prototype.get(), JS_GetClass(prototype), in_object.get()); }
static GIPropertyInfo * _pygi_lookup_property_from_g_type (GType g_type, const gchar *attr_name) { GIRepository *repository; GIBaseInfo *info; gssize n_infos; gssize i; GType parent; repository = g_irepository_get_default(); info = g_irepository_find_by_gtype (repository, g_type); if (info == NULL) { return NULL; } n_infos = g_object_info_get_n_properties ( (GIObjectInfo *) info); for (i = 0; i < n_infos; i++) { GIPropertyInfo *property_info; property_info = g_object_info_get_property ( (GIObjectInfo *) info, i); g_assert (info != NULL); if (strcmp (attr_name, g_base_info_get_name (property_info)) == 0) { g_base_info_unref (info); return property_info; } g_base_info_unref (property_info); } g_base_info_unref (info); parent = g_type_parent (g_type); if (parent > 0) return _pygi_lookup_property_from_g_type (parent, attr_name); return NULL; }
static VALUE rg_find(int argc, VALUE *argv, VALUE self) { GIBaseInfo *info; if (argc == 1) { VALUE rb_gtype; GType gtype; rb_gtype = argv[0]; gtype = NUM2UINT(rb_gtype); info = g_irepository_find_by_gtype(SELF(self), gtype); } else { VALUE rb_namespace, rb_name; const gchar *namespace_, *name; rb_scan_args(argc, argv, "2", &rb_namespace, &rb_name); namespace_ = RVAL2CSTR(rb_namespace); name = RVAL2CSTR(rb_name); info = g_irepository_find_by_name(SELF(self), namespace_, name); } return GI_BASE_INFO2RVAL(info); }
static GISignalInfo * _pygi_lookup_signal_from_g_type (GType g_type, const gchar *signal_name) { GIRepository *repository; GIBaseInfo *info; GISignalInfo *signal_info = NULL; repository = g_irepository_get_default(); info = g_irepository_find_by_gtype (repository, g_type); if (info == NULL) return NULL; if (GI_IS_OBJECT_INFO (info)) signal_info = g_object_info_find_signal ((GIObjectInfo *) info, signal_name); else if (GI_IS_INTERFACE_INFO (info)) signal_info = g_interface_info_find_signal ((GIInterfaceInfo *) info, signal_name); g_base_info_unref (info); return signal_info; }
static JSBool to_gbytes_func(JSContext *context, unsigned argc, jsval *vp) { JS::CallReceiver rec = JS::CallReceiverFromVp(vp); JSObject *object = JSVAL_TO_OBJECT(rec.thisv()); ByteArrayInstance *priv; JSObject *ret_bytes_obj; GIBaseInfo *gbytes_info; priv = priv_from_js(context, object); if (priv == NULL) return JS_TRUE; /* prototype, not instance */ byte_array_ensure_gbytes(priv); gbytes_info = g_irepository_find_by_gtype(NULL, G_TYPE_BYTES); ret_bytes_obj = gjs_boxed_from_c_struct(context, (GIStructInfo*)gbytes_info, priv->bytes, GJS_BOXED_CREATION_NONE); rec.rval().set(OBJECT_TO_JSVAL(ret_bytes_obj)); return JS_TRUE; }
static void implement_interface_methods (gpointer iface, GType proxy_type) { GType exten_type = G_TYPE_FROM_INTERFACE (iface); guint i; GArray *impls; g_debug ("Implementing interface '%s' for proxy type '%s'", g_type_name (exten_type), g_type_name (proxy_type)); impls = g_type_get_qdata (exten_type, method_impl_quark ()); if (impls == NULL) { GIInterfaceInfo *iface_info; guint n_vfuncs; iface_info = g_irepository_find_by_gtype (NULL, exten_type); g_return_if_fail (iface_info != NULL); g_return_if_fail (g_base_info_get_type (iface_info) == GI_INFO_TYPE_INTERFACE); n_vfuncs = g_interface_info_get_n_vfuncs (iface_info); impls = g_array_new (FALSE, TRUE, sizeof (MethodImpl)); g_array_set_size (impls, n_vfuncs); for (i = 0; i < n_vfuncs; i++) { GIVFuncInfo *vfunc_info; vfunc_info = g_interface_info_get_vfunc (iface_info, i); create_native_closure (exten_type, iface_info, vfunc_info, &g_array_index (impls, MethodImpl, i)); g_base_info_unref (vfunc_info); } g_type_set_qdata (exten_type, method_impl_quark (), impls); g_base_info_unref (iface_info); } for (i = 0; i < impls->len; i++) { MethodImpl *impl = &g_array_index (impls, MethodImpl, i); gpointer *method_ptr; if (impl->closure == NULL) continue; method_ptr = G_STRUCT_MEMBER_P (iface, impl->struct_offset); *method_ptr = impl->closure; g_debug ("Implemented '%s.%s' at %d (%p) with %p", g_type_name (exten_type), impl->method_name, impl->struct_offset, method_ptr, impl->closure); } g_debug ("Implemented interface '%s' for '%s' proxy", g_type_name (exten_type), g_type_name (proxy_type)); }
static JSBool gjs_value_from_g_value_internal(JSContext *context, jsval *value_p, const GValue *gvalue, gboolean no_copy, GSignalQuery *signal_query, gint arg_n) { GType gtype; gtype = G_VALUE_TYPE(gvalue); gjs_debug_marshal(GJS_DEBUG_GCLOSURE, "Converting gtype %s to jsval", g_type_name(gtype)); if (gtype == G_TYPE_STRING) { const char *v; v = g_value_get_string(gvalue); if (v == NULL) { gjs_debug_marshal(GJS_DEBUG_GCLOSURE, "Converting NULL string to JSVAL_NULL"); *value_p = JSVAL_NULL; } else { if (!gjs_string_from_utf8(context, v, -1, value_p)) return JS_FALSE; } } else if (gtype == G_TYPE_CHAR) { char v; v = g_value_get_schar(gvalue); *value_p = INT_TO_JSVAL(v); } else if (gtype == G_TYPE_UCHAR) { unsigned char v; v = g_value_get_uchar(gvalue); *value_p = INT_TO_JSVAL(v); } else if (gtype == G_TYPE_INT) { int v; v = g_value_get_int(gvalue); return JS_NewNumberValue(context, v, value_p); } else if (gtype == G_TYPE_UINT) { uint v; v = g_value_get_uint(gvalue); return JS_NewNumberValue(context, v, value_p); } else if (gtype == G_TYPE_DOUBLE) { double d; d = g_value_get_double(gvalue); return JS_NewNumberValue(context, d, value_p); } else if (gtype == G_TYPE_FLOAT) { double d; d = g_value_get_float(gvalue); return JS_NewNumberValue(context, d, value_p); } else if (gtype == G_TYPE_BOOLEAN) { gboolean v; v = g_value_get_boolean(gvalue); *value_p = BOOLEAN_TO_JSVAL(v); } else if (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_INTERFACE)) { GObject *gobj; JSObject *obj; gobj = g_value_get_object(gvalue); obj = gjs_object_from_g_object(context, gobj); *value_p = OBJECT_TO_JSVAL(obj); } else if (gtype == G_TYPE_STRV) { if (!gjs_array_from_strv (context, value_p, g_value_get_boxed (gvalue))) { gjs_throw(context, "Failed to convert strv to array"); return JS_FALSE; } } else if (g_type_is_a(gtype, G_TYPE_HASH_TABLE) || g_type_is_a(gtype, G_TYPE_ARRAY) || g_type_is_a(gtype, G_TYPE_BYTE_ARRAY) || g_type_is_a(gtype, G_TYPE_PTR_ARRAY)) { gjs_throw(context, "Unable to introspect element-type of container in GValue"); return JS_FALSE; } else if (g_type_is_a(gtype, G_TYPE_BOXED) || g_type_is_a(gtype, G_TYPE_VARIANT)) { GjsBoxedCreationFlags boxed_flags; GIBaseInfo *info; void *gboxed; JSObject *obj; if (g_type_is_a(gtype, G_TYPE_BOXED)) gboxed = g_value_get_boxed(gvalue); else gboxed = g_value_get_variant(gvalue); boxed_flags = GJS_BOXED_CREATION_NONE; /* special case GError */ if (g_type_is_a(gtype, G_TYPE_ERROR)) { obj = gjs_error_from_gerror(context, gboxed, FALSE); *value_p = OBJECT_TO_JSVAL(obj); return TRUE; } /* The only way to differentiate unions and structs is from * their g-i info as both GBoxed */ info = g_irepository_find_by_gtype(g_irepository_get_default(), gtype); if (info == NULL) { gjs_throw(context, "No introspection information found for %s", g_type_name(gtype)); return JS_FALSE; } if (g_base_info_get_type(info) == GI_INFO_TYPE_STRUCT && g_struct_info_is_foreign((GIStructInfo*)info)) { JSBool ret; GIArgument arg; arg.v_pointer = gboxed; ret = gjs_struct_foreign_convert_from_g_argument(context, value_p, info, &arg); g_base_info_unref(info); return ret; } switch (g_base_info_get_type(info)) { case GI_INFO_TYPE_BOXED: case GI_INFO_TYPE_STRUCT: if (no_copy) boxed_flags |= GJS_BOXED_CREATION_NO_COPY; obj = gjs_boxed_from_c_struct(context, (GIStructInfo *)info, gboxed, boxed_flags); break; case GI_INFO_TYPE_UNION: obj = gjs_union_from_c_union(context, (GIUnionInfo *)info, gboxed); break; default: gjs_throw(context, "Unexpected introspection type %d for %s", g_base_info_get_type(info), g_type_name(gtype)); g_base_info_unref(info); return JS_FALSE; } *value_p = OBJECT_TO_JSVAL(obj); g_base_info_unref(info); } else if (g_type_is_a(gtype, G_TYPE_ENUM)) { return convert_int_to_enum(context, value_p, gtype, g_value_get_enum(gvalue)); } else if (g_type_is_a(gtype, G_TYPE_PARAM)) { GParamSpec *gparam; JSObject *obj; gparam = g_value_get_param(gvalue); obj = gjs_param_from_g_param(context, gparam); *value_p = OBJECT_TO_JSVAL(obj); } else if (signal_query && g_type_is_a(gtype, G_TYPE_POINTER)) { JSBool res; GArgument arg; GIArgInfo *arg_info; GIBaseInfo *obj; GISignalInfo *signal_info; GITypeInfo type_info; obj = g_irepository_find_by_gtype(NULL, signal_query->itype); if (!obj) { gjs_throw(context, "Signal argument with GType %s isn't introspectable", g_type_name(signal_query->itype)); return JS_FALSE; } signal_info = g_object_info_find_signal((GIObjectInfo*)obj, signal_query->signal_name); if (!signal_info) { gjs_throw(context, "Unknown signal."); g_base_info_unref((GIBaseInfo*)obj); return JS_FALSE; } arg_info = g_callable_info_get_arg(signal_info, arg_n - 1); g_arg_info_load_type(arg_info, &type_info); arg.v_pointer = g_value_get_pointer(gvalue); res = gjs_value_from_g_argument(context, value_p, &type_info, &arg, TRUE); g_base_info_unref((GIBaseInfo*)arg_info); g_base_info_unref((GIBaseInfo*)signal_info); g_base_info_unref((GIBaseInfo*)obj); return res; } else if (g_type_is_a(gtype, G_TYPE_POINTER)) { gpointer pointer; pointer = g_value_get_pointer(gvalue); if (pointer == NULL) { *value_p = JSVAL_NULL; } else { gjs_throw(context, "Can't convert non-null pointer to JS value"); return JS_FALSE; } } else if (g_value_type_transformable(gtype, G_TYPE_DOUBLE)) { GValue double_value = { 0, }; double v; g_value_init(&double_value, G_TYPE_DOUBLE); g_value_transform(gvalue, &double_value); v = g_value_get_double(&double_value); return JS_NewNumberValue(context, v, value_p); } else if (g_value_type_transformable(gtype, G_TYPE_INT)) { GValue int_value = { 0, }; int v; g_value_init(&int_value, G_TYPE_INT); g_value_transform(gvalue, &int_value); v = g_value_get_int(&int_value); return JS_NewNumberValue(context, v, value_p); } else { gjs_throw(context, "Don't know how to convert GType %s to JavaScript object", g_type_name(gtype)); return JS_FALSE; } return JS_TRUE; }
static JSBool param_new_internal(JSContext *cx, uintN argc, jsval *vp) { jsval *argv = JS_ARGV(cx, vp); GParamSpec *pspec = NULL; JSBool ret = JS_FALSE; gchar *method_name; gchar *prop_name; JSObject *prop_gtype_jsobj; GType prop_gtype; GType prop_type; gchar *nick; gchar *blurb; GParamFlags flags; if (!gjs_parse_args(cx, "GObject.ParamSpec._new_internal", "!sossi", argc, argv, "prop_name", &prop_name, "prop_gtype", &prop_gtype_jsobj, "nick", &nick, "blurb", &blurb, "flags", &flags)) return JS_FALSE; prop_gtype = gjs_gtype_get_actual_gtype(cx, prop_gtype_jsobj); prop_type = G_TYPE_FUNDAMENTAL(prop_gtype); method_name = g_strdup_printf("GObject.ParamSpec.%s", g_type_name(prop_type)); argv += 5; argc -= 5; switch (prop_type) { case G_TYPE_UCHAR: case G_TYPE_CHAR: { gchar *minimum, *maximum, *default_value; if (!gjs_parse_args(cx, method_name, "sss", argc, argv, "minimum", &minimum, "maximum", &maximum, "default_value", &default_value)) goto out; if (prop_type == G_TYPE_CHAR) pspec = g_param_spec_char(prop_name, nick, blurb, minimum[0], maximum[0], default_value[0], flags); else pspec = g_param_spec_uchar(prop_name, nick, blurb, minimum[0], maximum[0], default_value[0], flags); g_free(minimum); g_free(maximum); g_free(default_value); } break; case G_TYPE_INT: case G_TYPE_UINT: case G_TYPE_LONG: case G_TYPE_ULONG: case G_TYPE_INT64: case G_TYPE_UINT64: { gint64 minimum, maximum, default_value; if (!gjs_parse_args(cx, method_name, "ttt", argc, argv, "minimum", &minimum, "maximum", &maximum, "default_value", &default_value)) goto out; switch (prop_type) { case G_TYPE_INT: pspec = g_param_spec_int(prop_name, nick, blurb, minimum, maximum, default_value, flags); break; case G_TYPE_UINT: pspec = g_param_spec_uint(prop_name, nick, blurb, minimum, maximum, default_value, flags); break; case G_TYPE_LONG: pspec = g_param_spec_long(prop_name, nick, blurb, minimum, maximum, default_value, flags); break; case G_TYPE_ULONG: pspec = g_param_spec_ulong(prop_name, nick, blurb, minimum, maximum, default_value, flags); break; case G_TYPE_INT64: pspec = g_param_spec_int64(prop_name, nick, blurb, minimum, maximum, default_value, flags); break; case G_TYPE_UINT64: pspec = g_param_spec_uint64(prop_name, nick, blurb, minimum, maximum, default_value, flags); break; } } break; case G_TYPE_BOOLEAN: { gboolean default_value; if (!gjs_parse_args(cx, method_name, "b", argc, argv, "default_value", &default_value)) goto out; default_value = JSVAL_TO_BOOLEAN(argv[0]); pspec = g_param_spec_boolean(prop_name, nick, blurb, default_value, flags); } break; case G_TYPE_ENUM: { JSObject *gtype_jsobj; GType gtype; GIEnumInfo *info; gint64 default_value; if (!gjs_parse_args(cx, method_name, "ot", argc, argv, "gtype", >ype_jsobj, "default_value", &default_value)) goto out; gtype = gjs_gtype_get_actual_gtype(cx, gtype_jsobj); if (gtype == G_TYPE_NONE) { gjs_throw(cx, "Passed invalid GType to GParamSpecEnum constructor"); goto out; } info = g_irepository_find_by_gtype(g_irepository_get_default(), gtype); if (!_gjs_enum_value_is_valid(cx, info, default_value)) goto out; pspec = g_param_spec_enum(prop_name, nick, blurb, gtype, default_value, flags); } break; case G_TYPE_FLAGS: { JSObject *gtype_jsobj; GType gtype; gint64 default_value; if (!gjs_parse_args(cx, method_name, "ot", argc, argv, "gtype", >ype_jsobj, "default_value", &default_value)) goto out; gtype = gjs_gtype_get_actual_gtype(cx, gtype_jsobj); if (gtype == G_TYPE_NONE) { gjs_throw(cx, "Passed invalid GType to GParamSpecFlags constructor"); goto out; } if (!_gjs_flags_value_is_valid(cx, gtype, default_value)) goto out; pspec = g_param_spec_flags(prop_name, nick, blurb, gtype, default_value, flags); } break; case G_TYPE_FLOAT: case G_TYPE_DOUBLE: { gfloat minimum, maximum, default_value; if (!gjs_parse_args(cx, "GObject.ParamSpec.float", "fff", argc, argv, "minimum", &minimum, "maximum", &maximum, "default_value", &default_value)) goto out; if (prop_type == G_TYPE_FLOAT) pspec = g_param_spec_float(prop_name, nick, blurb, minimum, maximum, default_value, flags); else pspec = g_param_spec_double(prop_name, nick, blurb, minimum, maximum, default_value, flags); } break; case G_TYPE_STRING: { gchar *default_value; if (!gjs_parse_args(cx, method_name, "s", argc, argv, "default_value", &default_value)) goto out; pspec = g_param_spec_string(prop_name, nick, blurb, default_value, flags); g_free (default_value); } break; case G_TYPE_PARAM: pspec = g_param_spec_param(prop_name, nick, blurb, prop_type, flags); break; case G_TYPE_BOXED: pspec = g_param_spec_boxed(prop_name, nick, blurb, prop_type, flags); break; case G_TYPE_POINTER: pspec = g_param_spec_pointer(prop_name, nick, blurb, flags); break; case G_TYPE_OBJECT: pspec = g_param_spec_object(prop_name, nick, blurb, prop_type, flags); break; default: gjs_throw(cx, "Could not create param spec for type '%s'", g_type_name(prop_gtype)); goto out; } ret = JS_TRUE; jsval foo = OBJECT_TO_JSVAL(gjs_param_from_g_param(cx, pspec)); JS_SET_RVAL(cx, vp, foo); out: g_free(method_name); g_free(prop_name); g_free(nick); g_free(blurb); return ret; }
/* a hook on getting a property; set value_p to override property's value. * Return value is JS_FALSE on OOM/exception. */ static JSBool param_get_prop(JSContext *context, JSObject *obj, jsid id, jsval *value_p) { JSBool success; Param *priv; GParamSpec *pspec; char *name; GType gtype; GIObjectInfo *info = NULL, *parent_info = NULL; GIFieldInfo *field_info = NULL; GITypeInfo *type_info = NULL; GIArgument arg; if (!gjs_get_string_id(context, id, &name)) return JS_TRUE; /* not something we affect, but no error */ priv = priv_from_js(context, obj); if (priv == NULL) { g_free(name); return JS_FALSE; /* wrong class */ } success = JS_FALSE; pspec = priv->gparam; gtype = G_TYPE_FROM_INSTANCE(pspec); info = (GIObjectInfo*)g_irepository_find_by_gtype(g_irepository_get_default(), gtype); if (info == NULL) { /* We may have a non-introspectable GParamSpec subclass here. Just return VOID. */ *value_p = JSVAL_VOID; success = JS_TRUE; goto out; } parent_info = g_object_info_get_parent(info); field_info = find_field_info(info, name); if (field_info == NULL) { /* Try it on the parent GParamSpec for generic GParamSpec properties. */ field_info = find_field_info(parent_info, name); } if (field_info == NULL) { *value_p = JSVAL_VOID; success = JS_TRUE; goto out; } type_info = g_field_info_get_type(field_info); if (!g_field_info_get_field(field_info, priv->gparam, &arg)) { gjs_throw(context, "Reading field %s.%s is not supported", g_base_info_get_name(info), g_base_info_get_name((GIBaseInfo*)field_info)); goto out; } if (!gjs_value_from_g_argument(context, value_p, type_info, &arg, TRUE)) goto out; success = JS_TRUE; out: if (field_info != NULL) g_base_info_unref((GIBaseInfo*)field_info); if (type_info != NULL) g_base_info_unref((GIBaseInfo*)type_info); if (info != NULL) g_base_info_unref((GIBaseInfo*)info); if (parent_info != NULL) g_base_info_unref((GIBaseInfo*)parent_info); g_free(name); return success; }