[libpeas] Override properties in PeasExtension subclasses



commit 811c61631ec1baec17e0bf31e1a54f33afe1b67b
Author: Garrett Regier <alias301 gmail com>
Date:   Sun Jan 16 12:53:51 2011 -0800

    Override properties in PeasExtension subclasses
    
    Generated subclasses do not override properties and this causes new
    versions of GObject to emit a critical warning.
    
    This also allows plugins to expose properties for setting and getting.

 configure.ac                                       |    1 +
 libpeas/Makefile.am                                |    1 +
 libpeas/peas-extension-priv.h                      |   36 ++++
 libpeas/peas-extension-subclasses.c                |   91 ++++++++++-
 libpeas/peas-extension.c                           |   19 ++-
 libpeas/peas-extension.h                           |    1 +
 loaders/c/peas-extension-c.c                       |    5 +-
 loaders/python/peas-extension-python.c             |    6 +-
 loaders/seed/peas-extension-seed.c                 |    5 +-
 tests/libpeas/extension.c                          |  127 +++++++++++++-
 tests/libpeas/introspection/Makefile.am            |    2 +
 .../introspection/introspection-properties.c       |   53 ++++++
 .../introspection/introspection-properties.h       |   52 ++++++
 tests/libpeas/plugins/Makefile.am                  |    2 +-
 tests/libpeas/plugins/properties/Makefile.am       |   19 ++
 .../libpeas/plugins/properties/properties-plugin.c |  184 ++++++++++++++++++++
 .../libpeas/plugins/properties/properties-plugin.h |   55 ++++++
 tests/libpeas/plugins/properties/properties.plugin |    8 +
 18 files changed, 652 insertions(+), 15 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a32fbe4..d3183f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -315,6 +315,7 @@ tests/Makefile
 tests/libpeas/Makefile
 tests/libpeas/plugins/Makefile
 tests/libpeas/plugins/callable/Makefile
+tests/libpeas/plugins/properties/Makefile
 tests/libpeas/introspection/Makefile
 tests/libpeas/testing/Makefile
 tests/libpeas-gtk/Makefile
diff --git a/libpeas/Makefile.am b/libpeas/Makefile.am
index f7c96db..0091087 100644
--- a/libpeas/Makefile.am
+++ b/libpeas/Makefile.am
@@ -29,6 +29,7 @@ INST_H_FILES =			\
 NOINST_H_FILES =			\
 	peas-debug.h			\
 	peas-dirs.h			\
+	peas-extension-priv.h		\
 	peas-extension-subclasses.h	\
 	peas-helpers.h			\
 	peas-i18n.h			\
diff --git a/libpeas/peas-extension-priv.h b/libpeas/peas-extension-priv.h
new file mode 100644
index 0000000..ee4416e
--- /dev/null
+++ b/libpeas/peas-extension-priv.h
@@ -0,0 +1,36 @@
+/*
+ * peas-extension-priv.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2010 - Steve Frécinaux
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PEAS_EXTENSION_PRIV_H__
+#define __PEAS_EXTENSION_PRIV_H__
+
+#include "peas-extension-priv.h"
+
+G_BEGIN_DECLS
+
+struct _PeasExtensionPrivate {
+  GType exten_type;
+  gboolean constructed;
+};
+
+G_END_DECLS
+
+#endif /* __PEAS_EXTENSION_PRIV_H__ */
diff --git a/libpeas/peas-extension-subclasses.c b/libpeas/peas-extension-subclasses.c
index f212148..761f65b 100644
--- a/libpeas/peas-extension-subclasses.c
+++ b/libpeas/peas-extension-subclasses.c
@@ -27,6 +27,7 @@
 #include <girepository.h>
 #include <girffi.h>
 #include "peas-extension.h"
+#include "peas-extension-priv.h"
 #include "peas-extension-subclasses.h"
 #include "peas-introspection.h"
 
@@ -228,9 +229,95 @@ implement_interface_methods (gpointer iface,
 }
 
 static void
-extension_subclass_init (GObjectClass *klass)
+extension_subclass_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
 {
+  PeasExtension *exten = PEAS_EXTENSION (object);
+  GIArgument args[2];
+  GIArgument return_value;
+
+  /* This will have already been set on the real instance */
+  if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) != 0)
+    return;
+
+  /* Setting will fail if we are not constructed yet */
+  if ((pspec->flags & G_PARAM_CONSTRUCT) != 0 && !exten->priv->constructed)
+    return;
+
+  g_debug ("Setting '%s:%s'",
+           G_OBJECT_TYPE_NAME (object),
+           g_param_spec_get_name (pspec));
+
+  args[0].v_string = (gchar *) g_param_spec_get_name (pspec);
+  args[1].v_pointer = (gpointer) value;
+
+  PEAS_EXTENSION_GET_CLASS (object)->call (exten,
+                                           G_TYPE_OBJECT,
+                                           "set_property",
+                                           args, &return_value);
+}
+
+static void
+extension_subclass_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  GIArgument args[2];
+  GIArgument return_value;
+
+  g_debug ("Getting '%s:%s'",
+           G_OBJECT_TYPE_NAME (object),
+           g_param_spec_get_name (pspec));
+
+  args[0].v_string = (gchar *) g_param_spec_get_name (pspec);
+  args[1].v_pointer = value;
+
+  PEAS_EXTENSION_GET_CLASS (object)->call (PEAS_EXTENSION (object),
+                                           G_TYPE_OBJECT,
+                                           "get_property",
+                                           args, &return_value);
+}
+
+static void
+extension_subclass_init (GObjectClass *klass,
+                         GType         exten_type)
+{
+  GIInterfaceInfo *iface_info;
+  gint n_props, i;
+
   g_debug ("Initializing class '%s'", G_OBJECT_CLASS_NAME (klass));
+
+  klass->set_property = extension_subclass_set_property;
+  klass->get_property = extension_subclass_get_property;
+
+  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_props = g_interface_info_get_n_properties (iface_info);
+
+  for (i = 0; i < n_props; ++i)
+    {
+      GIPropertyInfo *prop_info;
+
+      prop_info = g_interface_info_get_property (iface_info, i);
+
+      g_object_class_override_property (klass, i + 1,
+                                        g_base_info_get_name (prop_info));
+
+      g_debug ("Overrided '%s:%s' for '%s' proxy",
+               g_type_name (exten_type), g_base_info_get_name (prop_info),
+               G_OBJECT_CLASS_NAME (klass));
+
+      g_base_info_unref (prop_info);
+    }
+
+  g_base_info_unref (iface_info);
+
+  g_debug ("Initialized class '%s'", G_OBJECT_CLASS_NAME (klass));
 }
 
 static void
@@ -261,7 +348,7 @@ peas_extension_register_subclass (GType parent_type,
         (GBaseFinalizeFunc) NULL,
         (GClassInitFunc) extension_subclass_init,
         (GClassFinalizeFunc) NULL,
-        NULL,
+        GSIZE_TO_POINTER (extension_type),
         0,
         0,
         (GInstanceInitFunc) extension_subclass_instance_init
diff --git a/libpeas/peas-extension.c b/libpeas/peas-extension.c
index 261f56d..815ce08 100644
--- a/libpeas/peas-extension.c
+++ b/libpeas/peas-extension.c
@@ -24,6 +24,7 @@
 #endif
 
 #include "peas-extension.h"
+#include "peas-extension-priv.h"
 #include "peas-introspection.h"
 
 /**
@@ -69,10 +70,6 @@ enum {
   PROP_EXTENSION_TYPE
 };
 
-struct _PeasExtensionPrivate {
-  GType exten_type;
-};
-
 static void
 peas_extension_init (PeasExtension *exten)
 {
@@ -120,12 +117,24 @@ peas_extension_get_property (GObject    *object,
 }
 
 static void
+peas_extension_constructed (GObject *object)
+{
+  PeasExtension *exten = PEAS_EXTENSION (object);
+
+  exten->priv->constructed = TRUE;
+
+  if (G_OBJECT_CLASS (peas_extension_parent_class)->constructed != NULL)
+    G_OBJECT_CLASS (peas_extension_parent_class)->constructed (object);
+}
+
+static void
 peas_extension_class_init (PeasExtensionClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->set_property = peas_extension_set_property;
   object_class->get_property = peas_extension_get_property;
+  object_class->constructed = peas_extension_constructed;
 
   g_object_class_install_property (object_class, PROP_EXTENSION_TYPE,
                                    g_param_spec_gtype ("extension-type",
@@ -255,5 +264,5 @@ peas_extension_callv (PeasExtension *exten,
   g_return_val_if_fail (method_name != NULL, FALSE);
 
   klass = PEAS_EXTENSION_GET_CLASS (exten);
-  return klass->call (exten, method_name, args, return_value);
+  return klass->call (exten, G_TYPE_INVALID, method_name, args, return_value);
 }
diff --git a/libpeas/peas-extension.h b/libpeas/peas-extension.h
index d47639e..588ccb9 100644
--- a/libpeas/peas-extension.h
+++ b/libpeas/peas-extension.h
@@ -66,6 +66,7 @@ struct _PeasExtensionClass {
 
   /*< private >*/
   gboolean   (*call)                      (PeasExtension  *exten,
+                                           GType           gtype,
                                            const gchar    *method,
                                            GIArgument     *args,
                                            GIArgument     *return_value);
diff --git a/loaders/c/peas-extension-c.c b/loaders/c/peas-extension-c.c
index 1f628fe..3cc8ab9 100644
--- a/loaders/c/peas-extension-c.c
+++ b/loaders/c/peas-extension-c.c
@@ -37,14 +37,15 @@ peas_extension_c_init (PeasExtensionC *cexten)
 
 static gboolean
 peas_extension_c_call (PeasExtension *exten,
+                       GType          gtype,
                        const gchar   *method_name,
                        GIArgument    *args,
                        GIArgument    *retval)
 {
   PeasExtensionC *cexten = PEAS_EXTENSION_C (exten);
-  GType gtype;
 
-  gtype = peas_extension_get_extension_type (exten);
+  if (gtype == G_TYPE_INVALID)
+    gtype = peas_extension_get_extension_type (exten);
 
   return peas_method_apply (cexten->instance, gtype, method_name, args, retval);
 }
diff --git a/loaders/python/peas-extension-python.c b/loaders/python/peas-extension-python.c
index 461b864..3ae10b5 100644
--- a/loaders/python/peas-extension-python.c
+++ b/loaders/python/peas-extension-python.c
@@ -42,15 +42,17 @@ peas_extension_python_init (PeasExtensionPython *pyexten)
 
 static gboolean
 peas_extension_python_call (PeasExtension *exten,
+                            GType          gtype,
                             const gchar   *method_name,
                             GIArgument    *args,
                             GIArgument    *retval)
 {
   PeasExtensionPython *pyexten = PEAS_EXTENSION_PYTHON (exten);
-  GType gtype;
   GObject *instance;
 
-  gtype = peas_extension_get_extension_type (exten);
+  if (gtype == G_TYPE_INVALID)
+    gtype = peas_extension_get_extension_type (exten);
+
   instance = pygobject_get (pyexten->instance);
 
   return peas_method_apply (instance, gtype, method_name, args, retval);
diff --git a/loaders/seed/peas-extension-seed.c b/loaders/seed/peas-extension-seed.c
index 16c58f4..cbe0a51 100644
--- a/loaders/seed/peas-extension-seed.c
+++ b/loaders/seed/peas-extension-seed.c
@@ -226,12 +226,12 @@ set_return_value (OutArg        *arg,
 
 static gboolean
 peas_extension_seed_call (PeasExtension *exten,
+                          GType          exten_type,
                           const gchar   *method_name,
                           GIArgument    *args,
                           GIArgument    *retval)
 {
   PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (exten);
-  GType exten_type;
   SeedValue js_method;
   GICallableInfo *func_info;
   GITypeInfo *retval_info;
@@ -246,7 +246,8 @@ peas_extension_seed_call (PeasExtension *exten,
   g_return_val_if_fail (sexten->js_context != NULL, FALSE);
   g_return_val_if_fail (sexten->js_object != NULL, FALSE);
 
-  exten_type = peas_extension_get_extension_type (exten);
+  if (exten_type == G_TYPE_INVALID)
+    exten_type = peas_extension_get_extension_type (exten);
 
   /* Fetch the JS method we want to call */
   js_method = seed_object_get_property (sexten->js_context,
diff --git a/tests/libpeas/extension.c b/tests/libpeas/extension.c
index 4e6d969..d2ae6c9 100644
--- a/tests/libpeas/extension.c
+++ b/tests/libpeas/extension.c
@@ -31,6 +31,7 @@
 #include "testing/testing.h"
 
 #include "introspection/introspection-callable.h"
+#include "introspection/introspection-properties.h"
 #include "introspection/introspection-unimplemented.h"
 
 typedef struct _TestFixture TestFixture;
@@ -103,7 +104,7 @@ test_extension_create_invalid (PeasEngine *engine)
   /* Resident modules cause this to fail?
   g_test_trap_assert_failed ();*/
 
-  peas_engine_load_plugin (engine, info);
+  g_assert (peas_engine_load_plugin (engine, info));
 
   /* Invalid GType */
   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
@@ -132,6 +133,125 @@ test_extension_create_invalid (PeasEngine *engine)
 }
 
 static void
+test_extension_properties_construct_only (PeasEngine *engine)
+{
+  PeasPluginInfo *info;
+  PeasExtension *extension;
+  gchar *construct_only;
+
+  info = peas_engine_get_plugin_info (engine, "properties");
+
+  g_assert (peas_engine_load_plugin (engine, info));
+
+  extension = peas_engine_create_extension (engine, info,
+                                            INTROSPECTION_TYPE_PROPERTIES,
+                                            "construct-only", "my-construct-only",
+                                            NULL);
+
+
+  g_object_get (extension, "construct-only", &construct_only, NULL);
+  g_assert_cmpstr (construct_only, ==, "my-construct-only");
+  g_free (construct_only);
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+    {
+      g_object_set (extension, "construct-only", "other-construct-only", NULL);
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*WARNING*");
+
+  g_object_unref (extension);
+}
+
+static void
+test_extension_properties_read_only (PeasEngine *engine)
+{
+  PeasPluginInfo *info;
+  PeasExtension *extension;
+  gchar *read_only;
+
+  info = peas_engine_get_plugin_info (engine, "properties");
+
+  g_assert (peas_engine_load_plugin (engine, info));
+
+  extension = peas_engine_create_extension (engine, info,
+                                            INTROSPECTION_TYPE_PROPERTIES,
+                                            NULL);
+
+  g_object_get (extension, "read-only", &read_only, NULL);
+  g_assert_cmpstr (read_only, ==, "read-only");
+  g_free (read_only);
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+    {
+      g_object_set (extension, "read-only", "my-read-only", NULL);
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*WARNING*");
+
+  g_object_unref (extension);
+}
+
+static void
+test_extension_properties_write_only (PeasEngine *engine)
+{
+  PeasPluginInfo *info;
+  PeasExtension *extension;
+
+  info = peas_engine_get_plugin_info (engine, "properties");
+
+  g_assert (peas_engine_load_plugin (engine, info));
+
+  extension = peas_engine_create_extension (engine, info,
+                                            INTROSPECTION_TYPE_PROPERTIES,
+                                            NULL);
+
+  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+    {
+      gchar *write_only = NULL;
+
+      g_object_get (extension, "write-only", &write_only, NULL);
+      exit (0);
+    }
+  g_test_trap_assert_failed ();
+  g_test_trap_assert_stderr ("*WARNING*");
+
+  g_object_set (extension, "write-only", "my-write-only", NULL);
+
+  g_object_unref (extension);
+}
+
+static void
+test_extension_properties_readwrite (PeasEngine *engine)
+{
+  PeasPluginInfo *info;
+  PeasExtension *extension;
+  gchar *readwrite;
+
+  info = peas_engine_get_plugin_info (engine, "properties");
+
+  g_assert (peas_engine_load_plugin (engine, info));
+
+  extension = peas_engine_create_extension (engine, info,
+                                            INTROSPECTION_TYPE_PROPERTIES,
+                                            NULL);
+
+  g_object_get (extension, "readwrite", &readwrite, NULL);
+  g_assert_cmpstr (readwrite, ==, "readwrite");
+  g_free (readwrite);
+
+  g_object_set (extension, "readwrite", "my-readwrite", NULL);
+
+  g_object_get (extension, "readwrite", &readwrite, NULL);
+  g_assert_cmpstr (readwrite, ==, "my-readwrite");
+  g_free (readwrite);
+
+  g_object_unref (extension);
+}
+
+static void
 test_extension_call_invalid (PeasEngine *engine)
 {
   PeasPluginInfo *info;
@@ -267,6 +387,11 @@ main (int    argc,
   TEST ("create-valid", create_valid);
   TEST ("create-invalid", create_invalid);
 
+  TEST ("properties-construct-only", properties_construct_only);
+  TEST ("properties-read-only", properties_read_only);
+  TEST ("properties-write-only", properties_write_only);
+  TEST ("properties-readwrite", properties_readwrite);
+
   TEST ("call-invalid", call_invalid);
   TEST ("call-no-args", call_no_args);
   TEST ("call-with-return", call_with_return);
diff --git a/tests/libpeas/introspection/Makefile.am b/tests/libpeas/introspection/Makefile.am
index e10e4b7..47e5ac0 100644
--- a/tests/libpeas/introspection/Makefile.am
+++ b/tests/libpeas/introspection/Makefile.am
@@ -19,6 +19,8 @@ libintrospection_1_0_la_LIBADD = \
 libintrospection_1_0_la_SOURCES = \
 	introspection-callable.c	\
 	introspection-callable.h	\
+	introspection-properties.c	\
+	introspection-properties.h	\
 	introspection-unimplemented.c	\
 	introspection-unimplemented.h
 
diff --git a/tests/libpeas/introspection/introspection-properties.c b/tests/libpeas/introspection/introspection-properties.c
new file mode 100644
index 0000000..f6f3dda
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-properties.c
@@ -0,0 +1,53 @@
+/*
+ * introspection-properties.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2010 Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "introspection-properties.h"
+
+G_DEFINE_INTERFACE(IntrospectionProperties, introspection_properties, G_TYPE_OBJECT)
+
+void
+introspection_properties_default_init (IntrospectionPropertiesInterface *iface)
+{
+  static gboolean initialized = FALSE;
+
+#define DEFINE_PROP(name, flags) \
+  g_object_interface_install_property (iface, \
+                                       g_param_spec_string (name, name, \
+                                                            name, name, \
+                                                            G_PARAM_STATIC_STRINGS | \
+                                                            (flags)))
+
+  if (!initialized)
+    {
+      DEFINE_PROP ("construct-only", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+      DEFINE_PROP ("read-only", G_PARAM_READABLE);
+      DEFINE_PROP ("write-only", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT);
+      DEFINE_PROP ("readwrite", G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+      initialized = TRUE;
+    }
+
+#undef DEFINE_PROP
+}
diff --git a/tests/libpeas/introspection/introspection-properties.h b/tests/libpeas/introspection/introspection-properties.h
new file mode 100644
index 0000000..a4e0ac8
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-properties.h
@@ -0,0 +1,52 @@
+/*
+ * introspection-properties.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2010 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __INTROSPECTION_PROPERTIES_H__
+#define __INTROSPECTION_PROPERTIES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define INTROSPECTION_TYPE_PROPERTIES             (introspection_properties_get_type ())
+#define INTROSPECTION_PROPERTIES(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), INTROSPECTION_TYPE_PROPERTIES, IntrospectionProperties))
+#define INTROSPECTION_PROPERTIES_IFACE(obj)       (G_TYPE_CHECK_CLASS_CAST ((obj), INTROSPECTION_TYPE_PROPERTIES, IntrospectionPropertiesInterface))
+#define INTROSPECTION_IS_PROPERTIES(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INTROSPECTION_TYPE_PROPERTIES))
+#define INTROSPECTION_PROPERTIES_GET_IFACE(obj)   (G_TYPE_INSTANCE_GET_INTERFACE ((obj), INTROSPECTION_TYPE_PROPERTIES, IntrospectionPropertiesInterface))
+
+typedef struct _IntrospectionProperties           IntrospectionProperties; /* dummy typedef */
+typedef struct _IntrospectionPropertiesInterface  IntrospectionPropertiesInterface;
+
+struct _IntrospectionPropertiesInterface {
+  GTypeInterface g_iface;
+};
+
+/*
+ * Public methods
+ */
+GType introspection_properties_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __INTROSPECTION_PROPERTIES_H__ */
diff --git a/tests/libpeas/plugins/Makefile.am b/tests/libpeas/plugins/Makefile.am
index a0435ac..b3d0c9d 100644
--- a/tests/libpeas/plugins/Makefile.am
+++ b/tests/libpeas/plugins/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = callable
+SUBDIRS = callable properties
 
 noinst_DATA = \
 	info-missing-iage.plugin	\
diff --git a/tests/libpeas/plugins/properties/Makefile.am b/tests/libpeas/plugins/properties/Makefile.am
new file mode 100644
index 0000000..d80bcb3
--- /dev/null
+++ b/tests/libpeas/plugins/properties/Makefile.am
@@ -0,0 +1,19 @@
+INCLUDES = \
+	-I$(top_srcdir)		\
+	-I$(srcdir)/../../introspection	\
+	$(PEAS_CFLAGS)		\
+	$(WARN_CFLAGS)		\
+	$(DISABLE_DEPRECATED)
+
+noinst_LTLIBRARIES = libproperties.la
+
+libproperties_la_SOURCES = \
+	properties-plugin.c	\
+	properties-plugin.h
+
+libproperties_la_LDFLAGS = $(TEST_PLUGIN_LIBTOOL_FLAGS)
+libproperties_la_LIBADD  = $(PEAS_LIBS)
+
+noinst_DATA = properties.plugin
+
+EXTRA_DIST = $(noinst_DATA)
diff --git a/tests/libpeas/plugins/properties/properties-plugin.c b/tests/libpeas/plugins/properties/properties-plugin.c
new file mode 100644
index 0000000..727d0d2
--- /dev/null
+++ b/tests/libpeas/plugins/properties/properties-plugin.c
@@ -0,0 +1,184 @@
+/*
+ * properties-plugin.c
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2010 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmodule.h>
+
+#include <libpeas/peas.h>
+
+#include "introspection-properties.h"
+
+#include "properties-plugin.h"
+
+struct _TestingPropertiesPluginPrivate {
+  gchar *construct_only;
+  gchar *readwrite;
+};
+
+static void introspection_properties_iface_init (IntrospectionPropertiesInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (TestingPropertiesPlugin,
+                                testing_properties_plugin,
+                                PEAS_TYPE_EXTENSION_BASE,
+                                0,
+                                G_IMPLEMENT_INTERFACE_DYNAMIC (INTROSPECTION_TYPE_PROPERTIES,
+                                                               introspection_properties_iface_init))
+
+/* Properties */
+enum {
+  PROP_0,
+  PROP_CONSTRUCT_ONLY,
+  PROP_READ_ONLY,
+  PROP_WRITE_ONLY,
+  PROP_READWRITE
+};
+
+static void
+testing_properties_plugin_init (TestingPropertiesPlugin *plugin)
+{
+  plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin,
+                                              TESTING_TYPE_PROPERTIES_PLUGIN,
+                                              TestingPropertiesPluginPrivate);
+}
+
+static void
+testing_properties_plugin_set_property (GObject      *object,
+                                        guint         prop_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+  TestingPropertiesPlugin *plugin = TESTING_PROPERTIES_PLUGIN (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONSTRUCT_ONLY:
+      if (plugin->priv->construct_only != NULL)
+        g_free (plugin->priv->construct_only);
+
+      plugin->priv->construct_only = g_value_dup_string (value);
+      break;
+
+    case PROP_WRITE_ONLY:
+      /* Don't bother doing anything */
+      break;
+
+    case PROP_READWRITE:
+      if (plugin->priv->readwrite != NULL)
+        g_free (plugin->priv->readwrite);
+
+      plugin->priv->readwrite = g_value_dup_string (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+testing_properties_plugin_get_property (GObject    *object,
+                                        guint       prop_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  TestingPropertiesPlugin *plugin = TESTING_PROPERTIES_PLUGIN (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONSTRUCT_ONLY:
+      g_value_set_string (value, plugin->priv->construct_only);
+      break;
+
+    case PROP_READ_ONLY:
+      g_value_set_string (value, "read-only");
+      break;
+
+    case PROP_READWRITE:
+      g_value_set_string (value, plugin->priv->readwrite);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+testing_properties_plugin_dispose (GObject *object)
+{
+  TestingPropertiesPlugin *plugin = TESTING_PROPERTIES_PLUGIN (object);
+
+  if (plugin->priv->construct_only != NULL)
+    {
+      g_free (plugin->priv->construct_only);
+      plugin->priv->construct_only = NULL;
+    }
+
+  if (plugin->priv->readwrite != NULL)
+    {
+      g_free (plugin->priv->readwrite);
+      plugin->priv->readwrite = NULL;
+    }
+
+  G_OBJECT_CLASS (testing_properties_plugin_parent_class)->dispose (object);
+}
+
+static void
+testing_properties_plugin_class_init (TestingPropertiesPluginClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->set_property = testing_properties_plugin_set_property;
+  object_class->get_property = testing_properties_plugin_get_property;
+  object_class->dispose = testing_properties_plugin_dispose;
+
+  g_object_class_override_property (object_class, PROP_CONSTRUCT_ONLY, "construct-only");
+  g_object_class_override_property (object_class, PROP_READ_ONLY, "read-only");
+  g_object_class_override_property (object_class, PROP_WRITE_ONLY, "write-only");
+  g_object_class_override_property (object_class, PROP_READWRITE, "readwrite");
+
+  g_type_class_add_private (klass, sizeof (TestingPropertiesPluginPrivate));
+}
+
+static void
+introspection_properties_iface_init (IntrospectionPropertiesInterface *iface)
+{
+}
+
+static void
+testing_properties_plugin_class_finalize (TestingPropertiesPluginClass *klass)
+{
+}
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+  testing_properties_plugin_register_type (G_TYPE_MODULE (module));
+
+  peas_object_module_register_extension_type (module,
+                                              INTROSPECTION_TYPE_PROPERTIES,
+                                              TESTING_TYPE_PROPERTIES_PLUGIN);
+}
diff --git a/tests/libpeas/plugins/properties/properties-plugin.h b/tests/libpeas/plugins/properties/properties-plugin.h
new file mode 100644
index 0000000..5f5a477
--- /dev/null
+++ b/tests/libpeas/plugins/properties/properties-plugin.h
@@ -0,0 +1,55 @@
+/*
+ * properties-plugin.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2010 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __TESTING_PROPERTIES_PLUGIN_H__
+#define __TESTING_PROPERTIES_PLUGIN_H__
+
+#include <libpeas/peas.h>
+
+G_BEGIN_DECLS
+
+#define TESTING_TYPE_PROPERTIES_PLUGIN         (testing_properties_plugin_get_type ())
+#define TESTING_PROPERTIES_PLUGIN(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TESTING_TYPE_PROPERTIES_PLUGIN, TestingPropertiesPlugin))
+#define TESTING_PROPERTIES_PLUGIN_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), TESTING_TYPE_PROPERTIES_PLUGIN, TestingPropertiesPlugin))
+#define TESTING_IS_PROPERTIES_PLUGIN(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TESTING_TYPE_PROPERTIES_PLUGIN))
+#define TESTING_IS_PROPERTIES_PLUGIN_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TESTING_TYPE_PROPERTIES_PLUGIN))
+#define TESTING_PROPERTIES_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TESTING_TYPE_PROPERTIES_PLUGIN, TestingPropertiesPluginClass))
+
+typedef struct _TestingPropertiesPlugin         TestingPropertiesPlugin;
+typedef struct _TestingPropertiesPluginClass    TestingPropertiesPluginClass;
+typedef struct _TestingPropertiesPluginPrivate  TestingPropertiesPluginPrivate;
+
+struct _TestingPropertiesPlugin {
+  PeasExtensionBase parent_instance;
+
+  TestingPropertiesPluginPrivate *priv;
+};
+
+struct _TestingPropertiesPluginClass {
+  PeasExtensionBaseClass parent_class;
+};
+
+GType                 testing_properties_plugin_get_type (void) G_GNUC_CONST;
+G_MODULE_EXPORT void  peas_register_types                (PeasObjectModule *module);
+
+G_END_DECLS
+
+#endif /* __TESTING_PROPERTIES_PLUGIN_H__ */
diff --git a/tests/libpeas/plugins/properties/properties.plugin b/tests/libpeas/plugins/properties/properties.plugin
new file mode 100644
index 0000000..bcfced4
--- /dev/null
+++ b/tests/libpeas/plugins/properties/properties.plugin
@@ -0,0 +1,8 @@
+[Plugin]
+Module=properties
+IAge=2
+Name=Properties
+Description=This plugin can be loaded and has properties.
+Authors=Garrett Regier
+Copyright=Copyright © 2010 Garrett Regier
+Website=http://live.gnome.org/Libpeas



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