3
# glib-client-gen.py: "I Can't Believe It's Not dbus-binding-tool"
5
# Generate GLib client wrappers from the Telepathy specification.
6
# The master copy of this program is in the telepathy-glib repository -
7
# please make any changes there.
9
# Copyright (C) 2006-2008 Collabora Ltd. <http://www.collabora.co.uk/>
11
# This library is free software; you can redistribute it and/or
12
# modify it under the terms of the GNU Lesser General Public
13
# License as published by the Free Software Foundation; either
14
# version 2.1 of the License, or (at your option) any later version.
16
# This library is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
# Lesser General Public License for more details.
21
# You should have received a copy of the GNU Lesser General Public
22
# License along with this library; if not, write to the Free Software
23
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
import xml.dom.minidom
28
from getopt import gnu_getopt
30
from libglibcodegen import Signature, type_to_gtype, cmp_by_name, \
31
camelcase_to_lower, get_docstring
34
NS_TP = "http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
36
class Generator(object):
38
def __init__(self, dom, prefix, basename, opts):
43
self.prefix_lc = prefix.lower()
44
self.prefix_uc = prefix.upper()
45
self.prefix_mc = prefix.replace('_', '')
46
self.basename = basename
47
self.group = opts.get('--group', None)
48
self.iface_quark_prefix = opts.get('--iface-quark-prefix', None)
49
self.proxy_cls = opts.get('--subclass', 'TpProxy') + ' *'
50
self.proxy_arg = opts.get('--subclass', 'void') + ' *'
51
self.proxy_assert = opts.get('--subclass-assert', 'TP_IS_PROXY')
52
self.proxy_doc = ('A #%s or subclass'
53
% opts.get('--subclass', 'TpProxy'))
54
if self.proxy_arg == 'void *':
55
self.proxy_arg = 'gpointer '
58
self.__header.append(s)
63
def get_iface_quark(self):
64
assert self.iface_dbus is not None
65
assert self.iface_uc is not None
66
if self.iface_quark_prefix is None:
67
return 'g_quark_from_static_string (\"%s\")' % self.iface_dbus
69
return '%s_%s' % (self.iface_quark_prefix, self.iface_uc)
71
def do_signal(self, iface, signal):
72
iface_lc = iface.lower()
74
member = signal.getAttribute('name')
75
member_lc = camelcase_to_lower(member)
76
member_uc = member_lc.upper()
82
for arg in signal.getElementsByTagName('arg'):
83
name = arg.getAttribute('name')
84
type = arg.getAttribute('type')
85
tp_type = arg.getAttribute('tp:type')
88
name = 'arg%u' % arg_count
91
name = 'arg_%s' % name
93
info = type_to_gtype(type)
94
args.append((name, info, tp_type, arg))
96
callback_name = ('%s_%s_signal_callback_%s'
97
% (self.prefix_lc, iface_lc, member_lc))
98
collect_name = ('_%s_%s_collect_args_of_%s'
99
% (self.prefix_lc, iface_lc, member_lc))
100
invoke_name = ('_%s_%s_invoke_callback_for_%s'
101
% (self.prefix_lc, iface_lc, member_lc))
105
# typedef void (*tp_cli_connection_signal_callback_new_channel)
106
# (TpConnection *proxy, const gchar *arg_object_path,
107
# const gchar *arg_channel_type, guint arg_handle_type,
108
# guint arg_handle, gboolean arg_suppress_handler,
109
# gpointer user_data, GObject *weak_object);
112
self.b(' * %s:' % callback_name)
113
self.b(' * @proxy: The proxy on which %s_%s_connect_to_%s ()'
114
% (self.prefix_lc, iface_lc, member_lc))
115
self.b(' * was called')
118
name, info, tp_type, elt = arg
119
ctype, gtype, marshaller, pointer = info
121
self.b(' * @%s: <![CDATA[%s]]>' % (name,
122
get_docstring(elt) or '(Undocumented)'))
124
self.b(' * @user_data: User-supplied data')
125
self.b(' * @weak_object: User-supplied weakly referenced object')
127
self.b(' * Represents the signature of a callback for the signal %s.'
130
self.h('typedef void (*%s) (%sproxy,'
131
% (callback_name, self.proxy_cls))
134
name, info, tp_type, elt = arg
135
ctype, gtype, marshaller, pointer = info
137
const = pointer and 'const ' or ''
139
self.h(' %s%s%s,' % (const, ctype, name))
141
self.h(' gpointer user_data, GObject *weak_object);')
144
self.b('static void')
145
self.b('%s (DBusGProxy *proxy,' % collect_name)
148
name, info, tp_type, elt = arg
149
ctype, gtype, marshaller, pointer = info
151
const = pointer and 'const ' or ''
153
self.b(' %s%s%s,' % (const, ctype, name))
155
self.b(' TpProxySignalConnection *sc)')
157
self.b(' GValueArray *args = g_value_array_new (%d);' % len(args))
158
self.b(' GValue blank = { 0 };')
161
self.b(' g_value_init (&blank, G_TYPE_INT);')
163
self.b(' for (i = 0; i < %d; i++)' % len(args))
164
self.b(' g_value_array_append (args, &blank);')
167
for i, arg in enumerate(args):
168
name, info, tp_type, elt = arg
169
ctype, gtype, marshaller, pointer = info
171
self.b(' g_value_unset (args->values + %d);' % i)
172
self.b(' g_value_init (args->values + %d, %s);' % (i, gtype))
174
if gtype == 'G_TYPE_STRING':
175
self.b(' g_value_set_string (args->values + %d, %s);'
177
elif marshaller == 'BOXED':
178
self.b(' g_value_set_boxed (args->values + %d, %s);'
180
elif gtype == 'G_TYPE_UCHAR':
181
self.b(' g_value_set_uchar (args->values + %d, %s);'
183
elif gtype == 'G_TYPE_BOOLEAN':
184
self.b(' g_value_set_boolean (args->values + %d, %s);'
186
elif gtype == 'G_TYPE_INT':
187
self.b(' g_value_set_int (args->values + %d, %s);'
189
elif gtype == 'G_TYPE_UINT':
190
self.b(' g_value_set_uint (args->values + %d, %s);'
192
elif gtype == 'G_TYPE_INT64':
193
self.b(' g_value_set_int (args->values + %d, %s);'
195
elif gtype == 'G_TYPE_UINT64':
196
self.b(' g_value_set_uint (args->values + %d, %s);'
198
elif gtype == 'G_TYPE_DOUBLE':
199
self.b(' g_value_set_double (args->values + %d, %s);'
202
assert False, ("Don't know how to put %s in a GValue"
206
self.b(' tp_proxy_signal_connection_v0_take_results (sc, args);')
209
self.b('static void')
210
self.b('%s (TpProxy *tpproxy,' % invoke_name)
211
self.b(' GError *error,')
212
self.b(' GValueArray *args,')
213
self.b(' GCallback generic_callback,')
214
self.b(' gpointer user_data,')
215
self.b(' GObject *weak_object)')
217
self.b(' %s callback =' % callback_name)
218
self.b(' (%s) generic_callback;' % callback_name)
220
self.b(' if (callback != NULL)')
221
self.b(' callback (g_object_ref (tpproxy),')
223
# FIXME: factor out into a function
224
for i, arg in enumerate(args):
225
name, info, tp_type, elt = arg
226
ctype, gtype, marshaller, pointer = info
228
if marshaller == 'BOXED':
229
self.b(' g_value_get_boxed (args->values + %d),' % i)
230
elif gtype == 'G_TYPE_STRING':
231
self.b(' g_value_get_string (args->values + %d),' % i)
232
elif gtype == 'G_TYPE_UCHAR':
233
self.b(' g_value_get_uchar (args->values + %d),' % i)
234
elif gtype == 'G_TYPE_BOOLEAN':
235
self.b(' g_value_get_boolean (args->values + %d),' % i)
236
elif gtype == 'G_TYPE_UINT':
237
self.b(' g_value_get_uint (args->values + %d),' % i)
238
elif gtype == 'G_TYPE_INT':
239
self.b(' g_value_get_int (args->values + %d),' % i)
240
elif gtype == 'G_TYPE_UINT64':
241
self.b(' g_value_get_uint64 (args->values + %d),' % i)
242
elif gtype == 'G_TYPE_INT64':
243
self.b(' g_value_get_int64 (args->values + %d),' % i)
244
elif gtype == 'G_TYPE_DOUBLE':
245
self.b(' g_value_get_double (args->values + %d),' % i)
247
assert False, "Don't know how to get %s from a GValue" % gtype
249
self.b(' user_data,')
250
self.b(' weak_object);')
254
self.b(' g_value_array_free (args);')
256
self.b(' if (args != NULL)')
257
self.b(' g_value_array_free (args);')
260
self.b(' g_object_unref (tpproxy);')
265
# TpProxySignalConnection *
266
# tp_cli_connection_connect_to_new_channel
267
# (TpConnection *proxy,
268
# tp_cli_connection_signal_callback_new_channel callback,
269
# gpointer user_data,
270
# GDestroyNotify destroy);
272
# destroy is invoked when the signal becomes disconnected. This
273
# is either because the signal has been disconnected explicitly
274
# by the user, because the TpProxy has become invalid and
275
# emitted the 'invalidated' signal, or because the weakly referenced
276
# object has gone away.
279
self.b(' * %s_%s_connect_to_%s:'
280
% (self.prefix_lc, iface_lc, member_lc))
281
self.b(' * @proxy: %s' % self.proxy_doc)
282
self.b(' * @callback: Callback to be called when the signal is')
283
self.b(' * received')
284
self.b(' * @user_data: User-supplied data for the callback')
285
self.b(' * @destroy: Destructor for the user-supplied data, which')
286
self.b(' * will be called when this signal is disconnected, or')
287
self.b(' * before this function returns %NULL')
288
self.b(' * @weak_object: A #GObject which will be weakly referenced; ')
289
self.b(' * if it is destroyed, this callback will automatically be')
290
self.b(' * disconnected')
291
self.b(' * @error: If not %NULL, used to raise an error if %NULL is')
292
self.b(' * returned')
294
self.b(' * Connect a handler to the signal %s.' % member)
296
self.b(' * <![CDATA[%s]]>'
297
% (get_docstring(signal) or '(Undocumented)'))
299
self.b(' * Returns: a #TpProxySignalConnection containing all of the')
300
self.b(' * above, which can be used to disconnect the signal; or')
301
self.b(' * %NULL if the proxy does not have the desired interface')
302
self.b(' * or has become invalid.')
304
self.h('TpProxySignalConnection *%s_%s_connect_to_%s (%sproxy,'
305
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
306
self.h(' %s callback,' % callback_name)
307
self.h(' gpointer user_data,')
308
self.h(' GDestroyNotify destroy,')
309
self.h(' GObject *weak_object,')
310
self.h(' GError **error);')
312
self.b('TpProxySignalConnection *')
313
self.b('%s_%s_connect_to_%s (%sproxy,'
314
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
315
self.b(' %s callback,' % callback_name)
316
self.b(' gpointer user_data,')
317
self.b(' GDestroyNotify destroy,')
318
self.b(' GObject *weak_object,')
319
self.b(' GError **error)')
321
self.b(' GType expected_types[%d] = {' % (len(args) + 1))
324
name, info, tp_type, elt = arg
325
ctype, gtype, marshaller, pointer = info
327
self.b(' %s,' % gtype)
329
self.b(' G_TYPE_INVALID };')
331
self.b(' g_return_val_if_fail (%s (proxy), NULL);'
333
self.b(' g_return_val_if_fail (callback != NULL, NULL);')
335
self.b(' return tp_proxy_signal_connection_v0_new ((TpProxy *) proxy,')
336
self.b(' %s, \"%s\",' % (self.get_iface_quark(), member))
337
self.b(' expected_types,')
340
self.b(' G_CALLBACK (%s),' % collect_name)
342
self.b(' NULL, /* no args => no collector function */')
344
self.b(' %s,' % invoke_name)
345
self.b(' G_CALLBACK (callback), user_data, destroy,')
346
self.b(' weak_object, error);')
352
def do_method(self, iface, method):
353
iface_lc = iface.lower()
355
member = method.getAttribute('name')
356
member_lc = camelcase_to_lower(member)
357
member_uc = member_lc.upper()
364
for arg in method.getElementsByTagName('arg'):
365
name = arg.getAttribute('name')
366
direction = arg.getAttribute('direction')
367
type = arg.getAttribute('type')
368
tp_type = arg.getAttribute('tp:type')
370
if direction != 'out':
372
name = 'in%u' % in_count
375
name = 'in_%s' % name
378
name = 'out%u' % ret_count
381
name = 'out_%s' % name
383
info = type_to_gtype(type)
384
if direction != 'out':
385
in_args.append((name, info, tp_type, arg))
387
out_args.append((name, info, tp_type, arg))
389
# Async reply callback type
392
# void (*tp_cli_properties_interface_callback_for_get_properties)
394
# const GPtrArray *out0,
395
# const GError *error,
396
# gpointer user_data,
397
# GObject *weak_object);
400
self.b(' * %s_%s_callback_for_%s:'
401
% (self.prefix_lc, iface_lc, member_lc))
402
self.b(' * @proxy: the proxy on which the call was made')
405
name, info, tp_type, elt = arg
406
ctype, gtype, marshaller, pointer = info
408
self.b(' * @%s: Used to return an \'out\' argument if @error is '
409
'%%NULL: <![CDATA[%s]]>'
410
% (name, get_docstring(elt) or '(Undocumented)'))
412
self.b(' * @error: %NULL on success, or an error on failure')
413
self.b(' * @user_data: user-supplied data')
414
self.b(' * @weak_object: user-supplied object')
416
self.b(' * Signature of the callback called when a %s method call'
418
self.b(' * succeeds or fails.')
421
callback_name = '%s_%s_callback_for_%s' % (self.prefix_lc, iface_lc,
424
self.h('typedef void (*%s) (%sproxy,'
425
% (callback_name, self.proxy_cls))
428
name, info, tp_type, elt = arg
429
ctype, gtype, marshaller, pointer = info
430
const = pointer and 'const ' or ''
432
self.h(' %s%s%s,' % (const, ctype, name))
434
self.h(' const GError *error, gpointer user_data,')
435
self.h(' GObject *weak_object);')
438
# Async callback implementation
440
invoke_callback = '_%s_%s_invoke_callback_%s' % (self.prefix_lc,
444
collect_callback = '_%s_%s_collect_callback_%s' % (self.prefix_lc,
448
# The callback called by dbus-glib; this ends the call and collects
449
# the results into a GValueArray.
450
self.b('static void')
451
self.b('%s (DBusGProxy *proxy,' % collect_callback)
452
self.b(' DBusGProxyCall *call,')
453
self.b(' gpointer user_data)')
455
self.b(' GError *error = NULL;')
457
if len(out_args) > 0:
458
self.b(' GValueArray *args;')
459
self.b(' GValue blank = { 0 };')
463
name, info, tp_type, elt = arg
464
ctype, gtype, marshaller, pointer = info
466
self.b(' %s%s;' % (ctype, name))
469
self.b(' dbus_g_proxy_end_call (proxy, call, &error,')
472
name, info, tp_type, elt = arg
473
ctype, gtype, marshaller, pointer = info
475
self.b(' %s, &%s,' % (gtype, name))
477
self.b(' G_TYPE_INVALID);')
479
if len(out_args) == 0:
480
self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,'
484
self.b(' if (error != NULL)')
486
self.b(' tp_proxy_pending_call_v0_take_results (user_data, error,')
491
self.b(' args = g_value_array_new (%d);' % len(out_args))
492
self.b(' g_value_init (&blank, G_TYPE_INT);')
494
self.b(' for (i = 0; i < %d; i++)' % len(out_args))
495
self.b(' g_value_array_append (args, &blank);')
497
for i, arg in enumerate(out_args):
498
name, info, tp_type, elt = arg
499
ctype, gtype, marshaller, pointer = info
502
self.b(' g_value_unset (args->values + %d);' % i)
503
self.b(' g_value_init (args->values + %d, %s);' % (i, gtype))
505
if gtype == 'G_TYPE_STRING':
506
self.b(' g_value_take_string (args->values + %d, %s);'
508
elif marshaller == 'BOXED':
509
self.b(' g_value_take_boxed (args->values + %d, %s);'
511
elif gtype == 'G_TYPE_UCHAR':
512
self.b(' g_value_set_uchar (args->values + %d, %s);'
514
elif gtype == 'G_TYPE_BOOLEAN':
515
self.b(' g_value_set_boolean (args->values + %d, %s);'
517
elif gtype == 'G_TYPE_INT':
518
self.b(' g_value_set_int (args->values + %d, %s);'
520
elif gtype == 'G_TYPE_UINT':
521
self.b(' g_value_set_uint (args->values + %d, %s);'
523
elif gtype == 'G_TYPE_INT64':
524
self.b(' g_value_set_int (args->values + %d, %s);'
526
elif gtype == 'G_TYPE_UINT64':
527
self.b(' g_value_set_uint (args->values + %d, %s);'
529
elif gtype == 'G_TYPE_DOUBLE':
530
self.b(' g_value_set_double (args->values + %d, %s);'
533
assert False, ("Don't know how to put %s in a GValue"
536
self.b(' tp_proxy_pending_call_v0_take_results (user_data, '
541
self.b('static void')
542
self.b('%s (TpProxy *self,' % invoke_callback)
543
self.b(' GError *error,')
544
self.b(' GValueArray *args,')
545
self.b(' GCallback generic_callback,')
546
self.b(' gpointer user_data,')
547
self.b(' GObject *weak_object)')
549
self.b(' %s callback = (%s) generic_callback;'
550
% (callback_name, callback_name))
552
self.b(' if (error != NULL)')
554
self.b(' callback ((%s) self,' % self.proxy_cls)
557
name, info, tp_type, elt = arg
558
ctype, gtype, marshaller, pointer = info
560
if marshaller == 'BOXED' or pointer:
562
elif gtype == 'G_TYPE_DOUBLE':
567
self.b(' error, user_data, weak_object);')
568
self.b(' g_error_free (error);')
572
self.b(' callback ((%s) self,' % self.proxy_cls)
574
# FIXME: factor out into a function
575
for i, arg in enumerate(out_args):
576
name, info, tp_type, elt = arg
577
ctype, gtype, marshaller, pointer = info
579
if marshaller == 'BOXED':
580
self.b(' g_value_get_boxed (args->values + %d),' % i)
581
elif gtype == 'G_TYPE_STRING':
582
self.b(' g_value_get_string (args->values + %d),' % i)
583
elif gtype == 'G_TYPE_UCHAR':
584
self.b(' g_value_get_uchar (args->values + %d),' % i)
585
elif gtype == 'G_TYPE_BOOLEAN':
586
self.b(' g_value_get_boolean (args->values + %d),' % i)
587
elif gtype == 'G_TYPE_UINT':
588
self.b(' g_value_get_uint (args->values + %d),' % i)
589
elif gtype == 'G_TYPE_INT':
590
self.b(' g_value_get_int (args->values + %d),' % i)
591
elif gtype == 'G_TYPE_UINT64':
592
self.b(' g_value_get_uint64 (args->values + %d),' % i)
593
elif gtype == 'G_TYPE_INT64':
594
self.b(' g_value_get_int64 (args->values + %d),' % i)
595
elif gtype == 'G_TYPE_DOUBLE':
596
self.b(' g_value_get_double (args->values + %d),' % i)
598
assert False, "Don't know how to get %s from a GValue" % gtype
600
self.b(' error, user_data, weak_object);')
603
if len(out_args) > 0:
604
self.b(' g_value_array_free (args);')
606
self.b(' if (args != NULL)')
607
self.b(' g_value_array_free (args);')
615
# TpProxyPendingCall *
616
# tp_cli_properties_interface_call_get_properties
619
# const GArray *in_properties,
620
# tp_cli_properties_interface_callback_for_get_properties callback,
621
# gpointer user_data,
622
# GDestroyNotify *destructor);
624
self.h('TpProxyPendingCall *%s_%s_call_%s (%sproxy,'
625
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
626
self.h(' gint timeout_ms,')
629
self.b(' * %s_%s_call_%s:'
630
% (self.prefix_lc, iface_lc, member_lc))
631
self.b(' * @proxy: the #TpProxy')
632
self.b(' * @timeout_ms: the timeout in milliseconds, or -1 to use the')
636
name, info, tp_type, elt = arg
637
ctype, gtype, marshaller, pointer = info
639
self.b(' * @%s: Used to pass an \'in\' argument: <![CDATA[%s]]>'
640
% (name, get_docstring(elt) or '(Undocumented)'))
642
self.b(' * @callback: called when the method call succeeds or fails')
643
self.b(' * @user_data: user-supplied data passed to the callback')
644
self.b(' * @destroy: called with the user_data as argument, after the')
645
self.b(' * call has succeeded, failed or been cancelled')
646
self.b(' * @weak_object: A #GObject which will be weakly referenced; ')
647
self.b(' * if it is destroyed, this callback will automatically be')
648
self.b(' * disconnected')
650
self.b(' * Start a %s method call.' % member)
652
self.b(' * <![CDATA[%s]]>'
653
% (get_docstring(method) or '(Undocumented)'))
655
self.b(' * Returns: a #TpProxyPendingCall representing the call in')
656
self.b(' * progress. It is borrowed from the object, and will become')
657
self.b(' * invalid when the callback is called, the call is')
658
self.b(' * cancelled or the #TpProxy becomes invalid.')
660
self.b('TpProxyPendingCall *\n%s_%s_call_%s (%sproxy,'
661
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
662
self.b(' gint timeout_ms,')
665
name, info, tp_type, elt = arg
666
ctype, gtype, marshaller, pointer = info
668
const = pointer and 'const ' or ''
670
self.h(' %s%s%s,' % (const, ctype, name))
671
self.b(' %s%s%s,' % (const, ctype, name))
673
self.h(' %s callback,' % callback_name)
674
self.h(' gpointer user_data,')
675
self.h(' GDestroyNotify destroy,')
676
self.h(' GObject *weak_object);')
679
self.b(' %s callback,' % callback_name)
680
self.b(' gpointer user_data,')
681
self.b(' GDestroyNotify destroy,')
682
self.b(' GObject *weak_object)')
684
self.b(' GError *error = NULL;')
685
self.b(' GQuark interface = %s;' % self.get_iface_quark())
686
self.b(' DBusGProxy *iface;')
688
self.b(' g_return_val_if_fail (%s (proxy), NULL);'
691
self.b(' iface = tp_proxy_borrow_interface_by_id (')
692
self.b(' (TpProxy *) proxy,')
693
self.b(' interface, &error);')
695
self.b(' if (iface == NULL)')
697
self.b(' if (callback != NULL)')
698
self.b(' callback (proxy,')
701
name, info, tp_type, elt = arg
702
ctype, gtype, marshaller, pointer = info
709
self.b(' error, user_data, weak_object);')
710
self.b(' g_error_free (error);')
711
self.b(' return NULL;')
714
self.b(' if (callback == NULL)')
716
self.b(' dbus_g_proxy_call_no_reply (iface, "%s",' % member)
719
name, info, tp_type, elt = arg
720
ctype, gtype, marshaller, pointer = info
722
const = pointer and 'const ' or ''
724
self.b(' %s, %s,' % (gtype, name))
726
self.b(' G_TYPE_INVALID);')
727
self.b(' return NULL;')
731
self.b(' TpProxyPendingCall *data;')
733
self.b(' data = tp_proxy_pending_call_v0_new ((TpProxy *) proxy,')
734
self.b(' interface, "%s", iface,' % member)
735
self.b(' %s,' % invoke_callback)
736
self.b(' G_CALLBACK (callback), user_data, destroy,')
737
self.b(' weak_object, FALSE);')
738
self.b(' tp_proxy_pending_call_v0_take_pending_call (data,')
739
self.b(' dbus_g_proxy_begin_call_with_timeout (iface,')
740
self.b(' "%s",' % member)
741
self.b(' %s,' % collect_callback)
743
self.b(' tp_proxy_pending_call_v0_completed,')
744
self.b(' timeout_ms,')
747
name, info, tp_type, elt = arg
748
ctype, gtype, marshaller, pointer = info
750
const = pointer and 'const ' or ''
752
self.b(' %s, %s,' % (gtype, name))
754
self.b(' G_TYPE_INVALID));')
756
self.b(' return data;')
761
# Non reentrant blocking calls
763
# gboolean tp_cli_properties_interface_do_get_properties
766
# const GArray *in_properties,
770
self.h('gboolean %s_%s_do_%s (%sproxy,'
771
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
772
self.h(' gint timeout_ms,')
775
self.b(' * %s_%s_do_%s:' % (self.prefix_lc, iface_lc, member_lc))
776
self.b(' * @proxy: %s' % self.proxy_doc)
777
self.b(' * @timeout_ms: Timeout in milliseconds, or -1 for default')
780
name, info, tp_type, elt = arg
781
ctype, gtype, marshaller, pointer = info
783
self.b(' * @%s: Used to pass an \'in\' argument: <![CDATA[%s]]>'
784
% (name, get_docstring(elt) or '(Undocumented)'))
787
name, info, tp_type, elt = arg
788
ctype, gtype, marshaller, pointer = info
790
self.b(' * @%s: Used to return an \'out\' argument if %%TRUE is '
791
'returned: <![CDATA[%s]]>'
792
% (name, get_docstring(elt) or '(Undocumented)'))
794
self.b(' * @error: If not %NULL, used to return errors if %FALSE ')
795
self.b(' * is returned')
797
self.b(' * Call the method %s and block' % member)
798
self.b(' * until it returns.')
800
self.b(' * <![CDATA[%s]]>'
801
% (get_docstring(method) or '(Undocumented)'))
803
self.b(' * Returns: TRUE on success, FALSE and sets @error on error')
805
self.b('gboolean\n%s_%s_do_%s (%sproxy,'
806
% (self.prefix_lc, iface_lc, member_lc, self.proxy_arg))
807
self.b(' gint timeout_ms,')
810
name, info, tp_type, elt = arg
811
ctype, gtype, marshaller, pointer = info
813
const = pointer and 'const ' or ''
815
self.h(' %s%s%s,' % (const, ctype, name))
816
self.b(' %s%s%s,' % (const, ctype, name))
819
name, info, tp_type, elt = arg
820
ctype, gtype, marshaller, pointer = info
822
self.h(' %s*%s,' % (ctype, name))
823
self.b(' %s*%s,' % (ctype, name))
825
self.h(' GError **error);')
828
self.b(' GError **error)')
830
self.b(' DBusGProxy *iface;')
831
self.b(' GQuark interface = %s;' % self.get_iface_quark())
833
name, info, tp_type, elt = arg
834
ctype, gtype, marshaller, pointer = info
836
self.b(' %si_%s;' % (ctype, name))
838
self.b(' g_return_val_if_fail (%s (proxy), FALSE);'
841
self.b(' iface = tp_proxy_borrow_interface_by_id')
842
self.b(' ((TpProxy *) proxy, interface, error);')
844
self.b(' if (iface == NULL)')
845
self.b(' return FALSE;')
847
self.b(' if (dbus_g_proxy_call_with_timeout (iface,')
848
self.b(' "%s",' % member)
849
self.b(' timeout_ms,')
853
name, info, tp_type, elt = arg
854
ctype, gtype, marshaller, pointer = info
856
const = pointer and 'const ' or ''
858
self.b(' %s, %s,' % (gtype, name))
860
self.b(' G_TYPE_INVALID,')
863
name, info, tp_type, elt = arg
864
ctype, gtype, marshaller, pointer = info
866
self.b(' %s, &i_%s,' % (gtype, name))
867
self.b(' G_TYPE_INVALID))')
870
name, info, tp_type, elt = arg
871
ctype, gtype, marshaller, pointer = info
873
self.b(' *%s = i_%s;' % (name, name))
874
self.b(' return TRUE;')
877
self.b(' return FALSE;')
881
# leave a gap for the end of the method
885
def do_signal_add(self, signal):
886
marshaller_items = []
889
for i in signal.getElementsByTagName('arg'):
890
name = i.getAttribute('name')
891
type = i.getAttribute('type')
892
info = type_to_gtype(type)
893
# type, GType, STRING, is a pointer
894
gtypes.append(info[1])
896
self.b(' dbus_g_proxy_add_signal (proxy, "%s",'
897
% signal.getAttribute('name'))
899
self.b(' %s,' % gtype)
900
self.b(' G_TYPE_INVALID);')
902
def do_interface(self, node):
903
ifaces = node.getElementsByTagName('interface')
904
assert len(ifaces) == 1
906
name = node.getAttribute('name').replace('/', '')
909
self.iface_lc = name.lower()
910
self.iface_uc = name.upper()
911
self.iface_mc = name.replace('_', '')
912
self.iface_dbus = iface.getAttribute('name')
914
signals = node.getElementsByTagName('signal')
915
methods = node.getElementsByTagName('method')
917
self.b('static inline void')
918
self.b('%s_add_signals_for_%s (DBusGProxy *proxy)'
919
% (self.prefix_lc, name.lower()))
922
for signal in signals:
923
self.do_signal_add(signal)
929
for signal in signals:
930
self.do_signal(name, signal)
932
for method in methods:
933
self.do_method(name, method)
935
self.iface_dbus = None
939
self.h('G_BEGIN_DECLS')
942
self.b('/* We don\'t want gtkdoc scanning this file, it\'ll get')
943
self.b(' * confused by seeing function definitions, so mark it as: */')
944
self.b('/*<private_header>*/')
947
nodes = self.dom.getElementsByTagName('node')
948
nodes.sort(cmp_by_name)
951
self.do_interface(node)
953
if self.group is not None:
956
self.b(' * %s_%s_add_signals:' % (self.prefix_lc, self.group))
957
self.b(' * @self: the #TpProxy')
958
self.b(' * @quark: a quark whose string value is the interface')
959
self.b(' * name whose signals should be added')
960
self.b(' * @proxy: the D-Bus proxy to which to add the signals')
961
self.b(' * @unused: not used for anything')
963
self.b(' * Tell dbus-glib that @proxy has the signatures of all')
964
self.b(' * signals on the given interface, if it\'s one we')
965
self.b(' * support.')
967
self.b(' * This function should be used as a signal handler for')
968
self.b(' * #TpProxy::interface-added.')
970
self.b('static void')
971
self.b('%s_%s_add_signals (TpProxy *self,'
972
% (self.prefix_lc, self.group))
973
self.b(' guint quark,')
974
self.b(' DBusGProxy *proxy,')
975
self.b(' gpointer unused)')
980
iface = node.getElementsByTagName('interface')[0]
981
self.iface_dbus = iface.getAttribute('name')
982
name = node.getAttribute('name').replace('/', '').lower()
983
self.iface_uc = name.upper()
984
self.b(' if (quark == %s)' % self.get_iface_quark())
985
self.b(' %s_add_signals_for_%s (proxy);'
986
% (self.prefix_lc, name))
991
self.h('G_END_DECLS')
994
open(self.basename + '.h', 'w').write('\n'.join(self.__header))
995
open(self.basename + '-body.h', 'w').write('\n'.join(self.__body))
998
def types_to_gtypes(types):
999
return [type_to_gtype(t)[1] for t in types]
1002
if __name__ == '__main__':
1003
options, argv = gnu_getopt(sys.argv[1:], '',
1004
['group=', 'subclass=', 'subclass-assert=',
1005
'iface-quark-prefix='])
1009
for option, value in options:
1010
opts[option] = value
1012
dom = xml.dom.minidom.parse(argv[0])
1014
Generator(dom, argv[1], argv[2], opts)()