Add support for signals
authorJohan Dahlin <jdahlin@async.com.br>
Fri, 25 Apr 2008 16:26:51 +0000 (16:26 +0000)
committerJohan Dahlin <johan@src.gnome.org>
Fri, 25 Apr 2008 16:26:51 +0000 (16:26 +0000)
2008-04-25  Johan Dahlin  <jdahlin@async.com.br>

    * giscanner/cgobject.py:
    * giscanner/gidlwriter.py:
    * giscanner/gobjecttreebuilder.py:
    Add support for signals

    * tests/parser/foo.c (foo_object_class_init):
    * Foo-expected.gidl:
    Add a signal and update the expected output.

svn path=/trunk/; revision=225

ChangeLog
giscanner/cgobject.py
giscanner/gidlwriter.py
giscanner/gobjecttreebuilder.py
tests/parser/Foo-expected.gidl
tests/parser/foo.c

index c35e793..ac869cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-04-25  Johan Dahlin  <jdahlin@async.com.br>
+
+       * giscanner/cgobject.py:
+       * giscanner/gidlwriter.py:
+       * giscanner/gobjecttreebuilder.py:
+       Add support for signals
+
+       * tests/parser/foo.c (foo_object_class_init):
+       * Foo-expected.gidl:
+       Add a signal and update the expected output.
+
 2008-04-24  Johan Dahlin  <jdahlin@async.com.br>
 
        * giscanner/gidlwriter.py:
index 622735e..9b98ceb 100644 (file)
@@ -87,6 +87,20 @@ class GParamSpec(ctypes.Structure):
                 ('owner_type', GType)]
 
 
+class GSignalInfo(ctypes.Structure):
+    _fields_ = [('signal_id', ctypes.c_uint),
+                ('signal_name', ctypes.c_char_p),
+                ('itype', GType),
+                ('signal_flags', ctypes.c_uint),
+                ('return_type', GType),
+                ('n_params', ctypes.c_uint),
+                ('param_types', ctypes.POINTER(GType))]
+
+    def get_params(self):
+        for i in range(self.n_params):
+            yield self.param_types[i]
+
+
 _library_path = find_library('gobject-2.0')
 if not _library_path:
     raise ImportError("Could not find gobject-2.0 library")
@@ -161,3 +175,12 @@ def type_interface_prerequisites(type_id):
     type_ids = _gobj.g_type_interface_prerequisites(type_id, ctypes.byref(n))
     for i in range(n.value):
         yield type_ids[i]
+
+_gobj.g_signal_list_ids.restype = ctypes.POINTER(ctypes.c_int)
+def signal_list(type_id):
+    n = ctypes.c_uint()
+    signal_ids = _gobj.g_signal_list_ids(type_id, ctypes.byref(n))
+    for i in range(n.value):
+        info = GSignalInfo()
+        _gobj.g_signal_query(signal_ids[i], ctypes.byref(info))
+        yield info
index 8d23e01..0e1f789 100644 (file)
@@ -110,6 +110,8 @@ class GIDLWriter(XMLWriter):
                 self._write_method(method)
             for prop in node.properties:
                 self._write_property(prop)
+            for signal in node.signals:
+                self._write_signal(signal)
 
     def _write_boxed(self, boxed):
         attrs = [('name', boxed.name),
@@ -127,6 +129,12 @@ class GIDLWriter(XMLWriter):
                  ('prop', prop.type)]
         self.write_tag('property', attrs)
 
+    def _write_signal(self, signal):
+        attrs = [('name', signal.name)]
+        with self.tagcontext('signal', attrs):
+            self._write_return_type(signal.retval)
+            self._write_parameters(signal.parameters)
+
     def _write_callback(self, func):
         attrs = [('name', func.name)]
         with self.tagcontext('callback', attrs):
index 7510c87..3b9bc06 100644 (file)
@@ -5,7 +5,7 @@ import os
 from . import cgobject
 from .odict import odict
 from .treebuilder import (Callback, Class, Enum, Function, Interface,
-                          Member, Property, Struct)
+                          Member, Node, Parameter, Property, Return, Struct)
 
 # Copied from h2defs.py
 _upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])')
@@ -60,7 +60,7 @@ class GLibObject(Class):
         Class.__init__(self, name, parent)
         self.type_name = type_name
         self.get_type = get_type
-
+        self.signals = []
 
 class GLibBoxed(Struct):
     def __init__(self, name, type_name, get_type):
@@ -76,12 +76,20 @@ class GLibInterface(Interface):
         Interface.__init__(self, name)
         self.type_name = type_name
         self.get_type = get_type
+        self.signals = []
 
 
 class GLibProperty(Property):
     pass
 
 
+class GLibSignal(Node):
+    def __init__(self, name, retval):
+        Node.__init__(self, name)
+        self.retval = retval
+        self.parameters = []
+
+
 class GObjectTreeBuilder(object):
     def __init__(self, namespace_name):
         self._namespace_name = namespace_name
@@ -307,6 +315,7 @@ class GObjectTreeBuilder(object):
                           self._resolve_type_name(parent_type_name),
                           type_name, symbol)
         self._introspect_properties(node, type_id)
+        self._introspect_signals(node, type_id)
         self._add_attribute(node)
         self._remove_attribute(type_name)
         self._register_internal_type(type_name, node)
@@ -316,6 +325,7 @@ class GObjectTreeBuilder(object):
         node = GLibInterface(self._strip_namespace_object(type_name),
                              type_name, symbol)
         self._introspect_properties(node, type_id)
+        self._introspect_signals(node, type_id)
         self._add_attribute(node)
         self._remove_attribute(type_name)
         self._register_internal_type(type_name, node)
@@ -343,3 +353,16 @@ class GObjectTreeBuilder(object):
             node.properties.append(Property(
                 pspec.name,
                 cgobject.type_name(pspec.value_type)))
+
+    def _introspect_signals(self, node, type_id):
+        for signal_info in cgobject.signal_list(type_id):
+            retval = Return(cgobject.type_name(signal_info.return_type))
+            signal = GLibSignal(signal_info.signal_name, retval)
+            for i, parameter in enumerate(signal_info.get_params()):
+                if i == 0:
+                    name = 'object'
+                else:
+                    name = 'p%s' % (i-1,)
+                signal.parameters.append(
+                    Parameter(name, cgobject.type_name(parameter)))
+            node.signals.append(signal)
index 78a20a4..7855482 100644 (file)
                                </parameters>
                        </method>
                        <property name="string" type="char*" readable="1" writable="1" construct="1" construct-only="0"/>
+                       <signal name="signal" when="LAST">
+                               <return-type type="char*"/>
+                               <parameters>
+                                       <parameter name="object" type="FooObject*"/>
+                                       <parameter name="p0" type="GObject*"/>
+                                       <parameter name="p1" type="gpointer"/>
+                               </parameters>
+                       </signal>
                </object>
                <object name="FooSubobject" parent="FooObject" type-name="FooSubobject" get-type="foo_subobject_get_type">
                        <constructor name="new" symbol="foo_subobject_new">
index 032ef68..6aba7cb 100644 (file)
@@ -30,13 +30,21 @@ foo_interface_get_type (void)
   return object_type;
 }
 
-G_DEFINE_TYPE (FooObject, foo_object, G_TYPE_OBJECT);
 
 enum {
   PROP_0,
   PROP_STRING
 };
 
+enum {
+  SIGNAL,
+  LAST_SIGNAL
+};
+
+static guint foo_object_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (FooObject, foo_object, G_TYPE_OBJECT);
+
 static void
 foo_object_set_property (GObject         *object,
                          guint            prop_id,
@@ -90,6 +98,15 @@ foo_object_class_init (FooObjectClass *klass)
                                                         "The String Property Blurb",
                                                         NULL,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+  foo_object_signals[SIGNAL] =
+    g_signal_new ("signal",
+                 G_OBJECT_CLASS_TYPE (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 NULL,
+                 NULL, NULL,
+                 (GSignalCMarshaller)g_cclosure_marshal_STRING__OBJECT_POINTER,
+                 G_TYPE_STRING, 2, G_TYPE_OBJECT, G_TYPE_POINTER);
+
 }
 
 static void