static VALUE
interface_s_property(VALUE self, VALUE property_name)
{
    gpointer ginterface;
    const char* name;
    GParamSpec* prop;
    VALUE result;
    GType gtype = CLASS2GTYPE(self);

    if (SYMBOL_P(property_name))
        name = rb_id2name(SYM2ID(property_name));
    else
        name = StringValuePtr(property_name);

    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) {
        rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")),
                 "No such property: %s", name);
    }

    ginterface = g_type_default_interface_ref(gtype);
    prop = g_object_interface_find_property(ginterface, name);
    if (!prop){
        g_type_default_interface_unref(ginterface);
        rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")),
                 "No such property: %s", name);
    }
    result = GOBJ2RVAL(prop);
    g_type_default_interface_unref(ginterface);

    return result;
}
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;
}
Example #3
0
static void
test_dynamic_iface (void)
{
  TestDynamicIfaceClass *dynamic_iface;

  test_module_new (module_register);

  /* Not loaded until we call ref for the first time */
  dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
  g_assert (dynamic_iface == NULL);

  /* Ref loads */
  dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE);
  g_assert (dynamic_iface_init);
  g_assert (dynamic_iface && dynamic_iface->val == 42);

  /* Peek then works */
  dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
  g_assert (dynamic_iface && dynamic_iface->val == 42);
  
  /* Unref causes finalize */
  g_type_default_interface_unref (dynamic_iface);
#if 0
  g_assert (!dynamic_iface_init);
#endif

  /* Peek returns NULL */
  dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
#if 0
  g_assert (dynamic_iface == NULL);
#endif
  
  /* Ref reloads */
  dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE);
  g_assert (dynamic_iface_init);
  g_assert (dynamic_iface && dynamic_iface->val == 42);

  /* And Unref causes finalize once more*/
  g_type_default_interface_unref (dynamic_iface);
#if 0
  g_assert (!dynamic_iface_init);
#endif
}
Example #4
0
void
_g_type_struct_unref (GType    the_type,
                      gpointer type_struct)
{
  if (G_TYPE_IS_INTERFACE (the_type))
    g_type_default_interface_unref (type_struct);
  else if (G_TYPE_IS_OBJECT (the_type))
    g_type_class_unref (type_struct);
  else
    g_return_if_reached ();
}
static VALUE
interface_s_install_property(VALUE self, VALUE pspec_obj)
{
    const RGObjClassInfo* cinfo = rbgobj_lookup_class(self);
    gpointer ginterface;
    GParamSpec* pspec;

    if (cinfo->klass != self)
        rb_raise(rb_eTypeError, "%s isn't registered class", rb_class2name(self));

    pspec = G_PARAM_SPEC(RVAL2GOBJ(pspec_obj));
    ginterface = g_type_default_interface_ref(cinfo->gtype);
    g_object_interface_install_property(ginterface, pspec);
    g_type_default_interface_unref(ginterface);

    /* FIXME: define accessor methods */
    return Qnil;
}
Example #6
0
static void
test_static_iface (void)
{
    TestStaticIfaceClass *static_iface;

    /* Not loaded until we call ref for the first time */
    static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
    g_assert (static_iface == NULL);

    /* Ref loads */
    static_iface = g_type_default_interface_ref (TEST_TYPE_STATIC_IFACE);
    g_assert (static_iface && static_iface->val == 42);

    /* Peek then works */
    static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
    g_assert (static_iface && static_iface->val == 42);

    /* Unref does nothing */
    g_type_default_interface_unref (static_iface);

    /* And peek still works */
    static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
    g_assert (static_iface && static_iface->val == 42);
}
Example #7
0
std::string
get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strResult;
  std::string strObjectName = g_type_name(gtype);

  gpointer gclass_ref = nullptr;
  gpointer ginterface_ref = nullptr;

  if (G_TYPE_IS_OBJECT(gtype))
    gclass_ref = g_type_class_ref(gtype); // Ensures that class_init() is called.
  else if (G_TYPE_IS_INTERFACE(gtype))
    ginterface_ref = g_type_default_interface_ref(gtype); // install signals.

  // Get the list of signals:
  guint iCount = 0;
  guint* pIDs = g_signal_list_ids(gtype, &iCount);

  // Loop through the list of signals:
  if (pIDs)
  {
    for (guint i = 0; i < iCount; i++)
    {
      guint signal_id = pIDs[i];

      // Name:
      std::string strName = g_signal_name(signal_id);
      strResult += "(define-signal " + strName + "\n";
      strResult += "  (of-object \"" + strObjectName + "\")\n";

      // Other information about the signal:
      GSignalQuery signalQuery = {
        0, nullptr, 0, GSignalFlags(0), 0, 0, nullptr,
      };
      g_signal_query(signal_id, &signalQuery);

      // Return type:
      std::string strReturnTypeName =
        get_type_name_signal(signalQuery.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE,
          is_a_pointer_func); // The type is mangled with a flag. Hacky.
      // bool bReturnTypeHasStaticScope = (signalQuery.return_type & G_SIGNAL_TYPE_STATIC_SCOPE) ==
      // G_SIGNAL_TYPE_STATIC_SCOPE;
      strResult += "  (return-type \"" + strReturnTypeName + "\")\n";

      // Flags:
      std::string strFlags;
      add_signal_flag_if(strFlags, "Run First", signalQuery, G_SIGNAL_RUN_FIRST);
      add_signal_flag_if(strFlags, "Run Last", signalQuery, G_SIGNAL_RUN_LAST);
      add_signal_flag_if(strFlags, "Run Cleanup", signalQuery, G_SIGNAL_RUN_CLEANUP);
      add_signal_flag_if(strFlags, "No Recurse", signalQuery, G_SIGNAL_NO_RECURSE);
      add_signal_flag_if(strFlags, "Action", signalQuery, G_SIGNAL_ACTION);
      add_signal_flag_if(strFlags, "No Hooks", signalQuery, G_SIGNAL_NO_HOOKS);
      add_signal_flag_if(strFlags, "Must Collect", signalQuery, G_SIGNAL_MUST_COLLECT);
      strResult += "  (flags \"" + strFlags + "\")\n";

      if (signalQuery.signal_flags & G_SIGNAL_DETAILED)
        strResult += "  (detailed #t)\n"; // Default: not detailed

      if (signalQuery.signal_flags & G_SIGNAL_DEPRECATED)
        strResult += "  (deprecated #t)\n"; // Default: not deprecated

      // Loop through the list of parameters:
      const GType* pParameters = signalQuery.param_types;
      if (pParameters)
      {
        strResult += "  (parameters\n";

        for (unsigned j = 0; j < signalQuery.n_params; j++)
        {
          GType typeParamMangled = pParameters[j];

          // Parameter name:
          // We can't get the real parameter name from the GObject system. It's not registered with
          // g_signal_new().
          gchar* pchNum = g_strdup_printf("%d", j);
          std::string strParamName = "p" + std::string(pchNum);
          g_free(pchNum);
          pchNum = nullptr;

          // Just like above, for the return type:
          std::string strTypeName =
            get_type_name_signal(typeParamMangled & ~G_SIGNAL_TYPE_STATIC_SCOPE,
              is_a_pointer_func); // The type is mangled with a flag. Hacky.
          // bool bTypeHasStaticScope = (typeParamMangled & G_SIGNAL_TYPE_STATIC_SCOPE) ==
          // G_SIGNAL_TYPE_STATIC_SCOPE;

          strResult += "    '(\"" + strTypeName + "\" \"" + strParamName + "\")\n";
        }

        strResult += "  )\n"; // close (parameters
      }

      strResult += ")\n\n"; // close (define-signal
    }
  }

  g_free(pIDs);

  if (gclass_ref)
    g_type_class_unref(gclass_ref); // to match the g_type_class_ref() above.
  else if (ginterface_ref)
    g_type_default_interface_unref(ginterface_ref); // for interface ref above.

  return strResult;
}
Example #8
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;
}
Example #9
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);
}