[gobject-introspection] Add signal flags



commit d7a2b1dc90bd61bcd0908c3fd8b124bb84ecc862
Author: Johan Dahlin <jdahlin litl com>
Date:   Sat Aug 13 11:21:05 2011 -0300

    Add signal flags
    
    This adds all GSignalFlags into the gir.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=656457

 girepository/gdump.c                      |   26 ++++++++++++++-
 giscanner/ast.py                          |   15 ++++++++-
 giscanner/gdumpparser.py                  |    9 +++++-
 giscanner/girparser.py                    |    9 +++++-
 giscanner/girwriter.py                    |   12 ++++++-
 tests/scanner/Annotation-1.0-expected.gir |    7 ++--
 tests/scanner/Foo-1.0-expected.gir        |    4 +-
 tests/scanner/Regress-1.0-expected.gir    |   50 ++++++++++++++++++++++++++---
 tests/scanner/regress.c                   |   36 +++++++++++++++++++++
 9 files changed, 153 insertions(+), 15 deletions(-)
---
diff --git a/girepository/gdump.c b/girepository/gdump.c
index e607f32..aab067b 100644
--- a/girepository/gdump.c
+++ b/girepository/gdump.c
@@ -166,9 +166,33 @@ dump_signals (GType type, GOutputStream *out)
       sigid = sig_ids[i];
       g_signal_query (sigid, &query);
 
-      escaped_printf (out, "    <signal name=\"%s\" return=\"%s\">\n",
+      escaped_printf (out, "    <signal name=\"%s\" return=\"%s\"",
 		      query.signal_name, g_type_name (query.return_type));
 
+      if (query.signal_flags & G_SIGNAL_RUN_FIRST)
+        escaped_printf (out, " when=\"first\"");
+      else if (query.signal_flags & G_SIGNAL_RUN_LAST)
+        escaped_printf (out, " when=\"last\"");
+      else if (query.signal_flags & G_SIGNAL_RUN_CLEANUP)
+        escaped_printf (out, " when=\"cleanup\"");
+#if GLIB_CHECK_VERSION(2, 29, 15)
+      else if (query.signal_flags & G_SIGNAL_MUST_COLLECT)
+        escaped_printf (out, " when=\"must-collect\"");
+#endif
+      if (query.signal_flags & G_SIGNAL_NO_RECURSE)
+        escaped_printf (out, " no-recurse=\"1\"");
+
+      if (query.signal_flags & G_SIGNAL_DETAILED)
+        escaped_printf (out, " detailed=\"1\"");
+
+      if (query.signal_flags & G_SIGNAL_ACTION)
+        escaped_printf (out, " action=\"1\"");
+
+      if (query.signal_flags & G_SIGNAL_NO_HOOKS)
+        escaped_printf (out, " no-hooks=\"1\"");
+
+      goutput_write (out, ">\n");
+
       for (j = 0; j < query.n_params; j++)
 	{
 	  escaped_printf (out, "      <param type=\"%s\"/>\n",
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 252c86b..2b1c6f5 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -323,6 +323,12 @@ PARAM_TRANSFER_NONE = 'none'
 PARAM_TRANSFER_CONTAINER = 'container'
 PARAM_TRANSFER_FULL = 'full'
 
+SIGNAL_FIRST = 'first'
+SIGNAL_LAST = 'last'
+SIGNAL_CLEANUP = 'cleanup'
+SIGNAL_MUST_COLLECT = 'must-collect'
+
+
 class Namespace(object):
     def __init__(self, name, version,
                  identifier_prefixes=None,
@@ -868,8 +874,15 @@ class Boxed(Node, Registered):
 
 class Signal(Callable):
 
-    def __init__(self, name, retval, parameters):
+    def __init__(self, name, retval, parameters, when="first",
+                 no_recurse=False, detailed=False, action=False,
+                 no_hooks=False):
         Callable.__init__(self, name, retval, parameters, False)
+        self.when = when
+        self.no_recurse = no_recurse
+        self.detailed = detailed
+        self.action = action
+        self.no_hooks = no_hooks
 
 
 class Class(Node, Registered):
diff --git a/giscanner/gdumpparser.py b/giscanner/gdumpparser.py
index 35fea72..be25d61 100644
--- a/giscanner/gdumpparser.py
+++ b/giscanner/gdumpparser.py
@@ -453,6 +453,11 @@ different --identifier-prefix.""" % (xmlnode.attrib['name'], self._namespace.ide
             rtype = ast.Type.create_from_gtype_name(rctype)
             return_ = ast.Return(rtype)
             parameters = []
+            when = signal_info.attrib['when']
+            no_recurse = signal_info.attrib.get('no-recurse', '0') == '1'
+            detailed = signal_info.attrib.get('detailed', '0') == '1'
+            action = signal_info.attrib.get('action', '0') == '1'
+            no_hooks = signal_info.attrib.get('no-hooks', '0') == '1'
             for i, parameter in enumerate(signal_info.findall('param')):
                 if i == 0:
                     argname = 'object'
@@ -463,7 +468,9 @@ different --identifier-prefix.""" % (xmlnode.attrib['name'], self._namespace.ide
                 param = ast.Parameter(argname, ptype)
                 param.transfer = ast.PARAM_TRANSFER_NONE
                 parameters.append(param)
-            signal = ast.Signal(signal_info.attrib['name'], return_, parameters)
+            signal = ast.Signal(signal_info.attrib['name'], return_, parameters,
+                                when=when, no_recurse=no_recurse, detailed=detailed,
+                                action=action, no_hooks=no_hooks)
             node.signals.append(signal)
         node.signals = node.signals
 
diff --git a/giscanner/girparser.py b/giscanner/girparser.py
index 41e2abd..5e1866d 100644
--- a/giscanner/girparser.py
+++ b/giscanner/girparser.py
@@ -268,7 +268,7 @@ class GIRParser(object):
         for prop in self._find_children(node, _corens('property')):
             obj.properties.append(self._parse_property(prop))
         for signal in self._find_children(node, _glibns('signal')):
-            obj.signals.append(self._parse_function_common(signal, ast.Function))
+            obj.signals.append(self._parse_function_common(signal, ast.Signal))
 
     def _parse_callback(self, node):
         callback = self._parse_function_common(node, ast.Callback)
@@ -298,6 +298,13 @@ class GIRParser(object):
             func = klass(name, retval, parameters, throws, identifier)
         elif klass is ast.VFunction:
             func = klass(name, retval, parameters, throws)
+        elif klass is ast.Signal:
+            func = klass(name, retval, parameters,
+                         when=node.attrib.get('when', 'first'),
+                         no_recurse=node.attrib.get('no-recurse', '0') == '1',
+                         detailed=node.attrib.get('detailed', '0') == '1',
+                         action=node.attrib.get('action', '0') == '1',
+                         no_hooks=node.attrib.get('no-hooks', '0') == '1')
         else:
             assert False
 
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index ce173fd..591c7ae 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -554,7 +554,17 @@ and/or use gtk-doc annotations. ''')
                 self._write_type(field.type)
 
     def _write_signal(self, signal):
-        attrs = [('name', signal.name)]
+        attrs = [('name', signal.name),
+                 ('when', signal.when)]
+        if signal.no_recurse:
+            attrs.append(('no-recurse', '1'))
+        if signal.detailed:
+            attrs.append(('detailed', '1'))
+        if signal.action:
+            attrs.append(('action', '1'))
+        if signal.no_hooks:
+            attrs.append(('no-hooks', '1'))
+
         self._append_version(signal, attrs)
         self._append_node_generic(signal, attrs)
         with self.tagcontext('glib:signal', attrs):
diff --git a/tests/scanner/Annotation-1.0-expected.gir b/tests/scanner/Annotation-1.0-expected.gir
index 8ae17f5..c544702 100644
--- a/tests/scanner/Annotation-1.0-expected.gir
+++ b/tests/scanner/Annotation-1.0-expected.gir
@@ -549,7 +549,7 @@ of tabs and strings to test the tab handling capabilities of the scanner.</doc>
       <field name="parent_instance">
         <type name="GObject.Object" c:type="GObject"/>
       </field>
-      <glib:signal name="attribute-signal">
+      <glib:signal name="attribute-signal" when="last">
         <doc xml:whitespace="preserve">This signal tests a signal with attributes.</doc>
         <return-value transfer-ownership="full">
           <attribute name="some.annotation.foo3" value="val3"/>
@@ -569,7 +569,7 @@ of tabs and strings to test the tab handling capabilities of the scanner.</doc>
           </parameter>
         </parameters>
       </glib:signal>
-      <glib:signal name="doc-empty-arg-parsing">
+      <glib:signal name="doc-empty-arg-parsing" when="last">
         <doc xml:whitespace="preserve">This signal tests an empty document argument (@arg1)</doc>
         <return-value transfer-ownership="none">
           <type name="none"/>
@@ -580,7 +580,7 @@ of tabs and strings to test the tab handling capabilities of the scanner.</doc>
           </parameter>
         </parameters>
       </glib:signal>
-      <glib:signal name="list-signal">
+      <glib:signal name="list-signal" when="last">
         <doc xml:whitespace="preserve">This is a signal which takes a list of strings, but it's not
 known by GObject as it's only marked as G_TYPE_POINTER</doc>
         <return-value transfer-ownership="none">
@@ -596,6 +596,7 @@ known by GObject as it's only marked as G_TYPE_POINTER</doc>
         </parameters>
       </glib:signal>
       <glib:signal name="string-signal"
+                   when="last"
                    version="1.0"
                    deprecated="Use other-signal instead"
                    deprecated-version="1.2">
diff --git a/tests/scanner/Foo-1.0-expected.gir b/tests/scanner/Foo-1.0-expected.gir
index 06d15c3..1772b56 100644
--- a/tests/scanner/Foo-1.0-expected.gir
+++ b/tests/scanner/Foo-1.0-expected.gir
@@ -532,7 +532,7 @@ uses a C sugar return type.</doc>
       <field name="some_int">
         <type name="gint" c:type="int"/>
       </field>
-      <glib:signal name="signal">
+      <glib:signal name="signal" when="last">
         <return-value transfer-ownership="full">
           <type name="utf8"/>
         </return-value>
@@ -769,7 +769,7 @@ exposed to language bindings.</doc>
           </parameter>
         </parameters>
       </method>
-      <glib:signal name="destroy-event">
+      <glib:signal name="destroy-event" when="last">
         <return-value transfer-ownership="none">
           <type name="none"/>
         </return-value>
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index 8904d62..02e56fd 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -861,7 +861,27 @@ case.</doc>
       <field name="string">
         <type name="utf8" c:type="char*"/>
       </field>
-      <glib:signal name="sig-with-array-prop">
+      <glib:signal name="all"
+                   when="first"
+                   no-recurse="1"
+                   detailed="1"
+                   action="1"
+                   no-hooks="1">
+        <return-value transfer-ownership="none">
+          <type name="none"/>
+        </return-value>
+      </glib:signal>
+      <glib:signal name="cleanup" when="cleanup">
+        <return-value transfer-ownership="none">
+          <type name="none"/>
+        </return-value>
+      </glib:signal>
+      <glib:signal name="first" when="first">
+        <return-value transfer-ownership="none">
+          <type name="none"/>
+        </return-value>
+      </glib:signal>
+      <glib:signal name="sig-with-array-prop" when="last">
         <doc xml:whitespace="preserve">This test signal is like TelepathyGlib's
 TpChannel:: group-members-changed-detailed:</doc>
         <return-value transfer-ownership="none">
@@ -876,7 +896,7 @@ TpChannel:: group-members-changed-detailed:</doc>
           </parameter>
         </parameters>
       </glib:signal>
-      <glib:signal name="sig-with-hash-prop">
+      <glib:signal name="sig-with-hash-prop" when="last">
         <doc xml:whitespace="preserve">This test signal is like TelepathyGlib's
 TpAccount::status-changed</doc>
         <return-value transfer-ownership="none">
@@ -891,7 +911,7 @@ TpAccount::status-changed</doc>
           </parameter>
         </parameters>
       </glib:signal>
-      <glib:signal name="sig-with-strv">
+      <glib:signal name="sig-with-strv" when="last">
         <doc xml:whitespace="preserve">Test GStrv as a param.</doc>
         <return-value transfer-ownership="none">
           <type name="none"/>
@@ -905,12 +925,15 @@ TpAccount::status-changed</doc>
           </parameter>
         </parameters>
       </glib:signal>
-      <glib:signal name="test">
+      <glib:signal name="test" when="last" no-recurse="1" no-hooks="1">
         <return-value transfer-ownership="none">
           <type name="none"/>
         </return-value>
       </glib:signal>
-      <glib:signal name="test-with-static-scope-arg">
+      <glib:signal name="test-with-static-scope-arg"
+                   when="last"
+                   no-recurse="1"
+                   no-hooks="1">
         <return-value transfer-ownership="none">
           <type name="none"/>
         </return-value>
@@ -1330,6 +1353,23 @@ TpAccount::status-changed</doc>
         </parameter>
       </parameters>
     </function>
+    <function name="test_array_fixed_out_objects"
+              c:identifier="regress_test_array_fixed_out_objects">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="objs"
+                   direction="out"
+                   caller-allocates="0"
+                   transfer-ownership="full">
+          <doc xml:whitespace="preserve">An array of #RegressTestObj</doc>
+          <array zero-terminated="0" c:type="RegressTestObj***" fixed-size="2">
+            <type name="TestObj" c:type="RegressTestObj**"/>
+          </array>
+        </parameter>
+      </parameters>
+    </function>
     <function name="test_array_fixed_size_int_in"
               c:identifier="regress_test_array_fixed_size_int_in">
       <return-value transfer-ownership="none">
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index 13db3a7..938bcf1 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -1791,6 +1791,9 @@ enum {
   REGRESS_TEST_OBJ_SIGNAL_SIG_NEW_WITH_ARRAY_PROP,
   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_HASH_PROP,
   REGRESS_TEST_OBJ_SIGNAL_SIG_WITH_STRV,
+  REGRESS_TEST_OBJ_SIGNAL_FIRST,
+  REGRESS_TEST_OBJ_SIGNAL_CLEANUP,
+  REGRESS_TEST_OBJ_SIGNAL_ALL,
   N_REGRESS_TEST_OBJ_SIGNALS
 };
 
@@ -1887,6 +1890,39 @@ regress_test_obj_class_init (RegressTestObjClass *klass)
 		  1,
 		  G_TYPE_STRV);
 
+  regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_FIRST] =
+    g_signal_new ("first",
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_FIRST,
+		  0,
+		  NULL,
+		  NULL,
+		  g_cclosure_marshal_VOID__VOID,
+		  G_TYPE_NONE,
+                  0);
+
+    regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_CLEANUP] =
+    g_signal_new ("cleanup",
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_CLEANUP,
+		  0,
+		  NULL,
+		  NULL,
+		  g_cclosure_marshal_VOID__VOID,
+		  G_TYPE_NONE,
+                  0);
+
+    regress_test_obj_signals[REGRESS_TEST_OBJ_SIGNAL_ALL] =
+    g_signal_new ("all",
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_ACTION | G_SIGNAL_NO_HOOKS,
+		  0,
+		  NULL,
+		  NULL,
+		  g_cclosure_marshal_VOID__VOID,
+		  G_TYPE_NONE,
+                  0);
+
   gobject_class->set_property = regress_test_obj_set_property;
   gobject_class->get_property = regress_test_obj_get_property;
   gobject_class->dispose = regress_test_obj_dispose;



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