def do_signal(self, signal):
        marshaller = signal_to_marshal_name(signal, self.prefix)

        assert '__' in marshaller
        rhs = marshaller.split('__', 1)[1].split('_')

        self.marshallers[marshaller] = rhs
    def do_signal(self, signal):
        marshaller = signal_to_marshal_name(signal, self.prefix)

        assert '__' in marshaller
        rhs = marshaller.split('__', 1)[1].split('_')

        self.marshallers[marshaller] = rhs
    def do_signal(self, signal):
        assert self.node_name_mixed is not None

        in_base_init = []

        # for signal: Thing::StuffHappened (s, u)
        # we want to emit:
        # void tp_svc_thing_emit_stuff_happened (gpointer instance,
        #    const char *arg0, guint arg1);

        dbus_name = signal.getAttribute('name')

        ugly_name = signal.getAttribute('tp:name-for-bindings')
        if dbus_name != ugly_name.replace('_', ''):
            raise AssertionError('Signal %s tp:name-for-bindings (%s) does '
                    'not match' % (dbus_name, ugly_name))

        stub_name = (self.prefix_ + self.node_name_lc + '_emit_' +
                     ugly_name.lower())

        const_name = self.get_signal_const_entry(signal)

        # Gather arguments
        args = []
        for i in signal.getElementsByTagName('arg'):
            name = i.getAttribute('name')
            dtype = i.getAttribute('type')
            tp_type = i.getAttribute('tp:type')

            if name:
                name = 'arg_' + name
            else:
                name = 'arg' + str(len(args))

            ctype, gtype, marshaller, pointer = type_to_gtype(dtype)

            if pointer:
                ctype = 'const ' + ctype

            struct = (ctype, name, gtype)
            args.append(struct)

        tmp = (['gpointer instance'] +
               [ctype + name for (ctype, name, gtype) in args])

        self.h(('void %s (' % stub_name) + (',\n    '.join(tmp)) + ');')

        # FIXME: emit docs

        self.d('/**')
        self.d(' * %s:' % stub_name)
        self.d(' * @instance: The object implementing this interface')
        for (ctype, name, gtype) in args:
            self.d(' * @%s: %s (FIXME, generate documentation)'
                   % (name, ctype))
        self.d(' *')
        self.d(' * Type-safe wrapper around g_signal_emit to emit the')
        self.d(' * %s signal on interface %s.'
               % (dbus_name, self.iface_name))
        self.d(' */')

        self.b('void')
        self.b(('%s (' % stub_name) + (',\n    '.join(tmp)) + ')')
        self.b('{')
        self.b('  g_assert (instance != NULL);')
        self.b('  g_assert (G_TYPE_CHECK_INSTANCE_TYPE (instance, %s));'
               % (self.current_gtype))
        tmp = (['instance', '%s_signals[%s]' % (self.node_name_lc, const_name),
                '0'] + [name for (ctype, name, gtype) in args])
        self.b('  g_signal_emit (' + ',\n      '.join(tmp) + ');')
        self.b('}')
        self.b('')

        signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace('_',
                '-')

        self.d('/**')
        self.d(' * %s%s::%s:'
                % (self.Prefix, self.node_name_mixed, signal_name))
        self.d(' * @self: an object')
        for (ctype, name, gtype) in args:
            self.d(' * @%s: %s (FIXME, generate documentation)'
                   % (name, ctype))
        self.d(' *')
        self.d(' * The %s D-Bus signal is emitted whenever '
                'this GObject signal is.' % dbus_name)
        self.d(' */')
        self.d('')

        in_base_init.append('  %s_signals[%s] ='
                            % (self.node_name_lc, const_name))
        in_base_init.append('  g_signal_new ("%s",' % signal_name)
        in_base_init.append('      G_OBJECT_CLASS_TYPE (klass),')
        in_base_init.append('      G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,')
        in_base_init.append('      0,')
        in_base_init.append('      NULL, NULL,')
        in_base_init.append('      %s,'
                % signal_to_marshal_name(signal, self.signal_marshal_prefix))
        in_base_init.append('      G_TYPE_NONE,')
        tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args]
        in_base_init.append('      %s);' % ',\n      '.join(tmp))
        in_base_init.append('')

        return in_base_init
    def do_signal(self, signal):
        assert self.node_name_mixed is not None

        in_base_init = []

        # for signal: Thing::StuffHappened (s, u)
        # we want to emit:
        # void tp_svc_thing_emit_stuff_happened (gpointer instance,
        #    const char *arg0, guint arg1);

        dbus_name = signal.getAttribute('name')

        ugly_name = signal.getAttribute('tp:name-for-bindings')
        if dbus_name != ugly_name.replace('_', ''):
            raise AssertionError('Signal %s tp:name-for-bindings (%s) does '
                                 'not match' % (dbus_name, ugly_name))

        stub_name = (self.prefix_ + self.node_name_lc + '_emit_' +
                     ugly_name.lower())

        const_name = self.get_signal_const_entry(signal)

        # Gather arguments
        args = []
        for i in signal.getElementsByTagName('arg'):
            name = i.getAttribute('name')
            dtype = i.getAttribute('type')
            tp_type = i.getAttribute('tp:type')

            if name:
                name = 'arg_' + name
            else:
                name = 'arg' + str(len(args))

            ctype, gtype, marshaller, pointer = type_to_gtype(dtype)

            if pointer:
                ctype = 'const ' + ctype

            struct = (ctype, name, gtype)
            args.append(struct)

        tmp = (['gpointer instance'] +
               [ctype + name for (ctype, name, gtype) in args])

        self.h(('void %s (' % stub_name) + (',\n    '.join(tmp)) + ');')

        # FIXME: emit docs

        self.b('/**')
        self.b(' * %s:' % stub_name)
        self.b(' * @instance: The object implementing this interface')
        for (ctype, name, gtype) in args:
            self.b(' * @%s: %s (FIXME, generate documentation)' %
                   (name, ctype))
        self.b(' *')
        self.b(' * Type-safe wrapper around g_signal_emit to emit the')
        self.b(' * %s signal on interface %s.' % (dbus_name, self.iface_name))
        self.b(' */')

        self.b('void')
        self.b(('%s (' % stub_name) + (',\n    '.join(tmp)) + ')')
        self.b('{')
        self.b('  g_assert (instance != NULL);')
        self.b('  g_assert (G_TYPE_CHECK_INSTANCE_TYPE (instance, %s));' %
               (self.current_gtype))
        tmp = ([
            'instance',
            '%s_signals[%s]' % (self.node_name_lc, const_name), '0'
        ] + [name for (ctype, name, gtype) in args])
        self.b('  g_signal_emit (' + ',\n      '.join(tmp) + ');')
        self.b('}')
        self.b('')

        signal_name = dbus_gutils_wincaps_to_uscore(dbus_name).replace(
            '_', '-')
        in_base_init.append('  /**')
        in_base_init.append('   * %s%s::%s:' %
                            (self.Prefix, self.node_name_mixed, signal_name))
        for (ctype, name, gtype) in args:
            in_base_init.append(
                '   * @%s: %s (FIXME, generate documentation)' % (name, ctype))
        in_base_init.append('   *')
        in_base_init.append('   * The %s D-Bus signal is emitted whenever '
                            'this GObject signal is.' % dbus_name)
        in_base_init.append('   */')
        in_base_init.append('  %s_signals[%s] =' %
                            (self.node_name_lc, const_name))
        in_base_init.append('  g_signal_new ("%s",' % signal_name)
        in_base_init.append('      G_OBJECT_CLASS_TYPE (klass),')
        in_base_init.append('      G_SIGNAL_RUN_LAST|G_SIGNAL_DETAILED,')
        in_base_init.append('      0,')
        in_base_init.append('      NULL, NULL,')
        in_base_init.append(
            '      %s,' %
            signal_to_marshal_name(signal, self.signal_marshal_prefix))
        in_base_init.append('      G_TYPE_NONE,')
        tmp = ['%d' % len(args)] + [gtype for (ctype, name, gtype) in args]
        in_base_init.append('      %s);' % ',\n      '.join(tmp))
        in_base_init.append('')

        return in_base_init