summaryrefslogtreecommitdiff
path: root/tools/glib-ginterface-gen.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/glib-ginterface-gen.py')
-rw-r--r--tools/glib-ginterface-gen.py116
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,