static VALUE
interface_s_properties(int argc, VALUE* argv, VALUE self)
{
    guint n_properties;
    GParamSpec** props;
    VALUE inherited_too;
    VALUE ary = rb_ary_new();
    guint i;
    gpointer ginterface;
    GType gtype = CLASS2GTYPE(self);

    if (rb_scan_args(argc, argv, "01", &inherited_too) == 0)
        inherited_too = Qtrue;

    if (!G_TYPE_IS_INTERFACE(gtype))
        rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self));
    /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */
    if (gtype == G_TYPE_INTERFACE) return ary;

    ginterface = g_type_default_interface_ref(gtype);
    props = g_object_interface_list_properties(ginterface, &n_properties);
    for (i = 0; i < n_properties; i++){
        if (RVAL2CBOOL(inherited_too) || GTYPE2CLASS(props[i]->owner_type) == self)
            rb_ary_push(ary, rb_str_new2(props[i]->name));
    }
    g_free(props);
    g_type_default_interface_unref(ginterface);

    return ary;
}
static void
extension_subclass_init (GObjectClass *klass,
                         GType        *exten_types)
{
  guint i;
  guint property_id = 1;

  g_debug ("Initializing class '%s'", G_OBJECT_CLASS_NAME (klass));

  klass->set_property = extension_subclass_set_property;
  klass->get_property = extension_subclass_get_property;

  for (i = 0; exten_types[i] != 0; ++i)
    {
      guint n_props, j;
      gpointer iface_vtable;
      GParamSpec **properties;

      iface_vtable = g_type_default_interface_peek (exten_types[i]);
      properties = g_object_interface_list_properties (iface_vtable, &n_props);

      for (j = 0; j < n_props; ++j, ++property_id)
        {
          const gchar *property_name;

          property_name = g_param_spec_get_name (properties[j]);

          g_object_class_override_property (klass, property_id, property_name);

          g_debug ("Overrided '%s:%s' for '%s' proxy",
                   g_type_name (exten_types[i]), property_name,
                   G_OBJECT_CLASS_NAME (klass));
        }

      g_free (properties);
    }

  g_debug ("Initialized class '%s'", G_OBJECT_CLASS_NAME (klass));
}
Пример #3
0
// Until the glib bug https://bugzilla.gnome.org/show_bug.cgi?id=465631
// is fixed, get_properties() must be called for a GObject before it's
// called for a GInterface.
std::string
get_properties(GType gtype)
{
  std::string strResult;
  std::string strObjectName = g_type_name(gtype);

  // Get the list of properties:
  GParamSpec** ppParamSpec = nullptr;
  guint iCount = 0;
  if (G_TYPE_IS_OBJECT(gtype))
  {
    GObjectClass* pGClass = G_OBJECT_CLASS(g_type_class_ref(gtype));
    ppParamSpec = g_object_class_list_properties(pGClass, &iCount);
    g_type_class_unref(pGClass);

    if (!ppParamSpec)
    {
      strResult += ";; Warning: g_object_class_list_properties() returned NULL for " +
                   std::string(g_type_name(gtype)) + "\n";
    }
  }
  else if (G_TYPE_IS_INTERFACE(gtype))
  {
    gpointer pGInterface = g_type_default_interface_ref(gtype);
    if (pGInterface)
    {
      ppParamSpec = g_object_interface_list_properties(pGInterface, &iCount);
      g_type_default_interface_unref(pGInterface);

      if (!ppParamSpec)
      {
        strResult += ";; Warning: g_object_interface_list_properties() returned NULL for " +
                     std::string(g_type_name(gtype)) + "\n";
      }
    }
    else
      strResult += ";; Warning: g_type_default_interface_ref() returned NULL for " +
                   std::string(g_type_name(gtype)) + "\n";
  }

  // This extra check avoids an occasional crash
  if (!ppParamSpec)
    iCount = 0;

  for (guint i = 0; i < iCount; i++)
  {
    GParamSpec* pParamSpec = ppParamSpec[i];
    // Generate the property if the specified gtype actually owns the property.
    // (Generally all properties, including any base classes' properties are
    // retrieved by g_object_interface_list_properties() for a given gtype.
    // The base classes' properties should not be generated).
    if (pParamSpec && pParamSpec->owner_type == gtype)
    {
      strResult += get_property_with_node_name(pParamSpec, strObjectName, "define-property");
    }
  }

  g_free(ppParamSpec);

  return strResult;
}
Пример #4
0
void
rbgobj_define_property_accessors(VALUE klass)
{
    GType gtype;
    GParamSpec** pspecs = NULL;
    guint i;
    GString* source;
    guint n_properties = 0;
    gtype = CLASS2GTYPE(klass);

    if (G_TYPE_IS_INTERFACE(gtype)){
#if GLIB_CHECK_VERSION(2,4,0)
        gpointer iface = g_type_default_interface_ref(gtype);
        pspecs = g_object_interface_list_properties(iface, &n_properties);
        g_type_default_interface_unref(iface);
#endif
    } else {
        GObjectClass* oclass = G_OBJECT_CLASS(g_type_class_ref(gtype));
        pspecs = g_object_class_list_properties(oclass, &n_properties);
        g_type_class_unref(oclass);
    }

    if (n_properties == 0)
        return;

    source = g_string_new(NULL);
    for (i = 0; i < n_properties; i++){
        GParamSpec* pspec = pspecs[i];
        char* buf;
        char* prop_name;
        char* p;

        if (pspec->owner_type != gtype)
            continue;

        buf = g_strdup(pspec->name);
        for (p = buf; *p; p++)
            if (*p == '-')
                *p = '_';

        if (!strncmp(buf, "is_", 3))
            prop_name = buf + 3;
        else
            prop_name = buf;

        if (g_hash_table_lookup(prop_exclude_list, prop_name)){
            g_free(buf);
            continue;
        }

        if (pspec->flags & G_PARAM_READABLE){
            g_string_append_printf(
                source, 
                "def %s%s; get_property('%s'); end\n",
                prop_name,
                (G_PARAM_SPEC_VALUE_TYPE(pspec) == G_TYPE_BOOLEAN) ? "?" : "",
                pspec->name);
        }

        if (IS_FLAG(pspec->flags, G_PARAM_WRITABLE) && !IS_FLAG(pspec->flags, G_PARAM_CONSTRUCT_ONLY)){
            g_string_append_printf(source,
                "def set_%s(val); set_property('%s', val); end\n",
                prop_name, pspec->name);
#ifdef HAVE_NODE_ATTRASGN
            g_string_append_printf(source, "alias %s= set_%s\n",
                                   prop_name, prop_name);
#else
            g_string_append_printf(source,
                "def %s=(val); set_property('%s', val); val; end\n",
                prop_name, pspec->name);
#endif
        }

        g_free(buf);
    }

    if (source->len > 0)
        rb_funcall(klass, id_module_eval, 1, rb_str_new2(source->str));
    g_string_free(source, TRUE);
}