diff options
Diffstat (limited to 'tools/glib-ginterface-gen.py')
-rw-r--r-- | tools/glib-ginterface-gen.py | 116 |
1 files changed, 99 insertions, 17 deletions
diff --git a/tools/glib-ginterface-gen.py b/tools/glib-ginterface-gen.py index ef5f978..f806131 100644 --- a/tools/glib-ginterface-gen.py +++ b/tools/glib-ginterface-gen.py @@ -28,7 +28,7 @@ import xml.dom.minidom from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \ camelcase_to_lower, NS_TP, dbus_gutils_wincaps_to_uscore, \ - signal_to_marshal_name + signal_to_marshal_name, method_to_glue_marshal_name NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0" @@ -45,6 +45,22 @@ class Generator(object): assert prefix.endswith('_') assert not signal_marshal_prefix.endswith('_') + # The main_prefix, sub_prefix thing is to get: + # FOO_ -> (FOO_, _) + # FOO_SVC_ -> (FOO_, _SVC_) + # but + # FOO_BAR/ -> (FOO_BAR_, _) + # FOO_BAR/SVC_ -> (FOO_BAR_, _SVC_) + + if '/' in prefix: + main_prefix, sub_prefix = prefix.upper().split('/', 1) + prefix = prefix.replace('/', '_') + else: + main_prefix, sub_prefix = prefix.upper().split('_', 1) + + self.MAIN_PREFIX_ = main_prefix + '_' + self._SUB_PREFIX_ = '_' + sub_prefix + self.Prefix_ = prefix self.Prefix = prefix.replace('_', '') self.prefix_ = prefix.lower() @@ -77,7 +93,7 @@ class Generator(object): if tmp and not self.allow_havoc: raise AssertionError('%s is %s' % (self.iface_name, tmp)) - self.b('const DBusGObjectInfo dbus_glib_%s%s_object_info;' + self.b('static const DBusGObjectInfo _%s%s_object_info;' % (self.prefix_, node_name_lc)) self.b('') @@ -154,14 +170,8 @@ class Generator(object): self.h('GType %s%s_get_type (void);' % (self.prefix_, node_name_lc)) - main_prefix, sub_prefix = self.PREFIX_.split('_', 1) - main_prefix += '_' - sub_prefix = '_' + sub_prefix - # FOO_ -> (FOO_, _) - # FOO_SVC_ -> (FOO_, _SVC_) - gtype = self.current_gtype = \ - main_prefix + 'TYPE' + sub_prefix + node_name_uc + self.MAIN_PREFIX_ + 'TYPE' + self._SUB_PREFIX_ + node_name_uc classname = self.Prefix + node_name_mixed self.h('#define %s \\\n (%s%s_get_type ())' @@ -171,7 +181,7 @@ class Generator(object): % (self.PREFIX_, node_name_uc, gtype, classname)) self.h('#define %sIS%s%s(obj) \\\n' ' (G_TYPE_CHECK_INSTANCE_TYPE((obj), %s))' - % (main_prefix, sub_prefix, node_name_uc, gtype)) + % (self.MAIN_PREFIX_, self._SUB_PREFIX_, node_name_uc, gtype)) self.h('#define %s%s_GET_CLASS(obj) \\\n' ' (G_TYPE_INSTANCE_GET_INTERFACE((obj), %s, %sClass))' % (self.PREFIX_, node_name_uc, gtype, classname)) @@ -201,16 +211,94 @@ class Generator(object): self.b(s) self.b(' dbus_g_object_type_install_info (%s%s_get_type (),' % (self.prefix_, node_name_lc)) - self.b(' &dbus_glib_%s%s_object_info);' + self.b(' &_%s%s_object_info);' % (self.prefix_, node_name_lc)) self.b('}') self.h('') + self.b('static const DBusGMethodInfo _%s%s_methods[] = {' + % (self.prefix_, node_name_lc)) + + method_blob, offsets = self.get_method_glue(methods) + + for method, offset in zip(methods, offsets): + self.do_method_glue(method, offset) + + self.b('};') + self.b('') + + self.b('static const DBusGObjectInfo _%s%s_object_info = {' + % (self.prefix_, node_name_lc)) + self.b(' 0,') # version + self.b(' _%s%s_methods,' % (self.prefix_, node_name_lc)) + self.b(' %d,' % len(methods)) + self.b('"' + method_blob.replace('\0', '\\0') + '",') + self.b('"' + self.get_signal_glue(signals).replace('\0', '\\0') + '",') + self.b('"\\0"') + self.b('};') + self.b('') + self.node_name_mixed = None self.node_name_lc = None self.node_name_uc = None + def get_method_glue(self, methods): + info = [] + offsets = [] + + for method in methods: + offsets.append(len(''.join(info))) + + info.append(self.iface_name + '\0') + info.append(method.getAttribute('name') + '\0') + + info.append('A\0') # async + + counter = 0 + for arg in method.getElementsByTagName('arg'): + out = arg.getAttribute('direction') == 'out' + + name = arg.getAttribute('name') + if not name: + assert out + name = 'arg%u' % counter + counter += 1 + + info.append(name + '\0') + + if out: + info.append('O\0') + else: + info.append('I\0') + + if out: + info.append('F\0') # not const + info.append('N\0') # not error or return + info.append(arg.getAttribute('type') + '\0') + + info.append('\0') + + return ''.join(info) + '\0', offsets + + def do_method_glue(self, method, offset): + lc_name = camelcase_to_lower(method.getAttribute('name')) + + marshaller = method_to_glue_marshal_name(method, + self.signal_marshal_prefix) + wrapper = self.prefix_ + self.node_name_lc + '_' + lc_name + + self.b(" { (GCallback) %s, %s, %d }," % (wrapper, marshaller, offset)) + + def get_signal_glue(self, signals): + info = [] + + for signal in signals: + info.append(self.iface_name) + info.append(signal.getAttribute('name')) + + return '\0'.join(info) + '\0\0' + def get_method_impl_names(self, method): dbus_method_name = method.getAttribute('name') class_member_name = camelcase_to_lower(dbus_method_name) @@ -321,12 +409,6 @@ class Generator(object): self.b('}') self.b('') - # Fixup for dbus-binding-tool crack - dbus_glib_name = (self.prefix_ + self.node_name_lc + '_' + - dbus_gutils_wincaps_to_uscore(dbus_method_name)) - if dbus_glib_name != stub_name: - self.b('#define %s %s' % (dbus_glib_name, stub_name)) - # Implementation registration (in both header and body) self.h('void %s%s_implement_%s (%s%sClass *klass, %s impl);' % (self.prefix_, self.node_name_lc, class_member_name, |