Imported Upstream version 2.41.2 upstream/2.41.2
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 06:47:01 +0000 (23:47 -0700)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 7 Sep 2020 06:47:01 +0000 (23:47 -0700)
23 files changed:
NEWS
configure.ac
gio/giomm.h
gio/src/filelist.am
gio/src/gio_signals.defs
gio/src/gio_vfuncs.defs
gio/src/menu.hg
gio/src/permission.ccg [new file with mode: 0644]
gio/src/permission.hg [new file with mode: 0644]
gio/src/simplepermission.ccg [new file with mode: 0644]
gio/src/simplepermission.hg [new file with mode: 0644]
glib/glibmm/class.cc
glib/glibmm/class.h
glib/glibmm/interface.cc
glib/glibmm/property.cc
tools/extra_defs_gen/generate_defs_gio.cc
tools/extra_defs_gen/generate_extra_defs.cc
tools/extra_defs_gen/generate_extra_defs.h
tools/pm/Function.pm
tools/pm/GtkDefs.pm
tools/pm/Output.pm
tools/pm/Property.pm
tools/pm/WrapParser.pm

diff --git a/NEWS b/NEWS
index ddc72a0..45abaec 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,24 @@
+2.41.2 (unstable):
+
+Gio:
+* Menu: Allow detailed_action == null
+  (Kjell Ahlstedt) Bug #733203 (Hubert Figuiere)
+* Add Permission and SimplePermission.
+  (Juan R. García Blanco) Bug #732436
+
+Glib:
+* Make custom interface properties instance data.
+  (Kjell Ahlstedt) Bug #732746
+* PropertyBase: Use g_object_notify_by_pspec() instead of g_object_notify()
+  (Povilas Kanapickas) Bug #731484
+
+gmmproc:
+* Add support for GtkContainer child properties.
+  (Juan R. García Blanco)
+*  _WRAP_METHOD: Allow multi-word parameter types such as unsigned int.
+  (Kjell Ahlstedt)
+
+
 2.41.1 (unstable):
 
 Gio:
index e2f48ae..d7f6851 100644 (file)
@@ -15,7 +15,7 @@
 ## You should have received a copy of the GNU Lesser General Public License
 ## along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_INIT([glibmm], [2.41.1],
+AC_INIT([glibmm], [2.41.2],
         [http://bugzilla.gnome.org/enter_bug.cgi?product=glibmm],
         [glibmm], [http://www.gtkmm.org/])
 AC_PREREQ([2.59])
index 1199a2f..a618251 100644 (file)
 #include <giomm/networkservice.h>
 #include <giomm/notification.h>
 #include <giomm/outputstream.h>
+#include <giomm/permission.h>
 #include <giomm/pollableinputstream.h>
 #include <giomm/pollableoutputstream.h>
 #include <giomm/proxy.h>
 #include <giomm/settings.h>
 #include <giomm/simpleaction.h>
 #include <giomm/simpleactiongroup.h>
+#include <giomm/simplepermission.h>
 #include <giomm/socket.h>
 #include <giomm/socketaddress.h>
 #include <giomm/socketaddressenumerator.h>
index e2a545f..8ce9dd5 100644 (file)
@@ -90,6 +90,7 @@ giomm_files_any_hg =                  \
        networkservice.hg               \
        notification.hg         \
        outputstream.hg                 \
+       permission.hg           \
        pollableinputstream.hg          \
        pollableoutputstream.hg         \
        proxy.hg                        \
@@ -102,6 +103,7 @@ giomm_files_any_hg =                        \
        settings.hg                     \
        simpleaction.hg                 \
        simpleactiongroup.hg            \
+       simplepermission.hg             \
        socket.hg                       \
        socketaddress.hg                \
        socketaddressenumerator.hg      \
index ea5828a..337577c 100644 (file)
 
 ;; From GNotification
 
+;; From GPermission
+
+(define-property allowed
+  (of-object "GPermission")
+  (prop-type "GParamBoolean")
+  (docs "If the caller is allowed to perform the action")
+  (readable #t)
+  (writable #f)
+  (construct-only #f)
+)
+
+(define-property can-acquire
+  (of-object "GPermission")
+  (prop-type "GParamBoolean")
+  (docs "If calling g_permission_acquire() makes sense")
+  (readable #t)
+  (writable #f)
+  (construct-only #f)
+)
+
+(define-property can-release
+  (of-object "GPermission")
+  (prop-type "GParamBoolean")
+  (docs "If calling g_permission_release() makes sense")
+  (readable #t)
+  (writable #f)
+  (construct-only #f)
+)
+
 ;; From GPropertyAction
 
 (define-property name
index 1917d6c..e9792a9 100644 (file)
   '("GMount*" "mount")
  )
 )
+
+; GPermission
+
+(define-vfunc acquire
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+  '("GCancellable*" "cancellable")
+  '("GError**" "error")
+ )
+)
+
+(define-vfunc acquire_async
+ (of-object "GPermission")
+ (return-type "void")
+ (parameters
+  '("GCancellable*" "cancellable")
+  '("GAsyncReadyCallback" "callback")
+  '("gpointer" "user_data")
+ )
+)
+
+(define-vfunc acquire_finish
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+  '("GAsyncResult*" "result")
+  '("GError**" "error")
+ )
+)
+
+(define-vfunc release
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+  '("GCancellable*" "cancellable")
+  '("GError**" "error")
+ )
+)
+
+(define-vfunc release_async
+ (of-object "GPermission")
+ (return-type "void")
+ (parameters
+  '("GCancellable*" "cancellable")
+  '("GAsyncReadyCallback" "callback")
+  '("gpointer" "user_data")
+ )
+)
+
+(define-vfunc release_finish
+ (of-object "GPermission")
+ (return-type "gboolean")
+ (parameters
+  '("GAsyncResult*" "result")
+  '("GError**" "error")
+ )
+)
index 69ae591..ad129a9 100644 (file)
@@ -55,11 +55,13 @@ public:
   _WRAP_METHOD(void remove(int position), g_menu_remove)
   _WRAP_METHOD(void remove_all(), g_menu_remove_all)
 
-//TODO: Allow label to be null. But when would that be useful?
+// The glib docs says that label can be null in all insert/prepend/append functions.
+// But except in the xxx_section() functions, a null label results in a critical message,
+// and does not seem useful. See https://bugzilla.gnome.org/show_bug.cgi?id=733203
 //We don't return the MenuItem* because the C API can't give us something modifiable: See https://bugzilla.gnome.org/show_bug.cgi?id=708906
-  _WRAP_METHOD(void insert(int position, const Glib::ustring& label, const Glib::ustring& detailed_action = Glib::ustring()), g_menu_insert)
-  _WRAP_METHOD(void prepend(const Glib::ustring& label, const Glib::ustring& detailed_action = Glib::ustring()), g_menu_prepend)
-  _WRAP_METHOD(void append(const Glib::ustring& label, const Glib::ustring& detailed_action = Glib::ustring()), g_menu_append)
+  _WRAP_METHOD(void insert(int position, const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_insert)
+  _WRAP_METHOD(void prepend(const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_prepend)
+  _WRAP_METHOD(void append(const Glib::ustring& label, const Glib::ustring& detailed_action{?}), g_menu_append)
 
   _WRAP_METHOD(void insert_section(int position, const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_insert_section)
   _WRAP_METHOD(void prepend_section(const Glib::ustring& label{?}, const Glib::RefPtr<MenuModel>& section), g_menu_prepend_section)
diff --git a/gio/src/permission.ccg b/gio/src/permission.ccg
new file mode 100644 (file)
index 0000000..c3debd2
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copyright (C) 2014 The giomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gio/gio.h>
+#include "slot_async.h"
+
+
+namespace Gio
+{
+} // namespace Gio
diff --git a/gio/src/permission.hg b/gio/src/permission.hg
new file mode 100644 (file)
index 0000000..6405ece
--- /dev/null
@@ -0,0 +1,91 @@
+/* Copyright (C) 2014 The giomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glibmm/object.h>
+#include <giomm/cancellable.h>
+#include <giomm/asyncresult.h>
+
+_DEFS(giomm,gio)
+_PINCLUDE(glibmm/private/object_p.h)
+_PINCLUDE(gio/gio.h)
+
+namespace Gio
+{
+
+/** An object representing the permission to perform a certain action.
+ *
+ * A Permission represents the status of the caller's permission to
+ * perform a certain action.
+ *
+ * You can query if the action is currently allowed and if it is
+ * possible to acquire the permission so that the action will be allowed
+ * in the future.
+ *
+ * There is also an API to actually acquire the permission and one to
+ * release it.
+ *
+ * As an example, a Permission might represent the ability for the
+ * user to write to a Settings object.  This Permission object could
+ * then be used to decide if it is appropriate to show a "Click here to
+ * unlock" button in a dialog and to provide the mechanism to invoke
+ * when that button is clicked.
+ *
+ * @newin{2,42}
+ */
+class Permission : public Glib::Object
+{
+  _CLASS_GOBJECT(Permission, GPermission, G_PERMISSION, Glib::Object, GObject)
+
+public:
+
+  _WRAP_METHOD(bool acquire(const Glib::RefPtr<Cancellable>& cancellable{?}), g_permission_acquire, errthrow)
+  _WRAP_METHOD(void acquire_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}), g_permission_acquire_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_METHOD(bool acquire_finish(const Glib::RefPtr<AsyncResult>& result), g_permission_acquire_finish, errthrow)
+
+  _WRAP_METHOD(bool release(const Glib::RefPtr<Cancellable>& cancellable{?}), g_permission_release, errthrow)
+  _WRAP_METHOD(void release_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.?}), g_permission_release_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_METHOD(bool release_finish(const Glib::RefPtr<AsyncResult>& result), g_permission_release_finish, errthrow)
+
+  _WRAP_METHOD(bool get_allowed() const, g_permission_get_allowed)
+  _WRAP_METHOD(bool get_can_acquire() const, g_permission_get_can_acquire)
+  _WRAP_METHOD(bool get_can_release() const, g_permission_get_can_release)
+
+  _WRAP_PROPERTY("allowed", bool)
+  _WRAP_PROPERTY("can-acquire", bool)
+  _WRAP_PROPERTY("can-release", bool)
+
+protected:
+
+  _CTOR_DEFAULT
+
+// A copy is needed for vfuncs, i.e. Glib::wrap($3, true)
+#m4 _CONVERSION(`GAsyncResult*',`const Glib::RefPtr<AsyncResult>&',`Glib::wrap($3, true)')
+#m4 _CONVERSION(`GCancellable*',`const Glib::RefPtr<Cancellable>&',`Glib::wrap($3, true)')
+
+  _WRAP_VFUNC(bool acquire(const Glib::RefPtr<Cancellable>& cancellable), acquire, errthrow)
+  _WRAP_VFUNC(void acquire_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}), acquire_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(bool acquire_finish(const Glib::RefPtr<AsyncResult>& result), acquire_finish, errthrow)
+
+  _WRAP_VFUNC(bool release(const Glib::RefPtr<Cancellable>& cancellable), release, errthrow)
+  _WRAP_VFUNC(void release_async(const SlotAsyncReady& slot{callback}, const Glib::RefPtr<Cancellable>& cancellable{.}), release_async, slot_name slot, slot_callback SignalProxy_async_callback)
+  _WRAP_VFUNC(bool release_finish(const Glib::RefPtr<AsyncResult>& result), release_finish, errthrow)
+
+  // You should never call this function except from a Gio::Permission implementation.
+  _WRAP_METHOD(void impl_update(bool allowed, bool can_acquire, bool can_release), g_permission_impl_update)
+};
+
+} // namespace Gio
diff --git a/gio/src/simplepermission.ccg b/gio/src/simplepermission.ccg
new file mode 100644 (file)
index 0000000..c22ac8b
--- /dev/null
@@ -0,0 +1,23 @@
+/* Copyright (C) 2014 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <gio/gio.h>
+
+
+namespace Gio
+{
+} // namespace Gio
diff --git a/gio/src/simplepermission.hg b/gio/src/simplepermission.hg
new file mode 100644 (file)
index 0000000..c6a2ea3
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (C) 2014 The giomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <giomm/permission.h>
+
+_DEFS(giomm,gio)
+_PINCLUDE(giomm/private/permission_p.h)
+
+namespace Gio
+{
+
+/** A Permission that doesn't change value.
+ *
+ * SimplePermission is a trivial implementation of Permission that
+ * represents a permission that is either always or never allowed.  The
+ * value is given at construction and doesn't change.
+ *
+ * Calling Permission::acquire() or Permission::release() will result
+ * in errors.
+ */
+class SimplePermission : public Permission
+{
+  _CLASS_GOBJECT(SimplePermission, GSimplePermission, G_SIMPLE_PERMISSION, Gio::Permission, GPermission)
+
+protected:
+
+  _WRAP_CTOR(SimplePermission(bool allowed), g_simple_permission_new)
+
+public:
+
+  _WRAP_CREATE(bool allowed)
+
+  // SimplePermission has no properties nor signals.
+};
+
+} // namespace Gio
index f68138b..217d02e 100644 (file)
@@ -150,19 +150,20 @@ GType Class::clone_custom_type(const char* custom_type_name,
 }
 
 // Initialize the static quark to store/get custom type properties.
-GQuark Class::properties_quark = g_quark_from_string("gtkmm_CustomObject_properties");
+GQuark Class::iface_properties_quark = g_quark_from_string("gtkmm_CustomObject_iface_properties");
 
 // static
 void Class::custom_class_base_finalize_function(void* g_class)
 {
   const GType gtype = G_TYPE_FROM_CLASS(g_class);
 
-  // Free the data related to the properties for the custom type, if any.
-  properties_type* props = static_cast<properties_type*>(g_type_get_qdata(gtype, properties_quark));
+  // Free the data related to the interface properties for the custom type, if any.
+  iface_properties_type* props = static_cast<iface_properties_type*>(
+    g_type_get_qdata(gtype, iface_properties_quark));
 
   if(props)
   {
-    for(properties_type::size_type i = 0; i < props->size(); i++)
+    for(iface_properties_type::size_type i = 0; i < props->size(); i++)
     {
       g_value_unset((*props)[i]);
       g_free((*props)[i]);
@@ -190,12 +191,12 @@ void Class::custom_class_init_function(void* g_class, void* class_data)
   // Override the properties of implemented interfaces, if any.
   const GType object_type = G_TYPE_FROM_CLASS(g_class);
 
-  Class::properties_type* props = static_cast<Class::properties_type*>(
-    g_type_get_qdata(object_type, Class::properties_quark));
+  Class::iface_properties_type* props = static_cast<Class::iface_properties_type*>(
+    g_type_get_qdata(object_type, Class::iface_properties_quark));
   if (!props)
   {
-    props = new Class::properties_type();
-    g_type_set_qdata(object_type, Class::properties_quark, props);
+    props = new Class::iface_properties_type();
+    g_type_set_qdata(object_type, Class::iface_properties_quark, props);
   }
 
   guint n_interfaces = 0;
@@ -213,10 +214,13 @@ void Class::custom_class_init_function(void* g_class, void* class_data)
       const gchar* prop_name = g_param_spec_get_name(iface_props[p]);
 
       // Override only properties which have not been overridden in a base class.
+      // Store the default values belonging to the class.
+      // They are copied to an object in custom_set_property_callback() in property.cc.
       if (!g_object_class_find_property(gobject_class, prop_name))
       {
         GValue* g_value = g_new0(GValue, 1);
         g_value_init(g_value, iface_props[p]->value_type);
+        g_param_value_set_default(iface_props[p], g_value);
         props->push_back(g_value);
 
         g_object_class_override_property(gobject_class, props->size(), prop_name);
index 438c3ca..89e9d34 100644 (file)
@@ -25,7 +25,7 @@
 #include <glib-object.h>
 #include <glibmmconfig.h> //Include this here so that the /private/*.h classes have access to GLIBMM_VFUNCS_ENABLED
 
-#include <vector> //For properties that custom types might override.
+#include <vector> //For interface properties that custom types might override.
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
@@ -101,10 +101,10 @@ private:
 
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-  // The type that holds the values of the properties of custom types.
-  typedef std::vector<GValue*> properties_type;
-  // The quark used for storing/getting the properties of custom types.
-  static GQuark properties_quark;
+  // The type that holds the values of the interface properties of custom types.
+  typedef std::vector<GValue*> iface_properties_type;
+  // The quark used for storing/getting the interface properties of custom types.
+  static GQuark iface_properties_quark;
 #endif
 };
 
index 19554ca..c849565 100644 (file)
@@ -66,13 +66,13 @@ Interface::Interface(const Interface_Class& interface_class)
         // Override the properties of the derived interface, if any.
 
         const GType custom_type = G_OBJECT_CLASS_TYPE(instance_class);
-        Class::properties_type* props = static_cast<Class::properties_type*>(
-          g_type_get_qdata(custom_type, Class::properties_quark));
+        Class::iface_properties_type* props = static_cast<Class::iface_properties_type*>(
+          g_type_get_qdata(custom_type, Class::iface_properties_quark));
 
         if(!props)
         {
-          props = new Class::properties_type();
-          g_type_set_qdata(custom_type, Class::properties_quark, props);
+          props = new Class::iface_properties_type();
+          g_type_set_qdata(custom_type, Class::iface_properties_quark, props);
         }
 
         const guint n_existing_props = props->size();
index 0ae0345..4cf054f 100644 (file)
@@ -98,6 +98,23 @@ Glib::PropertyBase& property_from_id(Glib::ObjectBase& object, unsigned int prop
   return *static_cast<Glib::PropertyBase*>(prop_ptr);
 }
 
+// Delete the interface property values when an object of a custom type is finalized.
+void destroy_notify_obj_iface_props(void* data)
+{
+  Glib::Class::iface_properties_type* obj_iface_props =
+    static_cast<Glib::Class::iface_properties_type*>(data);
+
+  if (obj_iface_props)
+  {
+    for (Glib::Class::iface_properties_type::size_type i = 0; i < obj_iface_props->size(); i++)
+    {
+      g_value_unset((*obj_iface_props)[i]);
+      g_free((*obj_iface_props)[i]);
+    }
+    delete obj_iface_props;
+  }
+}
+
 } // anonymous namespace
 
 
@@ -112,21 +129,30 @@ void custom_get_property_callback(GObject* object, unsigned int property_id,
 
   GType custom_type = G_OBJECT_TYPE(object);
 
-  Class::properties_type* props = static_cast<Class::properties_type*>(g_type_get_qdata(custom_type, Class::properties_quark));
-  Class::properties_type::size_type props_size = 0;
+  Class::iface_properties_type* iface_props = static_cast<Class::iface_properties_type*>(
+    g_type_get_qdata(custom_type, Class::iface_properties_quark));
+
+  Class::iface_properties_type::size_type iface_props_size = 0;
 
-  if(props) props_size = props->size();
+  if (iface_props)
+    iface_props_size = iface_props->size();
 
-  if(property_id <= props_size)
+  if (property_id <= iface_props_size)
   {
-    g_value_copy((*props)[property_id - 1], value);
+    // Get the object's property value if there is one, else the class's default value.
+    Class::iface_properties_type* obj_iface_props = static_cast<Class::iface_properties_type*>(
+      g_object_get_qdata(object, Class::iface_properties_quark));
+    if (obj_iface_props)
+      g_value_copy((*obj_iface_props)[property_id - 1], value);
+    else
+      g_value_copy((*iface_props)[property_id - 1], value);
   }
   else
   {
     if(Glib::ObjectBase *const wrapper = Glib::ObjectBase::_get_current_wrapper(object))
     {
       PropertyBase& property =
-        property_from_id(*wrapper, property_id - props_size);
+        property_from_id(*wrapper, property_id - iface_props_size);
 
       if((property.object_ == wrapper) && (property.param_spec_ == param_spec))
         g_value_copy(property.value_.gobj(), value);
@@ -144,27 +170,48 @@ void custom_set_property_callback(GObject* object, unsigned int property_id,
 
   GType custom_type = G_OBJECT_TYPE(object);
 
-  Class::properties_type* props = static_cast<Class::properties_type*>(g_type_get_qdata(custom_type, Class::properties_quark));
-  Class::properties_type::size_type props_size = 0;
+  Class::iface_properties_type* iface_props = static_cast<Class::iface_properties_type*>(
+    g_type_get_qdata(custom_type, Class::iface_properties_quark));
 
-  if(props) props_size = props->size();
+  Class::iface_properties_type::size_type iface_props_size = 0;
 
-  if(property_id <= props_size)
+  if (iface_props)
+    iface_props_size = iface_props->size();
+
+  if (property_id <= iface_props_size)
   {
-    g_value_copy(value, (*props)[property_id - 1]);
-    g_object_notify(object, g_param_spec_get_name(param_spec));
+    // If the object does not have interface property values,
+    // copy the class's default values to the object.
+    Class::iface_properties_type* obj_iface_props = static_cast<Class::iface_properties_type*>(
+      g_object_get_qdata(object, Class::iface_properties_quark));
+    if (!obj_iface_props)
+    {
+      obj_iface_props = new Class::iface_properties_type();
+      g_object_set_qdata_full(object, Class::iface_properties_quark, obj_iface_props,
+                              destroy_notify_obj_iface_props);
+      for (Class::iface_properties_type::size_type p = 0; p < iface_props_size; ++p)
+      {
+        GValue* g_value = g_new0(GValue, 1);
+        g_value_init(g_value, G_VALUE_TYPE((*iface_props)[p]));
+        g_value_copy((*iface_props)[p], g_value);
+        obj_iface_props->push_back(g_value);
+      }
+    }
+
+    g_value_copy(value, (*obj_iface_props)[property_id - 1]);
+    g_object_notify_by_pspec(object, param_spec);
   }
   else
   {
     if(Glib::ObjectBase *const wrapper = Glib::ObjectBase::_get_current_wrapper(object))
     {
       PropertyBase& property =
-        property_from_id(*wrapper, property_id - props_size);
+        property_from_id(*wrapper, property_id - iface_props_size);
 
       if((property.object_ == wrapper) && (property.param_spec_ == param_spec))
       {
         g_value_copy(value, property.value_.gobj());
-        g_object_notify(object, g_param_spec_get_name(param_spec));
+        g_object_notify_by_pspec(object, param_spec);
       }
       else
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, param_spec);
@@ -215,12 +262,14 @@ void PropertyBase::install_property(GParamSpec* param_spec)
   // properties.
 
   GType gtype = G_OBJECT_TYPE(object_->gobj());
-  Class::properties_type* props = static_cast<Class::properties_type*>(g_type_get_qdata(gtype, Class::properties_quark));
+  Class::iface_properties_type* iface_props = static_cast<Class::iface_properties_type*>(
+    g_type_get_qdata(gtype, Class::iface_properties_quark));
 
-  Class::properties_type::size_type props_size = 0;
-  if(props) props_size = props->size();
+  Class::iface_properties_type::size_type iface_props_size = 0;
+  if (iface_props)
+    iface_props_size = iface_props->size();
 
-  const unsigned int property_id = property_to_id(*object_, *this) + props_size;
+  const unsigned int property_id = property_to_id(*object_, *this) + iface_props_size;
 
   g_object_class_install_property(G_OBJECT_GET_CLASS(object_->gobj()), property_id, param_spec);
 
@@ -242,9 +291,7 @@ Glib::ustring PropertyBase::get_name() const
 
 void PropertyBase::notify()
 {
-  g_object_notify(object_->gobj(), g_param_spec_get_name(param_spec_));
+  g_object_notify_by_pspec(object_->gobj(), param_spec_);
 }
 
 } // namespace Glib
-
-
index df76459..213f52e 100644 (file)
@@ -82,6 +82,7 @@ int main(int, char**)
             << get_defs(G_TYPE_MOUNT)
             << get_defs(G_TYPE_MOUNT_OPERATION)
             << get_defs(G_TYPE_NOTIFICATION)
+            << get_defs(G_TYPE_PERMISSION)
             << get_defs(G_TYPE_PROPERTY_ACTION)
             << get_defs(G_TYPE_PROXY)
             << get_defs(G_TYPE_PROXY_ADDRESS)
@@ -115,6 +116,7 @@ int main(int, char**)
             << get_defs(G_TYPE_NETWORK_ADDRESS)
             << get_defs(G_TYPE_NETWORK_SERVICE)
             << get_defs(G_TYPE_SETTINGS)
+            << get_defs(G_TYPE_SIMPLE_PERMISSION)
             << get_defs(G_TYPE_SOCKET)
             << get_defs(G_TYPE_SOCKET_CLIENT)
             << get_defs(G_TYPE_SOCKET_CONNECTION)
index 52a35fe..f209348 100644 (file)
 #include "generate_extra_defs.h"
 #include <algorithm>
 
+std::string get_property_with_node_name(GParamSpec* pParamSpec, const std::string& strObjectName, const std::string& strNodeName)
+{
+  std::string strResult;
+
+  //Name and type:
+  const std::string strName = g_param_spec_get_name(pParamSpec);
+  const std::string strTypeName = G_PARAM_SPEC_TYPE_NAME(pParamSpec);
+
+  const gchar* pchBlurb = g_param_spec_get_blurb(pParamSpec);
+  std::string strDocs = (pchBlurb) ? pchBlurb : "";
+  // Quick hack to get rid of nested double quotes:
+  std::replace(strDocs.begin(), strDocs.end(), '"', '\'');
+
+  strResult += "(" + strNodeName + " " + strName + "\n";
+  strResult += "  (of-object \"" + strObjectName + "\")\n";
+  strResult += "  (prop-type \"" + strTypeName + "\")\n";
+  strResult += "  (docs \"" + strDocs + "\")\n";
+
+  //Flags:
+  GParamFlags flags = pParamSpec->flags;
+  bool bReadable = (flags & G_PARAM_READABLE) == G_PARAM_READABLE;
+  bool bWritable = (flags & G_PARAM_WRITABLE) == G_PARAM_WRITABLE;
+  bool bConstructOnly = (flags & G_PARAM_CONSTRUCT_ONLY) == G_PARAM_CONSTRUCT_ONLY;
+
+  //#t and #f aren't documented, but I guess that it's correct based on the example in the .defs spec.
+  const std::string strTrue = "#t";
+  const std::string strFalse = "#f";
+
+  strResult += "  (readable " + (bReadable ? strTrue : strFalse) + ")\n";
+  strResult += "  (writable " + (bWritable ? strTrue : strFalse) + ")\n";
+  strResult += "  (construct-only " + (bConstructOnly ? strTrue : strFalse) + ")\n";
+
+  strResult += ")\n\n"; //close (strNodeName
+
+  return strResult;
+}
+
 // 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.
@@ -75,35 +112,7 @@ std::string get_properties(GType gtype)
     // The base classes' properties should not be generated).
     if(pParamSpec && pParamSpec->owner_type == gtype)
     {
-      //Name and type:
-      const std::string strName = g_param_spec_get_name(pParamSpec);
-      const std::string strTypeName = G_PARAM_SPEC_TYPE_NAME(pParamSpec);
-
-      const gchar* pchBlurb = g_param_spec_get_blurb(pParamSpec);
-      std::string strDocs = (pchBlurb) ? pchBlurb : "";
-      // Quick hack to get rid of nested double quotes:
-      std::replace(strDocs.begin(), strDocs.end(), '"', '\'');
-
-      strResult += "(define-property " + strName + "\n";
-      strResult += "  (of-object \"" + strObjectName + "\")\n";
-      strResult += "  (prop-type \"" + strTypeName + "\")\n";
-      strResult += "  (docs \"" + strDocs + "\")\n";
-
-      //Flags:
-      GParamFlags flags = pParamSpec->flags;
-      bool bReadable = (flags & G_PARAM_READABLE) == G_PARAM_READABLE;
-      bool bWritable = (flags & G_PARAM_WRITABLE) == G_PARAM_WRITABLE;
-      bool bConstructOnly = (flags & G_PARAM_CONSTRUCT_ONLY) == G_PARAM_CONSTRUCT_ONLY;
-
-      //#t and #f aren't documented, but I guess that it's correct based on the example in the .defs spec.
-      const std::string strTrue = "#t";
-      const std::string strFalse = "#f";
-
-      strResult += "  (readable " + (bReadable ? strTrue : strFalse) + ")\n";
-      strResult += "  (writable " + (bWritable ? strTrue : strFalse) + ")\n";
-      strResult += "  (construct-only " + (bConstructOnly ? strTrue : strFalse) + ")\n";
-
-      strResult += ")\n\n"; //close (define-property           
+      strResult += get_property_with_node_name(pParamSpec, strObjectName, "define-property");
     }
   }
 
index 4866ac0..1283c2d 100644 (file)
@@ -39,6 +39,9 @@ bool gtype_is_a_pointer(GType gtype);
 std::string get_defs(GType gtype,
                 GTypeIsAPointerFunc is_a_pointer_func = gtype_is_a_pointer);
 
+std::string get_property_with_node_name(GParamSpec* pParamSpec,
+                const std::string& strObjectName, const std::string& strNodeName);
+
 std::string get_properties(GType gtype);
 
 std::string get_type_name(GType gtype,
index 592e3f4..728187b 100644 (file)
@@ -179,15 +179,14 @@ sub num_args #($)
 }
 
 # parses C++ parameter lists.
-# forms a list of types, names, and initial values
-#  (we don't currently use values)
+# forms a list of types, names, and default values
 sub parse_param($$)
 {
   my ($self, $line) = @_;
 
-
   my $type = "";
   my $name = "";
+  my $name_pos = -1;
   my $value = "";
   my $id = 0;
   my $has_value = 0;
@@ -254,6 +253,7 @@ sub parse_param($$)
     }
     elsif ( $_ eq "=" ) #Default value
     {
+      $str[$name_pos] = "" if ($name_pos >= 0);
       $type = join("", @str); #The type is everything before the = character.
       @str = (); #Wipe it so that it will only contain the default value, which comes next.
       $has_value = 1;
@@ -267,6 +267,7 @@ sub parse_param($$)
       }
       else
       {
+        $str[$name_pos] = "" if ($name_pos >= 0);
         $type = join("", @str);
       }
 
@@ -291,6 +292,7 @@ sub parse_param($$)
       $value = "";
       $has_value = 0;
       $name = "";
+      $name_pos = -1;
       $flags = 0;
       $curr_param++;
 
@@ -308,16 +310,16 @@ sub parse_param($$)
       next;
     }
 
+    # The last identifier before ',', '=', or '{.*}' is the parameter name.
+    # E.g. int name, unsigned long int name = 42, const unsigned int& name.
+    # The name must be preceded by at least one other identifier (the type).
+    # 'const ' is treated specially, as it can't by itself denote the type.
     $id++;
-    $name = $_ if ($id == 2);
-    push(@str, $_) if ($id == 1);
-
-    if ($id > 2)
+    push(@str, $_);
+    if ($id >= 2)
     {
-      print STDERR "Can't parse $line.\n";
-      print STDERR "  arg type so far: $type\n";
-      print STDERR "  arg name so far: $name\n";
-      print STDERR "  arg default value so far: $value\n";
+      $name = $_;
+      $name_pos = $#str;
     }
   }
 
@@ -328,6 +330,7 @@ sub parse_param($$)
   }
   else
   {
+    $str[$name_pos] = "" if ($name_pos >= 0);
     $type = join("", @str);
   }
 
index d9e4532..5fdef5a 100644 (file)
@@ -34,6 +34,7 @@ use FunctionBase;
 #    @ get_methods()
 #    @ get_signals()
 #    @ get_properties()
+#    @ get_child_properties()
 #    @ get_unwrapped()
 #
 #    $ lookup_enum(c_type)
@@ -43,6 +44,7 @@ use FunctionBase;
 #    $ lookup_method(c_name)
 #    $ lookup_function(c_name)
 #    $ lookup_property(object, c_name)
+#    $ lookup_child_property(object, c_name)
 #    $ lookup_signal(object, c_name)
 #
 
@@ -75,6 +77,7 @@ use warnings;
 %GtkDefs::methods = (); #GtkDefs::Function
 %GtkDefs::signals = (); #GtkDefs::Signal
 %GtkDefs::properties = (); #Property
+%GtkDefs::child_properties = (); #Property
 
 @GtkDefs::read = ();
 @GtkDefs::file = ();
@@ -152,6 +155,8 @@ sub read_defs($$;$)
     { on_method($token); }
     elsif ($token =~ /^\(define-property.*\)$/)
     { on_property($token); }
+    elsif ($token =~ /^\(define-child-property.*\)$/)
+    { on_child_property($token); }
     elsif ($token =~ /^\(define-signal.*\)$/)
     { on_signal($token);  }
     elsif ($token =~ /^\(define-vfunc.*\)$/)
@@ -334,6 +339,12 @@ sub on_property($)
   $GtkDefs::properties{"$$thing{class}::$$thing{name}"} = $thing;
 }
 
+sub on_child_property($)
+{
+  my $thing = Property::new(shift(@_));
+  $GtkDefs::child_properties{"$$thing{class}::$$thing{name}"} = $thing;
+}
+
 sub on_signal($)
 {
   my $thing = GtkDefs::Signal::new(shift(@_));
@@ -365,6 +376,11 @@ sub get_properties
   return sort {$$a{name} cmp $$b{name}} values %GtkDefs::properties;
 }
 
+sub get_child_properties
+{
+  return sort {$$a{name} cmp $$b{name}} values %GtkDefs::child_properties;
+}
+
 sub get_marked
 {
   no warnings;
@@ -380,6 +396,7 @@ sub get_unwrapped
   push @targets,grep {$$_{entity_type} eq "method" && $$_{mark}==1} values %GtkDefs::methods;
   push @targets,grep {$$_{mark}==1} values %GtkDefs::signals;
   push @targets,grep {$$_{mark}==1} values %GtkDefs::properties;
+  push @targets,grep {$$_{mark}==1} values %GtkDefs::child_properties;
 
   # find the classes which used them.
   my @classes = unique(map { $$_{class} } @targets);
@@ -412,10 +429,12 @@ sub get_unwrapped
     if ($detailed)
     {
       push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0 && not exists $GtkDefs::properties{$parent . '::' . $_->{name}}} values %GtkDefs::properties;
+      push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0 && not exists $GtkDefs::child_properties{$parent . '::' . $_->{name}}} values %GtkDefs::child_properties;
     }
     else
     {
       push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0} values %GtkDefs::properties;
+      push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0} values %GtkDefs::child_properties;
     }
 
     push @unwrapped, grep {$$_{class} eq $class && $$_{mark}==0} values %GtkDefs::methods;
@@ -474,6 +493,18 @@ sub lookup_property($$)
   return $obj;
 }
 
+# $objChildProperty lookup_child_property($name, $parent_object_name)
+sub lookup_child_property($$)
+{
+  no warnings;
+  my ($parent_object_name, $name) = @_;
+  $name =~ s/-/_/g;
+  my $obj = $GtkDefs::child_properties{"${parent_object_name}::${name}"};
+  return 0 if ($obj eq "");
+  $$obj{mark} = 1;
+  return $obj;
+}
+
 sub lookup_method_dont_mark($)
 {
   no warnings;
index 975ba75..1a00d66 100644 (file)
@@ -763,89 +763,115 @@ sub output_wrap_gerror($$$$$$$)
   $self->append($str);
 }
 
-# _PROPERTY_PROXY(name, cpp_type)
-# void output_wrap_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
-sub output_wrap_property($$$$$$$$)
+# _PROPERTY_PROXY(name, cpp_type) and _CHILD_PROPERTY_PROXY(name, cpp_type)
+# void output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro)
+sub output_wrap_any_property($$$$$$$$$$)
 {
-  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro) = @_;
 
   my $objDefsParser = $$self{objDefsParser};
 
-  my $objProperty = GtkDefs::lookup_property($c_class, $name);
-  if($objProperty eq 0) #If the lookup failed:
-  {
-    $self->output_wrap_failed($name, "property defs lookup failed.");
-  }
-  else
-  {
-    # We use a suffix to specify a particular Glib::PropertyProxy* class.
-    my $proxy_suffix = "";
+  # We use a suffix to specify a particular Glib::PropertyProxy* class.
+  my $proxy_suffix = "";
 
-    # Read/Write:
-    if($objProperty->get_construct_only() eq 1)
-    {
-      # construct-only functions can be read, but not written.
-      $proxy_suffix = "_ReadOnly";
+  # Read/Write:
+  if($objProperty->get_construct_only() eq 1)
+  {
+    # construct-only functions can be read, but not written.
+    $proxy_suffix = "_ReadOnly";
 
-      if($objProperty->get_readable() ne 1)
-      {
-        $self->output_wrap_failed($name, "attempt to wrap write-only and construct-only property.");
-        return;
-      }
-    }
-    elsif($objProperty->get_readable() ne 1)
-    {
-      $proxy_suffix = "_WriteOnly";
-    }
-    elsif($objProperty->get_writable() ne 1)
+    if($objProperty->get_readable() ne 1)
     {
-       $proxy_suffix = "_ReadOnly";
+      $self->output_wrap_failed($name, "attempt to wrap write-only and construct-only property.");
+      return;
     }
+  }
+  elsif($objProperty->get_readable() ne 1)
+  {
+    $proxy_suffix = "_WriteOnly";
+  }
+  elsif($objProperty->get_writable() ne 1)
+  {
+    $proxy_suffix = "_ReadOnly";
+  }
 
-    # Convert - to _ so we can use it in C++ method and variable names:
-    my $name_underscored = $name;
-    $name_underscored =~ tr/-/_/;
+  # Convert - to _ so we can use it in C++ method and variable names:
+  my $name_underscored = $name;
+  $name_underscored =~ tr/-/_/;
 
-    # Get the property documentation, if any, and add m4 quotes.
-    my $documentation = $objProperty->get_docs($deprecation_docs);
-    add_m4_quotes(\$documentation) if ($documentation ne "");
+  # Get the property documentation, if any, and add m4 quotes.
+  my $documentation = $objProperty->get_docs($deprecation_docs);
+  add_m4_quotes(\$documentation) if ($documentation ne "");
 
-    #Declaration:
-    if($deprecated ne "")
-    {
-      $self->append("\n_DEPRECATE_IFDEF_START\n");
-    }
+  #Declaration:
+  if($deprecated ne "")
+  {
+    $self->append("\n_DEPRECATE_IFDEF_START\n");
+  }
+
+  my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s')dnl\n",
+    $name,
+    $name_underscored,
+    $cpp_type,
+    $proxy_suffix,
+    $deprecated,
+    $documentation
+  );
+  $self->append($str);
+  $self->append("\n");
 
-    my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,%s,`%s')dnl\n",
+  # If the property is not already read-only, and the property can be read,
+  # then add a second const accessor for a read-only propertyproxy:
+  if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
+  {
+    my $str = sprintf("$proxy_macro(%s,%s,%s,%s,%s,`%s')dnl\n",
       $name,
       $name_underscored,
       $cpp_type,
-      $proxy_suffix,
+      "_ReadOnly",
       $deprecated,
       $documentation
     );
     $self->append($str);
-    $self->append("\n");
+  }
 
-    # If the property is not already read-only, and the property can be read,
-    # then add a second const accessor for a read-only propertyproxy:
-    if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
-    {
-      my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,%s,`%s')dnl\n",
-        $name,
-        $name_underscored,
-        $cpp_type,
-        "_ReadOnly",
-        $deprecated,
-        $documentation
-      );
-      $self->append($str);
-    }
+  if($deprecated ne "")
+  {
+    $self->append("\n_DEPRECATE_IFDEF_END");
+  }
+}
 
-    if($deprecated ne "")
-    {
-      $self->append("\n_DEPRECATE_IFDEF_END");
-    }
+# _PROPERTY_PROXY(name, cpp_type)
+# void output_wrap_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
+sub output_wrap_property($$$$$$$$)
+{
+  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+
+  my $objProperty = GtkDefs::lookup_property($c_class, $name);
+  if($objProperty eq 0) #If the lookup failed:
+  {
+    $self->output_wrap_failed($name, "property defs lookup failed.");
+  }
+  else
+  {
+    $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, "_PROPERTY_PROXY");
+  }
+}
+
+# _CHILD_PROPERTY_PROXY(name, cpp_type)
+# void output_wrap_child_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
+sub output_wrap_child_property($$$$$$$$)
+{
+  my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+
+  my $objChildProperty = GtkDefs::lookup_child_property($c_class, $name);
+  if($objChildProperty eq 0) #If the lookup failed:
+  {
+    $self->output_wrap_failed($name, "child property defs lookup failed.");
+  }
+  else
+  {
+    $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objChildProperty, "_CHILD_PROPERTY_PROXY");
   }
 }
 
index 03d67b4..f89140e 100644 (file)
@@ -40,7 +40,7 @@ sub new
   $def=~s/\)$//;
   # snarf down the fields
   $$self{mark} = 0;
-  $$self{name} = $1                     if ($def =~ s/^define-property (\S+)//);
+  $$self{name} = $2                     if ($def =~ s/(^define-property|^define-child-property) (\S+)//);
   $$self{class} = $1                    if ($def =~ s/\(of-object "(\S+)"\)//);
   $$self{type} = $1                     if ($def =~ s/\(prop-type "(\S+)"\)//);
   $$self{readable} = ($1 eq "#t")       if ($def =~ s/\(readable (\S+)\)//);
index f7df4ba..1ef5cbc 100644 (file)
@@ -116,6 +116,7 @@ sub parse_and_build_output($)
     if ($token eq "_WRAP_CORBA_METHOD")     { $self->on_wrap_corba_method(); next;} #Used in libbonobo*mm.
     if ($token eq "_WRAP_SIGNAL") { $self->on_wrap_signal(); next;}
     if ($token eq "_WRAP_PROPERTY") { $self->on_wrap_property(); next;}
+    if ($token eq "_WRAP_CHILD_PROPERTY") { $self->on_wrap_child_property(); next;}
     if ($token eq "_WRAP_VFUNC") { $self->on_wrap_vfunc(); next;}
     if ($token eq "_WRAP_CTOR")   { $self->on_wrap_ctor(); next;}
     if ($token eq "_WRAP_CREATE") { $self->on_wrap_create(); next;}
@@ -1401,12 +1402,9 @@ sub on_wrap_gerror($)
       $$self{filename}, $$self{line_num}, $cpp_type, $c_enum, $domain, @args);
 }
 
-sub on_wrap_property($)
+sub on_wrap_any_property($)
 {
   my ($self) = @_;
-  my $objOutputter = $$self{objOutputter};
-
-  return unless ($self->check_for_eof());
 
   my $str = $self->extract_bracketed_text();
   my @args = string_split_commas($str);
@@ -1446,10 +1444,32 @@ sub on_wrap_property($)
     }
   }
 
+  return ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs);
+}
+
+sub on_wrap_property($)
+{
+  my ($self) = @_;
+  my $objOutputter = $$self{objOutputter};
+
+  return unless ($self->check_for_eof());
+
+  my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = $self->on_wrap_any_property();
 
   $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs);
 }
 
+sub on_wrap_child_property($)
+{
+  my ($self) = @_;
+  my $objOutputter = $$self{objOutputter};
+
+  return unless ($self->check_for_eof());
+
+  my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = $self->on_wrap_any_property();
+
+  $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs);
+}
 
 sub output_wrap_check($$$$$$)
 {