コード例 #1
0
ファイル: marshal.c プロジェクト: ntd/lgi
/* 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;
}
コード例 #2
0
ファイル: value.c プロジェクト: Katyunechka/gjs
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);
}
コード例 #3
0
ファイル: interface.cpp プロジェクト: GNOME/gjs
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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: param.cpp プロジェクト: leigh123linux/cjs
/*
 * 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;
}
コード例 #6
0
ファイル: core.c プロジェクト: heirecka/lgi
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);
}
コード例 #7
0
ファイル: fundamental.cpp プロジェクト: victoryang/gjs
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;
}
コード例 #8
0
ファイル: fundamental.cpp プロジェクト: victoryang/gjs
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;
}
コード例 #9
0
ファイル: param.cpp プロジェクト: leigh123linux/cjs
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());
}
コード例 #10
0
ファイル: pygi-property.c プロジェクト: jdahlin/pygobject
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;
}
コード例 #11
0
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);
}
コード例 #12
0
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;
}
コード例 #13
0
ファイル: byteArray.cpp プロジェクト: victoryang/gjs
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;
}
コード例 #14
0
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));
}
コード例 #15
0
ファイル: value.c プロジェクト: Katyunechka/gjs
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;
}
コード例 #16
0
ファイル: param.c プロジェクト: goizueta/gjs
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", &gtype_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", &gtype_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;
}
コード例 #17
0
ファイル: param.c プロジェクト: goizueta/gjs
/* 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;
}