[gobject-introspection] Add support for non-GObject fundamental objects



commit 1e9822c7817062a9b853269b9418fd78782090b5
Author: Johan Dahlin <johan gnome org>
Date:   Sat Jun 12 18:08:56 2010 -0300

    Add support for non-GObject fundamental objects
    
    This patch adds support for instantiable fundamental object types,
    which are not GObject based. This is mostly interesting for being
    able to support GstMiniObject's which are extensivly used in GStreamer.
    Includes a big test case to the Everything module (inspired by
    GstMiniObject) which should be used by language bindings who wishes to
    test this functionallity.
    
    This patch increases the size of the typelib and breaks compatibility
    with older typelibs.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=568913

 docs/reference/gi-sections.txt      |   13 ++
 gir/Everything-1.0-expected.gir     |  101 ++++++++++++
 gir/everything.c                    |  293 +++++++++++++++++++++++++++++++++++
 gir/everything.h                    |   55 +++++++
 girepository/gdump.c                |   55 ++++++-
 girepository/giobjectinfo.c         |  249 +++++++++++++++++++++++++++++
 girepository/giobjectinfo.h         |   52 ++++++
 girepository/giregisteredtypeinfo.h |    3 +-
 girepository/girnode.c              |   21 +++
 girepository/girnode.h              |    6 +
 girepository/girparser.c            |   19 +++
 girepository/girwriter.c            |   22 +++
 girepository/gitypelib-internal.h   |   23 +++-
 girepository/gitypelib.c            |    2 +-
 giscanner/annotationparser.py       |   15 ++
 giscanner/girwriter.py              |   11 ++
 giscanner/glibast.py                |    5 +
 giscanner/glibtransformer.py        |   32 ++++
 18 files changed, 970 insertions(+), 7 deletions(-)
---
diff --git a/docs/reference/gi-sections.txt b/docs/reference/gi-sections.txt
index 261afd8..6b04bbf 100644
--- a/docs/reference/gi-sections.txt
+++ b/docs/reference/gi-sections.txt
@@ -144,9 +144,14 @@ g_interface_info_find_vfunc
 <FILE>giobjectinfo</FILE>
 GI_IS_OBJECT_INFO
 GIObjectInfo
+GIObjectInfoGetValueFunction
+GIObjectInfoRefFunction
+GIObjectInfoSetValueFunction
+GIObjectInfoUnrefFunction
 g_object_info_get_type_name
 g_object_info_get_type_init
 g_object_info_get_abstract
+g_object_info_get_fundamental
 g_object_info_get_parent
 g_object_info_get_n_interfaces
 g_object_info_get_interface
@@ -165,6 +170,14 @@ g_object_info_get_n_constants
 g_object_info_get_constant
 g_object_info_get_class_struct
 g_object_info_find_vfunc
+g_object_info_get_unref_function
+g_object_info_get_unref_function_pointer
+g_object_info_get_ref_function
+g_object_info_get_ref_function_pointer
+g_object_info_get_set_value_function
+g_object_info_get_set_value_function_pointer
+g_object_info_get_get_value_function
+g_object_info_get_get_value_function_pointer
 </SECTION>
 
 <SECTION>
diff --git a/gir/Everything-1.0-expected.gir b/gir/Everything-1.0-expected.gir
index 7fe9d1d..4d3d263 100644
--- a/gir/Everything-1.0-expected.gir
+++ b/gir/Everything-1.0-expected.gir
@@ -161,6 +161,107 @@ and/or use gtk-doc annotations.  -->
               c:type="GInitiallyUnownedClass"/>
       </field>
     </record>
+    <class name="TestFundamentalObject"
+           c:type="TestFundamentalObject"
+           abstract="1"
+           glib:type-name="TestFundamentalObject"
+           glib:get-type="test_fundamental_object_get_type"
+           glib:type-struct="TestFundamentalObjectClass"
+           glib:fundamental="1"
+           glib:ref-func="test_fundamental_object_ref"
+           glib:unref-func="test_fundamental_object_unref"
+           glib:set-value-func="test_value_set_fundamental_object"
+           glib:get-value-func="test_value_get_fundamental_object">
+      <method name="ref" c:identifier="test_fundamental_object_ref">
+        <return-value transfer-ownership="full">
+          <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+        </return-value>
+      </method>
+      <method name="unref" c:identifier="test_fundamental_object_unref">
+        <return-value transfer-ownership="none">
+          <type name="none" c:type="void"/>
+        </return-value>
+      </method>
+      <field name="instance">
+        <type name="GObject.TypeInstance" c:type="GTypeInstance"/>
+      </field>
+      <field name="refcount">
+        <type name="int" c:type="gint"/>
+      </field>
+      <field name="flags">
+        <type name="uint" c:type="guint"/>
+      </field>
+    </class>
+    <record name="TestFundamentalObjectClass"
+            c:type="TestFundamentalObjectClass"
+            glib:is-gtype-struct-for="TestFundamentalObject">
+      <field name="type_class">
+        <type name="GObject.TypeClass" c:type="GTypeClass"/>
+      </field>
+      <field name="copy">
+        <type name="TestFundamentalObjectCopyFunction"
+              c:type="TestFundamentalObjectCopyFunction"/>
+      </field>
+      <field name="finalize">
+        <type name="TestFundamentalObjectFinalizeFunction"
+              c:type="TestFundamentalObjectFinalizeFunction"/>
+      </field>
+    </record>
+    <callback name="TestFundamentalObjectCopyFunction"
+              c:type="TestFundamentalObjectCopyFunction">
+      <return-value transfer-ownership="full">
+        <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+      </return-value>
+      <parameters>
+        <parameter name="obj" transfer-ownership="none">
+          <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+        </parameter>
+      </parameters>
+    </callback>
+    <callback name="TestFundamentalObjectFinalizeFunction"
+              c:type="TestFundamentalObjectFinalizeFunction">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="obj" transfer-ownership="none">
+          <type name="TestFundamentalObject" c:type="TestFundamentalObject*"/>
+        </parameter>
+      </parameters>
+    </callback>
+    <class name="TestFundamentalSubObject"
+           c:type="TestFundamentalSubObject"
+           parent="TestFundamentalObject"
+           glib:type-name="TestFundamentalSubObject"
+           glib:get-type="test_fundamental_sub_object_get_type"
+           glib:type-struct="TestFundamentalSubObjectClass"
+           glib:fundamental="1">
+      <constructor name="new" c:identifier="test_fundamental_sub_object_new">
+        <return-value transfer-ownership="full">
+          <type name="TestFundamentalSubObject"
+                c:type="TestFundamentalSubObject*"/>
+        </return-value>
+        <parameters>
+          <parameter name="data" transfer-ownership="none">
+            <type name="utf8" c:type="char*"/>
+          </parameter>
+        </parameters>
+      </constructor>
+      <field name="fundamental_object">
+        <type name="TestFundamentalObject" c:type="TestFundamentalObject"/>
+      </field>
+      <field name="data">
+        <type name="utf8" c:type="char*"/>
+      </field>
+    </class>
+    <record name="TestFundamentalSubObjectClass"
+            c:type="TestFundamentalSubObjectClass"
+            glib:is-gtype-struct-for="TestFundamentalSubObject">
+      <field name="fundamental_object_class">
+        <type name="TestFundamentalObjectClass"
+              c:type="TestFundamentalObjectClass"/>
+      </field>
+    </record>
     <interface name="TestInterface"
                c:type="EverythingTestInterface"
                glib:type-name="EverythingTestInterface"
diff --git a/gir/everything.c b/gir/everything.c
index 2219667..a2b4ef6 100644
--- a/gir/everything.c
+++ b/gir/everything.c
@@ -1,5 +1,8 @@
 #include <string.h>
 #include <stdlib.h>
+#include <glib-object.h>
+#include <gobject/gvaluecollector.h>
+
 #include "everything.h"
 
 static gboolean abort_on_error = TRUE;
@@ -1896,6 +1899,296 @@ test_sub_obj_unset_bare (TestSubObj *obj)
   test_obj_set_bare(TEST_OBJECT(obj), NULL);
 }
 
+/* TestFundamental */
+
+TestFundamentalObject *
+test_fundamental_object_ref (TestFundamentalObject * fundamental_object)
+{
+  g_return_val_if_fail (fundamental_object != NULL, NULL);
+  g_atomic_int_inc (&fundamental_object->refcount);
+
+  return fundamental_object;
+}
+
+static void
+test_fundamental_object_free (TestFundamentalObject * fundamental_object)
+{
+  TestFundamentalObjectClass *mo_class;
+  test_fundamental_object_ref (fundamental_object);
+
+  mo_class = TEST_FUNDAMENTAL_OBJECT_GET_CLASS (fundamental_object);
+  mo_class->finalize (fundamental_object);
+
+  if (G_LIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
+    g_type_free_instance ((GTypeInstance *) fundamental_object);
+  }
+}
+
+void
+test_fundamental_object_unref (TestFundamentalObject * fundamental_object)
+{
+  g_return_if_fail (fundamental_object != NULL);
+  g_return_if_fail (fundamental_object->refcount > 0);
+
+  if (G_UNLIKELY (g_atomic_int_dec_and_test (&fundamental_object->refcount))) {
+    test_fundamental_object_free (fundamental_object);
+  }
+}
+
+static void
+test_fundamental_object_replace (TestFundamentalObject ** olddata, TestFundamentalObject * newdata)
+{
+  TestFundamentalObject *olddata_val;
+
+  g_return_if_fail (olddata != NULL);
+
+  olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+
+  if (olddata_val == newdata)
+    return;
+
+  if (newdata)
+    test_fundamental_object_ref (newdata);
+
+  while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
+          olddata_val, newdata)) {
+    olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+  }
+
+  if (olddata_val)
+    test_fundamental_object_unref (olddata_val);
+}
+
+static void
+test_value_fundamental_object_init (GValue * value)
+{
+  value->data[0].v_pointer = NULL;
+}
+
+static void
+test_value_fundamental_object_free (GValue * value)
+{
+  if (value->data[0].v_pointer) {
+    test_fundamental_object_unref (TEST_FUNDAMENTAL_OBJECT_CAST (value->data[0].v_pointer));
+  }
+}
+
+static void
+test_value_fundamental_object_copy (const GValue * src_value, GValue * dest_value)
+{
+  if (src_value->data[0].v_pointer) {
+    dest_value->data[0].v_pointer =
+        test_fundamental_object_ref (TEST_FUNDAMENTAL_OBJECT_CAST (src_value->data[0].
+            v_pointer));
+  } else {
+    dest_value->data[0].v_pointer = NULL;
+  }
+}
+
+static gpointer
+test_value_fundamental_object_peek_pointer (const GValue * value)
+{
+  return value->data[0].v_pointer;
+}
+
+static gchar *
+test_value_fundamental_object_collect (GValue * value,
+                                       guint n_collect_values,
+                                       GTypeCValue * collect_values,
+                                       guint collect_flags)
+{
+  if (collect_values[0].v_pointer) {
+    value->data[0].v_pointer =
+        test_fundamental_object_ref (collect_values[0].v_pointer);
+  } else {
+    value->data[0].v_pointer = NULL;
+  }
+
+  return NULL;
+}
+
+static gchar *
+test_value_fundamental_object_lcopy (const GValue * value,
+                                     guint n_collect_values,
+                                     GTypeCValue * collect_values,
+                                     guint collect_flags)
+{
+  gpointer *fundamental_object_p = collect_values[0].v_pointer;
+
+  if (!fundamental_object_p) {
+    return g_strdup_printf ("value location for '%s' passed as NULL",
+        G_VALUE_TYPE_NAME (value));
+  }
+
+  if (!value->data[0].v_pointer)
+    *fundamental_object_p = NULL;
+  else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
+    *fundamental_object_p = value->data[0].v_pointer;
+  else
+    *fundamental_object_p = test_fundamental_object_ref (value->data[0].v_pointer);
+
+  return NULL;
+}
+
+static void
+test_fundamental_object_finalize (TestFundamentalObject * obj)
+{
+
+}
+
+static TestFundamentalObject *
+test_fundamental_object_copy_default (const TestFundamentalObject * obj)
+{
+  g_warning ("TestFundamentalObject classes must implement TestFundamentalObject::copy");
+  return NULL;
+}
+
+static void
+test_fundamental_object_class_init (gpointer g_class, gpointer class_data)
+{
+  TestFundamentalObjectClass *mo_class = TEST_FUNDAMENTAL_OBJECT_CLASS (g_class);
+
+  mo_class->copy = test_fundamental_object_copy_default;
+  mo_class->finalize = test_fundamental_object_finalize;
+}
+
+static void
+test_fundamental_object_init (GTypeInstance * instance, gpointer klass)
+{
+  TestFundamentalObject *fundamental_object = TEST_FUNDAMENTAL_OBJECT_CAST (instance);
+
+  fundamental_object->refcount = 1;
+}
+
+/**
+ * TestFundamentalObject:
+ *
+ * Ref Func: test_fundamental_object_ref
+ * Unref Func: test_fundamental_object_unref
+ * Set Value Func: test_value_set_fundamental_object
+ * Get Value Func: test_value_get_fundamental_object
+ */
+
+GType
+test_fundamental_object_get_type (void)
+{
+  static GType _test_fundamental_object_type = 0;
+
+  if (G_UNLIKELY (_test_fundamental_object_type == 0)) {
+    static const GTypeValueTable value_table = {
+      test_value_fundamental_object_init,
+      test_value_fundamental_object_free,
+      test_value_fundamental_object_copy,
+      test_value_fundamental_object_peek_pointer,
+      (char *) "p",
+      test_value_fundamental_object_collect,
+      (char *) "p",
+      test_value_fundamental_object_lcopy
+    };
+    static const GTypeInfo fundamental_object_info = {
+      sizeof (TestFundamentalObjectClass),
+      NULL, NULL,
+      test_fundamental_object_class_init,
+      NULL,
+      NULL,
+      sizeof (TestFundamentalObject),
+      0,
+      (GInstanceInitFunc) test_fundamental_object_init,
+      &value_table
+    };
+    static const GTypeFundamentalInfo fundamental_object_fundamental_info = {
+      (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
+          G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
+    };
+
+    _test_fundamental_object_type = g_type_fundamental_next ();
+    g_type_register_fundamental (_test_fundamental_object_type, "TestFundamentalObject",
+        &fundamental_object_info, &fundamental_object_fundamental_info, G_TYPE_FLAG_ABSTRACT);
+
+  }
+
+  return _test_fundamental_object_type;
+}
+
+/**
+ * test_value_set_fundamental_object: (skip)
+ * @value:
+ * @fundamental_object:
+ */
+void
+test_value_set_fundamental_object (GValue * value, TestFundamentalObject * fundamental_object)
+{
+  gpointer *pointer_p;
+
+  g_return_if_fail (TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value));
+  g_return_if_fail (fundamental_object == NULL || TEST_IS_FUNDAMENTAL_OBJECT (fundamental_object));
+
+  pointer_p = &value->data[0].v_pointer;
+
+  test_fundamental_object_replace ((TestFundamentalObject **) pointer_p, fundamental_object);
+}
+
+/**
+ * test_value_get_fundamental_object: (skip)
+ * @value:
+ */
+TestFundamentalObject *
+test_value_get_fundamental_object (const GValue * value)
+{
+  g_return_val_if_fail (TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT (value), NULL);
+
+  return value->data[0].v_pointer;
+}
+
+static TestFundamentalObjectClass *parent_class = NULL;
+
+G_DEFINE_TYPE (TestFundamentalSubObject, test_fundamental_sub_object, TEST_TYPE_FUNDAMENTAL_OBJECT);
+
+static TestFundamentalSubObject *
+_test_fundamental_sub_object_copy (TestFundamentalSubObject * fundamental_sub_object)
+{
+  TestFundamentalSubObject *copy;
+
+  copy = test_fundamental_sub_object_new(NULL);
+  copy->data = g_strdup(fundamental_sub_object->data);
+  return copy;
+}
+
+static void
+test_fundamental_sub_object_finalize (TestFundamentalSubObject * fundamental_sub_object)
+{
+  g_return_if_fail (fundamental_sub_object != NULL);
+
+  g_free(fundamental_sub_object->data);
+  test_fundamental_object_unref (TEST_FUNDAMENTAL_OBJECT (fundamental_sub_object));
+}
+
+static void
+test_fundamental_sub_object_class_init (TestFundamentalSubObjectClass * klass)
+{
+  parent_class = g_type_class_peek_parent (klass);
+
+  klass->fundamental_object_class.copy = (TestFundamentalObjectCopyFunction) _test_fundamental_sub_object_copy;
+  klass->fundamental_object_class.finalize =
+      (TestFundamentalObjectFinalizeFunction) test_fundamental_sub_object_finalize;
+}
+
+static void
+test_fundamental_sub_object_init(TestFundamentalSubObject *object)
+{
+
+}
+
+TestFundamentalSubObject *
+test_fundamental_sub_object_new (const char * data)
+{
+  TestFundamentalSubObject *object;
+
+  object = (TestFundamentalSubObject *) g_type_create_instance (test_fundamental_sub_object_get_type());
+  object->data = g_strdup(data);
+  return object;
+}
+
 
 /**
  * test_callback:
diff --git a/gir/everything.h b/gir/everything.h
index 8a8b1e0..55b26cd 100644
--- a/gir/everything.h
+++ b/gir/everything.h
@@ -334,6 +334,61 @@ TestSubObj* test_sub_obj_new (void);
 void        test_sub_obj_unset_bare (TestSubObj *obj);
 int         test_sub_obj_instance_method (TestSubObj *obj);
 
+/* fundamental object */
+#define TEST_TYPE_FUNDAMENTAL_OBJECT            (test_fundamental_object_get_type())
+#define TEST_IS_FUNDAMENTAL_OBJECT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_FUNDAMENTAL_OBJECT))
+#define TEST_IS_FUNDAMENTAL_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_FUNDAMENTAL_OBJECT))
+#define TEST_FUNDAMENTAL_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_FUNDAMENTAL_OBJECT, TestFundamentalObjectClass))
+#define TEST_FUNDAMENTAL_OBJECT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_FUNDAMENTAL_OBJECT, TestFundamentalObject))
+#define TEST_FUNDAMENTAL_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_FUNDAMENTAL_OBJECT, TestFundamentalObjectClass))
+#define TEST_FUNDAMENTAL_OBJECT_CAST(obj)       ((TestFundamentalObject*)(obj))
+
+typedef struct _TestFundamentalObject TestFundamentalObject;
+typedef struct _TestFundamentalObjectClass TestFundamentalObjectClass;
+typedef TestFundamentalObject * (*TestFundamentalObjectCopyFunction) (const TestFundamentalObject *obj);
+typedef void (*TestFundamentalObjectFinalizeFunction) (TestFundamentalObject *obj);
+
+
+struct _TestFundamentalObject {
+  GTypeInstance instance;
+  gint refcount;
+  guint flags;
+};
+
+struct _TestFundamentalObjectClass {
+  GTypeClass type_class;
+
+  TestFundamentalObjectCopyFunction copy;
+  TestFundamentalObjectFinalizeFunction finalize;
+};
+
+GType 		       test_fundamental_object_get_type (void);
+TestFundamentalObject* test_fundamental_object_ref      (TestFundamentalObject *fundamental_object);
+void 		       test_fundamental_object_unref 	(TestFundamentalObject *fundamental_object);
+
+#define TEST_VALUE_HOLDS_FUNDAMENTAL_OBJECT(value)  (G_VALUE_HOLDS(value, TEST_TYPE_FUNDAMENTAL_OBJECT))
+
+void 		       test_value_set_fundamental_object (GValue *value, TestFundamentalObject *fundamental_object);
+TestFundamentalObject* test_value_get_fundamental_object (const GValue *value);
+
+typedef struct _TestFundamentalSubObject TestFundamentalSubObject;
+typedef struct _TestFundamentalSubObjectClass TestFundamentalSubObjectClass;
+
+struct _TestFundamentalSubObject
+{
+  TestFundamentalObject fundamental_object;
+  char *data;
+};
+
+struct _TestFundamentalSubObjectClass {
+  TestFundamentalObjectClass fundamental_object_class;
+};
+
+GType test_fundamental_sub_object_get_type(void);
+
+TestFundamentalSubObject *
+test_fundamental_sub_object_new (const char *data);
+
 /* callback */
 typedef void (*TestSimpleCallback) (void);
 typedef int (*TestCallback) (void);
diff --git a/girepository/gdump.c b/girepository/gdump.c
index 5cb10b0..328f075 100644
--- a/girepository/gdump.c
+++ b/girepository/gdump.c
@@ -271,6 +271,56 @@ dump_enum_type (GType type, const char *symbol, GOutputStream *out)
 }
 
 static void
+dump_fundamental_type (GType type, const char *symbol, GOutputStream *out)
+{
+  guint n_interfaces;
+  guint i;
+  GType *interfaces;
+  GString *parent_str;
+  GType parent;
+  gboolean first = TRUE;
+
+
+  escaped_printf (out, "  <fundamental name=\"%s\" get-type=\"%s\"",
+		  g_type_name (type), symbol);
+
+  if (G_TYPE_IS_ABSTRACT (type))
+    escaped_printf (out, " abstract=\"1\"");
+
+  if (G_TYPE_IS_INSTANTIATABLE (type))
+    escaped_printf (out, " instantiatable=\"1\"");
+
+  parent = type;
+  parent_str = g_string_new ("");
+  do
+    {
+      parent = g_type_parent (parent);
+      if (first)
+        first = FALSE;
+      else
+        g_string_append_c (parent_str, ',');
+      if (!g_type_name (parent))
+        break;
+      g_string_append (parent_str, g_type_name (parent));
+    } while (parent != G_TYPE_INVALID);
+
+  if (parent_str->len > 0)
+    escaped_printf (out, " parents=\"%s\"", parent_str->str);
+  g_string_free (parent_str, TRUE);
+
+  goutput_write (out, ">\n");
+
+  interfaces = g_type_interfaces (type, &n_interfaces);
+  for (i = 0; i < n_interfaces; i++)
+    {
+      GType itype = interfaces[i];
+      escaped_printf (out, "    <implements name=\"%s\"/>\n",
+		      g_type_name (itype));
+    }
+  goutput_write (out, "  </fundamental>\n");
+}
+
+static void
 dump_type (GType type, const char *symbol, GOutputStream *out)
 {
   switch (g_type_fundamental (type))
@@ -294,10 +344,7 @@ dump_type (GType type, const char *symbol, GOutputStream *out)
       /* GValue, etc.  Just skip them. */
       break;
     default:
-      /* Other fundamental types such as the once GStreamer and Clutter registers
-       * are not yet interesting from an introspection perspective and should be
-       * ignored
-       */
+      dump_fundamental_type (type, symbol, out);
       break;
     }
 }
diff --git a/girepository/giobjectinfo.c b/girepository/giobjectinfo.c
index ace8d5d..bc2ddcd 100644
--- a/girepository/giobjectinfo.c
+++ b/girepository/giobjectinfo.c
@@ -97,6 +97,29 @@ g_object_info_get_abstract (GIObjectInfo *info)
 }
 
 /**
+ * g_object_info_get_fundamental:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain if the object type is of a fundamental type which is not
+ * G_TYPE_OBJECT. This is mostly for supporting GstMiniObject.
+ *
+ * Returns: %TRUE if the object type is a fundamental type
+ */
+gboolean
+g_object_info_get_fundamental (GIObjectInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob;
+
+  g_return_val_if_fail (info != NULL, FALSE);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
+
+  blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->fundamental != 0;
+}
+
+/**
  * g_object_info_get_type_name:
  * @info: a #GIObjectInfo
  *
@@ -636,3 +659,229 @@ g_object_info_get_class_struct (GIObjectInfo *info)
     return NULL;
 }
 
+typedef const char* (*SymbolGetter) (GIObjectInfo *info);
+
+static void *
+_get_func(GIObjectInfo *info,
+          SymbolGetter getter)
+{
+  const char* symbol;
+  GSList *parents = NULL, *l;
+  GIObjectInfo *parent_info;
+
+  parent_info = info;
+  while (parent_info != NULL) {
+    parents = g_slist_prepend(parents, parent_info);
+    parent_info = g_object_info_get_parent(parent_info);
+  }
+
+  for (l = parents; l; l = l->next) {
+    GIObjectInfoRefFunction func;
+    parent_info = l->data;
+    symbol = getter(parent_info);
+    if (symbol == NULL)
+      continue;
+    if (g_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (void**) &func)) {
+      g_slist_free(parents);
+      return func;
+    }
+  }
+
+  g_slist_free(parents);
+  return NULL;
+
+}
+
+/**
+ * g_object_info_get_ref_function:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain the symbol name of the function that should be called to ref this
+ * object type. It's mainly used fundamental types. The type signature for
+ * the symbol is %GIObjectInfoRefFunction, to fetch the function pointer
+ * see g_object_info_get_ref_function().
+ *
+ * Returns: the symbol or %NULL
+ */
+const char *
+g_object_info_get_ref_function (GIObjectInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob;
+
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (blob->ref_func)
+    return g_typelib_get_string (rinfo->typelib, blob->ref_func);
+
+  return NULL;
+}
+
+/**
+ * g_object_info_get_ref_function_pointer:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain a pointer to a function which can be used to
+ * increase the reference count an instance of this object type.
+ * This takes derivation into account and will reversely traverse
+ * the base classes of this type, starting at the top type.
+ *
+ * Returns: the function pointer or %NULL
+ */
+GIObjectInfoRefFunction
+g_object_info_get_ref_function_pointer (GIObjectInfo *info)
+{
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  return (GIObjectInfoRefFunction)_get_func(info, (SymbolGetter)g_object_info_get_ref_function);
+}
+
+/**
+ * g_object_info_get_unref_function:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain the symbol name of the function that should be called to unref this
+ * object type. It's mainly used fundamental types. The type signature for
+ * the symbol is %GIObjectInfoUnrefFunction, to fetch the function pointer
+ * see g_object_info_get_unref_function().
+ *
+ * Returns: the symbol or %NULL
+ */
+const char *
+g_object_info_get_unref_function (GIObjectInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob;
+
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (blob->unref_func)
+    return g_typelib_get_string (rinfo->typelib, blob->unref_func);
+
+  return NULL;
+}
+
+/**
+ * g_object_info_get_unref_function_pointer:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain a pointer to a function which can be used to
+ * decrease the reference count an instance of this object type.
+ * This takes derivation into account and will reversely traverse
+ * the base classes of this type, starting at the top type.
+ *
+ * Returns: the function pointer or %NULL
+ */
+GIObjectInfoUnrefFunction
+g_object_info_get_unref_function_pointer (GIObjectInfo *info)
+{
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  return (GIObjectInfoUnrefFunction)_get_func(info, (SymbolGetter)g_object_info_get_unref_function);
+}
+
+/**
+ * g_object_info_get_set_value_function:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain the symbol name of the function that should be called to convert
+ * set a GValue giving an object instance pointer of this object type.
+ * I's mainly used fundamental types. The type signature for the symbol
+ * is %GIObjectInfoSetValueFunction, to fetch the function pointer
+ * see g_object_info_get_set_value_function().
+ *
+ * Returns: the symbol or %NULL
+ */
+const char *
+g_object_info_get_set_value_function (GIObjectInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob;
+
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (blob->set_value_func)
+    return g_typelib_get_string (rinfo->typelib, blob->set_value_func);
+
+  return NULL;
+}
+
+/**
+ * g_object_info_get_set_value_function_pointer:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain a pointer to a function which can be used to
+ * set a GValue given an instance of this object type.
+ * This takes derivation into account and will reversely traverse
+ * the base classes of this type, starting at the top type.
+ *
+ * Returns: the function pointer or %NULL
+ */
+GIObjectInfoSetValueFunction
+g_object_info_get_set_value_function_pointer (GIObjectInfo *info)
+{
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  return (GIObjectInfoSetValueFunction)_get_func(info, (SymbolGetter)g_object_info_get_set_value_function);
+}
+
+/**
+ * g_object_info_get_get_value_function:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain the symbol name of the function that should be called to convert
+ * an object instance pointer of this object type to a GValue.
+ * I's mainly used fundamental types. The type signature for the symbol
+ * is %GIObjectInfoGetValueFunction, to fetch the function pointer
+ * see g_object_info_get_get_value_function().
+ *
+ * Returns: the symbol or %NULL
+ */
+const char *
+g_object_info_get_get_value_function (GIObjectInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob;
+
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (blob->get_value_func)
+    return g_typelib_get_string (rinfo->typelib, blob->get_value_func);
+
+  return NULL;
+}
+
+/**
+ * g_object_info_get_get_value_function_pointer:
+ * @info: a #GIObjectInfo
+ *
+ * Obtain a pointer to a function which can be used to
+ * extract an instance of this object type out of a GValue.
+ * This takes derivation into account and will reversely traverse
+ * the base classes of this type, starting at the top type.
+ *
+ * Returns: the function pointer or %NULL
+ */
+GIObjectInfoGetValueFunction
+g_object_info_get_get_value_function_pointer (GIObjectInfo *info)
+{
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
+
+  return (GIObjectInfoGetValueFunction)_get_func(info, (SymbolGetter)g_object_info_get_get_value_function);
+}
diff --git a/girepository/giobjectinfo.h b/girepository/giobjectinfo.h
index 27ec714..630def6 100644
--- a/girepository/giobjectinfo.h
+++ b/girepository/giobjectinfo.h
@@ -30,12 +30,52 @@
 
 G_BEGIN_DECLS
 
+/**
+ * GIObjectInfoRefFunction:
+ * @object: object instance pointer
+ *
+ * Increases the reference count of an object instance.
+ *
+ * Returns: the object instance
+ */
+typedef void * (*GIObjectInfoRefFunction) (void *object);
+
+/**
+ * GIObjectInfoUnrefFunction:
+ * @object: object instance pointer
+ *
+ * Decreases the reference count of an object instance.
+ *
+ */
+typedef void   (*GIObjectInfoUnrefFunction) (void *object);
+
+/**
+ * GIObjectInfoSetValueFunction:
+ * @value: a #GValue
+ * @object: object instance pointer
+ *
+ * Update @value and attach the object instance pointer @object to it.
+ *
+ */
+typedef void   (*GIObjectInfoSetValueFunction) (GValue *value, void *object);
+
+/**
+ * GIObjectInfoGetValueFunction:
+ * @value: a #GValue
+ *
+ * Extract an object instance out of @value
+ *
+ * Returns: the object instance
+ */
+typedef void * (*GIObjectInfoGetValueFunction) (const GValue *value);
+
 #define GI_IS_OBJECT_INFO(info) \
     (g_base_info_get_type((GIBaseInfo*)info) ==  GI_INFO_TYPE_OBJECT)
 
 const gchar *     g_object_info_get_type_name	 (GIObjectInfo *info);
 const gchar *     g_object_info_get_type_init	 (GIObjectInfo *info);
 gboolean          g_object_info_get_abstract     (GIObjectInfo *info);
+gboolean          g_object_info_get_fundamental  (GIObjectInfo *info);
 GIObjectInfo *    g_object_info_get_parent       (GIObjectInfo *info);
 gint              g_object_info_get_n_interfaces (GIObjectInfo *info);
 GIInterfaceInfo * g_object_info_get_interface    (GIObjectInfo *info,
@@ -64,6 +104,18 @@ GIConstantInfo *  g_object_info_get_constant     (GIObjectInfo *info,
 						  gint          n);
 GIStructInfo *    g_object_info_get_class_struct (GIObjectInfo *info);
 
+const char *                 g_object_info_get_ref_function               (GIObjectInfo *info);
+GIObjectInfoRefFunction      g_object_info_get_ref_function_pointer       (GIObjectInfo *info);
+
+const char *                 g_object_info_get_unref_function             (GIObjectInfo *info);
+GIObjectInfoUnrefFunction    g_object_info_get_unref_function_pointer     (GIObjectInfo *info);
+
+const char *                 g_object_info_get_set_value_function         (GIObjectInfo *info);
+GIObjectInfoSetValueFunction g_object_info_get_set_value_function_pointer (GIObjectInfo *info);
+
+const char *                 g_object_info_get_get_value_function         (GIObjectInfo *info);
+GIObjectInfoGetValueFunction g_object_info_get_get_value_function_pointer (GIObjectInfo *info);
+
 
 G_END_DECLS
 
diff --git a/girepository/giregisteredtypeinfo.h b/girepository/giregisteredtypeinfo.h
index f3c20fd..76a1ee2 100644
--- a/girepository/giregisteredtypeinfo.h
+++ b/girepository/giregisteredtypeinfo.h
@@ -38,7 +38,8 @@ G_BEGIN_DECLS
      (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \
      (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \
      (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \
-     (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION))
+     (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) || \
+     (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_BOXED))
 
 const gchar *          g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info);
 const gchar *          g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info);
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 576ac10..af24161 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -298,6 +298,10 @@ g_ir_node_free (GIrNode *node)
 	g_free (node->name);
 	g_free (iface->gtype_name);
 	g_free (iface->gtype_init);
+	g_free (iface->ref_func);
+	g_free (iface->unref_func);
+	g_free (iface->set_value_func);
+	g_free (iface->get_value_func);
 
 
 	g_free (iface->glib_type_struct);
@@ -692,6 +696,14 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
 	size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
 	if (iface->gtype_init)
 	  size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
+	if (iface->ref_func)
+	  size += ALIGN_VALUE (strlen (iface->ref_func) + 1, 4);
+	if (iface->unref_func)
+	  size += ALIGN_VALUE (strlen (iface->unref_func) + 1, 4);
+	if (iface->set_value_func)
+	  size += ALIGN_VALUE (strlen (iface->set_value_func) + 1, 4);
+	if (iface->get_value_func)
+	  size += ALIGN_VALUE (strlen (iface->get_value_func) + 1, 4);
 	size += 2 * (n + (n % 2));
 
 	for (l = iface->members; l; l = l->next)
@@ -2094,11 +2106,20 @@ g_ir_node_build_typelib (GIrNode         *node,
 
 	blob->blob_type = BLOB_TYPE_OBJECT;
 	blob->abstract = object->abstract;
+        blob->fundamental = object->fundamental;
 	blob->deprecated = object->deprecated;
 	blob->reserved = 0;
 	blob->name = write_string (node->name, strings, data, offset2);
 	blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
 	blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
+        if (object->ref_func)
+          blob->ref_func = write_string (object->ref_func, strings, data, offset2);
+        if (object->unref_func)
+          blob->unref_func = write_string (object->unref_func, strings, data, offset2);
+        if (object->set_value_func)
+          blob->set_value_func = write_string (object->set_value_func, strings, data, offset2);
+        if (object->get_value_func)
+          blob->get_value_func = write_string (object->get_value_func, strings, data, offset2);
 	if (object->parent)
 	  blob->parent = find_entry (module, modules, object->parent);
 	else
diff --git a/girepository/girnode.h b/girepository/girnode.h
index bd9acd0..dcd8fa4 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -244,10 +244,16 @@ struct _GIrNodeInterface
 
   gboolean abstract;
   gboolean deprecated;
+  gboolean fundamental;
 
   gchar *gtype_name;
   gchar *gtype_init;
 
+  gchar *ref_func;
+  gchar *unref_func;
+  gchar *set_value_func;
+  gchar *get_value_func;
+
   gchar *parent;
   gchar *glib_type_struct;
 
diff --git a/girepository/girparser.c b/girepository/girparser.c
index 678edcc..7796bea 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1640,6 +1640,11 @@ start_class (GMarkupParseContext *context,
   const gchar *typeinit;
   const gchar *deprecated;
   const gchar *abstract;
+  const gchar *fundamental;
+  const gchar *ref_func;
+  const gchar *unref_func;
+  const gchar *set_value_func;
+  const gchar *get_value_func;
   GIrNodeInterface *iface;
 
   if (!(strcmp (element_name, "class") == 0 &&
@@ -1656,6 +1661,11 @@ start_class (GMarkupParseContext *context,
   typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values);
   deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
   abstract = find_attribute ("abstract", attribute_names, attribute_values);
+  fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values);
+  ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values);
+  unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values);
+  set_value_func = find_attribute ("glib:set-value-func", attribute_names, attribute_values);
+  get_value_func = find_attribute ("glib:get-value-func", attribute_names, attribute_values);
 
   if (name == NULL)
     {
@@ -1686,6 +1696,15 @@ start_class (GMarkupParseContext *context,
 
   iface->abstract = abstract && strcmp (abstract, "1") == 0;
 
+  if (ref_func)
+    iface->ref_func = g_strdup (ref_func);
+  if (unref_func)
+    iface->unref_func = g_strdup (unref_func);
+  if (set_value_func)
+    iface->set_value_func = g_strdup (set_value_func);
+  if (get_value_func)
+    iface->get_value_func = g_strdup (get_value_func);
+
   push_node (ctx, (GIrNode *) iface);
   ctx->current_module->entries =
     g_list_append (ctx->current_module->entries, iface);
diff --git a/girepository/girwriter.c b/girepository/girwriter.c
index 19862b0..56d61b2 100644
--- a/girepository/girwriter.c
+++ b/girepository/girwriter.c
@@ -999,8 +999,10 @@ write_object_info (const gchar  *namespace,
   const gchar *name;
   const gchar *type_name;
   const gchar *type_init;
+  const gchar *func;
   gboolean deprecated;
   gboolean is_abstract;
+  gboolean is_fundamental;
   GIObjectInfo *pnode;
   GIStructInfo *class_struct;
   gint i;
@@ -1008,6 +1010,7 @@ write_object_info (const gchar  *namespace,
   name = g_base_info_get_name ((GIBaseInfo *)info);
   deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info);
   is_abstract = g_object_info_get_abstract (info);
+  is_fundamental = g_object_info_get_fundamental (info);
 
   type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info);
   type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info);
@@ -1033,6 +1036,25 @@ write_object_info (const gchar  *namespace,
 
   xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init);
 
+  if (is_fundamental)
+    xml_printf (file, " glib:fundamental=\"1\"");
+
+  func = g_object_info_get_unref_function (info);
+  if (func)
+    xml_printf (file, " glib:unref-function=\"%s\"", func);
+
+  func = g_object_info_get_ref_function (info);
+  if (func)
+    xml_printf (file, " glib:ref-function=\"%s\"", func);
+
+  func = g_object_info_get_set_value_function (info);
+  if (func)
+    xml_printf (file, " glib:set-value-function=\"%s\"", func);
+
+  func = g_object_info_get_get_value_function (info);
+  if (func)
+    xml_printf (file, " glib:get-value-function=\"%s\"", func);
+
   if (deprecated)
     xml_printf (file, " deprecated=\"1\"");
 
diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h
index d4577ac..981f7b4 100644
--- a/girepository/gitypelib-internal.h
+++ b/girepository/gitypelib-internal.h
@@ -72,6 +72,11 @@ G_BEGIN_DECLS
 /*
 TYPELIB HISTORY
 -----
+
+Version 1.1
+- Add ref/unref/set-value/get-value functions to Object, to be able
+  to support instantiatable fundamental types which are not GObject based.
+
 Version 1.0
 - Rename class_struct to gtype_struct, add to interfaces
 
@@ -918,6 +923,8 @@ typedef struct {
 /**
  * ObjectBlob:
  * @blob_type: #BLOB_TYPE_OBJECT
+ * @fundamental: this object is not a GObject derived type, instead it's
+ * an additional fundamental type.
  * @gtype_name: String name of the associated #GType
  * @gtype_init: String naming the symbol which gets the runtime #GType
  * @parent: The directory index of the parent type. This is only set for
@@ -938,12 +945,21 @@ typedef struct {
  * @signals: Describes the signals.
  * @vfuncs: Describes the virtual functions.
  * @constants: Describes the constants.
+ * @ref_func: String pointing to a function which can be called to increase
+ * the reference count for an instance of this object type.
+ * @unref_func: String pointing to a function which can be called to decrease
+ * the reference count for an instance of this object type.
+ * @set_value_func: String pointing to a function which can be called to
+ * convert a pointer of this object to a GValue
+ * @get_value_func: String pointing to a function which can be called to
+ * convert extract a pointer to this object from a GValue
  */
 typedef struct {
   guint16   blob_type;  /* 7 */
   guint16   deprecated   : 1;
   guint16   abstract     : 1;
-  guint16   reserved     :14;
+  guint16   fundamental  : 1;
+  guint16   reserved     :13;
   guint32   name;
 
   guint32   gtype_name;
@@ -961,6 +977,11 @@ typedef struct {
   guint16   n_constants;
   guint16   reserved2;
 
+  guint32   ref_func;
+  guint32   unref_func;
+  guint32   set_value_func;
+  guint32   get_value_func;
+
   guint32   reserved3;
   guint32   reserved4;
 
diff --git a/girepository/gitypelib.c b/girepository/gitypelib.c
index 6aa3077..74aa7ed 100644
--- a/girepository/gitypelib.c
+++ b/girepository/gitypelib.c
@@ -183,7 +183,7 @@ g_typelib_check_sanity (void)
   CHECK_SIZE (PropertyBlob, 16);
   CHECK_SIZE (SignalBlob, 16);
   CHECK_SIZE (VFuncBlob, 20);
-  CHECK_SIZE (ObjectBlob, 44);
+  CHECK_SIZE (ObjectBlob, 60);
   CHECK_SIZE (InterfaceBlob, 40);
   CHECK_SIZE (ConstantBlob, 24);
   CHECK_SIZE (AttributeBlob, 12);
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index 03ffb54..c642d56 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -52,6 +52,10 @@ TAG_ATTRIBUTES = 'attributes'
 TAG_RENAME_TO = 'rename to'
 TAG_TYPE = 'type'
 TAG_TRANSFER = 'transfer'
+TAG_UNREF_FUNC = 'unref func'
+TAG_REF_FUNC = 'ref func'
+TAG_SET_VALUE_FUNC = 'set value func'
+TAG_GET_VALUE_FUNC = 'get value func'
 
 # Options - annotations for parameters and return values
 OPT_ALLOW_NONE = 'allow-none'
@@ -361,6 +365,7 @@ class AnnotationApplier(object):
         self._parse_fields(class_, class_.fields)
         if block:
             class_.doc = block.comment
+        self._parse_type_instance_tags(class_, block)
 
     def _parse_interface(self, interface):
         block = self._blocks.get(interface.type_name)
@@ -911,6 +916,16 @@ class AnnotationApplier(object):
             if OPT_FOREIGN in block.options:
                 node.foreign = True
 
+    def _parse_type_instance_tags(self, node, block):
+        tag = self._get_tag(block, TAG_UNREF_FUNC)
+        node.unref_func = tag.value if tag else None
+        tag = self._get_tag(block, TAG_REF_FUNC)
+        node.ref_func = tag.value if tag else None
+        tag = self._get_tag(block, TAG_SET_VALUE_FUNC)
+        node.set_value_func = tag.value if tag else None
+        tag = self._get_tag(block, TAG_GET_VALUE_FUNC)
+        node.get_value_func = tag.value if tag else None
+
     def _parse_rename_to_func(self, node, block):
         rename_to_tag = self._get_tag(block, TAG_RENAME_TO)
         if rename_to_tag is None:
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 5e29d06..2e0a6cd 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -348,6 +348,17 @@ and/or use gtk-doc annotations. ''')
                 attrs.append(('glib:get-type', node.get_type))
             if node.glib_type_struct:
                 attrs.append(('glib:type-struct', node.glib_type_struct.name))
+        if isinstance(node, GLibObject):
+            if node.fundamental:
+                attrs.append(('glib:fundamental', '1'))
+            if node.ref_func:
+                attrs.append(('glib:ref-func', node.ref_func))
+            if node.unref_func:
+                attrs.append(('glib:unref-func', node.unref_func))
+            if node.set_value_func:
+                attrs.append(('glib:set-value-func', node.set_value_func))
+            if node.get_value_func:
+                attrs.append(('glib:get-value-func', node.get_value_func))
         with self.tagcontext(tag_name, attrs):
             self._write_generic(node)
             if isinstance(node, GLibObject):
diff --git a/giscanner/glibast.py b/giscanner/glibast.py
index fb1ef20..c712988 100644
--- a/giscanner/glibast.py
+++ b/giscanner/glibast.py
@@ -120,6 +120,11 @@ class GLibObject(Class):
         Class.__init__(self, name, parent, is_abstract)
         self.type_name = type_name
         self.get_type = get_type
+        self.fundamental = False
+        self.unref_func = None
+        self.ref_func = None
+        self.set_value_func = None
+        self.get_value_func = None
         self.signals = []
         self.ctype = ctype or type_name
 
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 3b088bc..1178c5f 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -689,6 +689,8 @@ class GLibTransformer(object):
             self._introspect_interface(xmlnode)
         elif xmlnode.tag == 'boxed':
             self._introspect_boxed(xmlnode)
+        elif xmlnode.tag == 'fundamental':
+            self._introspect_fundamental(xmlnode)
         else:
             raise ValueError("Unhandled introspection XML tag %s", xmlnode.tag)
 
@@ -808,6 +810,36 @@ class GLibTransformer(object):
             node.signals.append(signal)
         node.signals = sorted(node.signals)
 
+    def _introspect_fundamental(self, xmlnode):
+        # We only care about types that can be instantiatable, other
+        # fundamental types such as the Clutter.Fixed/CoglFixed registers
+        # are not yet interesting from an introspection perspective and
+        # are ignored
+        if not xmlnode.attrib.get('instantiatable', False):
+            return
+
+        type_name = xmlnode.attrib['name']
+
+        # Get a list of parents here; some of them may be hidden, and what
+        # we really want to do is use the most-derived one that we know of.
+        if 'parents' in xmlnode.attrib:
+            parent_type_names = xmlnode.attrib['parents'].split(',')
+            parent_gitype = self._resolve_gtypename_chain(parent_type_names)
+        else:
+            parent_gitype = None
+        is_abstract = bool(xmlnode.attrib.get('abstract', False))
+        node = GLibObject(
+            self._transformer.remove_prefix(type_name),
+            parent_gitype,
+            type_name,
+            xmlnode.attrib['get-type'], is_abstract)
+        node.fundamental = True
+        self._introspect_implemented_interfaces(node, xmlnode)
+
+        self._add_record_fields(node)
+        self._add_attribute(node, replace=True)
+        self._register_internal_type(type_name, node)
+
     def _add_record_fields(self, node):
         # add record fields
         record = self._get_attribute(node.name)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]