GVariant: add g_variant_take_ref()
[platform/upstream/glib.git] / gio / gdbus-codegen / codegen.py
1 # -*- Mode: Python -*-
2
3 # GDBus - GLib D-Bus Library
4 #
5 # Copyright (C) 2008-2011 Red Hat, Inc.
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General
18 # Public License along with this library; if not, write to the
19 # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 # Boston, MA 02111-1307, USA.
21 #
22 # Author: David Zeuthen <davidz@redhat.com>
23
24 import sys
25
26 import config
27 import utils
28 import dbustypes
29
30 # ----------------------------------------------------------------------------------------------------
31
32 class CodeGenerator:
33     def __init__(self, ifaces, namespace, interface_prefix, generate_objmanager, docbook_gen, h, c):
34         self.docbook_gen = docbook_gen
35         self.generate_objmanager = generate_objmanager
36         self.ifaces = ifaces
37         self.h = h
38         self.c = c
39         self.namespace = namespace
40         if len(namespace) > 1:
41             self.ns_upper = utils.camel_case_to_uscore(namespace).upper() + '_'
42             self.ns_lower = utils.camel_case_to_uscore(namespace).lower() + '_'
43         else:
44             self.ns_upper = ''
45             self.ns_lower = ''
46         self.interface_prefix = interface_prefix
47         self.header_guard = self.h.name.upper().replace('.', '_').replace('-', '_')
48
49     # ----------------------------------------------------------------------------------------------------
50
51     def generate_intro(self):
52         self.c.write('/*\n'
53                      ' * Generated by gdbus-codegen %s. DO NOT EDIT.\n'
54                      ' *\n'
55                      ' * The license of this code is the same as for the source it was derived from.\n'
56                      ' */\n'
57                      '\n'
58                      %(config.VERSION))
59         self.c.write('#ifdef HAVE_CONFIG_H\n'
60                      '#  include "config.h"\n'
61                      '#endif\n'
62                      '\n'
63                      '#include "%s"\n'
64                      '\n'%(self.h.name))
65
66         self.c.write('typedef struct\n'
67                      '{\n'
68                      '  GDBusArgInfo parent_struct;\n'
69                      '  gboolean use_gvariant;\n'
70                      '} _ExtendedGDBusArgInfo;\n'
71                      '\n')
72
73         self.c.write('typedef struct\n'
74                      '{\n'
75                      '  GDBusMethodInfo parent_struct;\n'
76                      '  const gchar *signal_name;\n'
77                      '} _ExtendedGDBusMethodInfo;\n'
78                      '\n')
79
80         self.c.write('typedef struct\n'
81                      '{\n'
82                      '  GDBusSignalInfo parent_struct;\n'
83                      '  const gchar *signal_name;\n'
84                      '} _ExtendedGDBusSignalInfo;\n'
85                      '\n')
86
87         self.c.write('typedef struct\n'
88                      '{\n'
89                      '  GDBusPropertyInfo parent_struct;\n'
90                      '  const gchar *hyphen_name;\n'
91                      '  gboolean use_gvariant;\n'
92                      '} _ExtendedGDBusPropertyInfo;\n'
93                      '\n')
94
95         self.c.write('typedef struct\n'
96                      '{\n'
97                      '  GDBusInterfaceInfo parent_struct;\n'
98                      '  const gchar *hyphen_name;\n'
99                      '} _ExtendedGDBusInterfaceInfo;\n'
100                      '\n')
101
102         self.c.write('typedef struct\n'
103                      '{\n'
104                      '  const _ExtendedGDBusPropertyInfo *info;\n'
105                      '  guint prop_id;\n'
106                      '  GValue orig_value; /* the value before the change */\n'
107                      '} ChangedProperty;\n'
108                      '\n'
109                      'static void\n'
110                      '_changed_property_free (ChangedProperty *data)\n'
111                      '{\n'
112                      '  g_value_unset (&data->orig_value);\n'
113                      '  g_free (data);\n'
114                      '}\n'
115                      '\n')
116
117         self.c.write('static gboolean\n'
118                      '_g_strv_equal0 (gchar **a, gchar **b)\n'
119                      '{\n'
120                      '  gboolean ret = FALSE;\n'
121                      '  guint n;\n'
122                      '  if (a == NULL && b == NULL)\n'
123                      '    {\n'
124                      '      ret = TRUE;\n'
125                      '      goto out;\n'
126                      '    }\n'
127                      '  if (a == NULL || b == NULL)\n'
128                      '    goto out;\n'
129                      '  if (g_strv_length (a) != g_strv_length (b))\n'
130                      '    goto out;\n'
131                      '  for (n = 0; a[n] != NULL; n++)\n'
132                      '    if (g_strcmp0 (a[n], b[n]) != 0)\n'
133                      '      goto out;\n'
134                      '  ret = TRUE;\n'
135                      'out:\n'
136                      '  return ret;\n'
137                      '}\n'
138                      '\n')
139
140         self.c.write('static gboolean\n'
141                      '_g_variant_equal0 (GVariant *a, GVariant *b)\n'
142                      '{\n'
143                      '  gboolean ret = FALSE;\n'
144                      '  if (a == NULL && b == NULL)\n'
145                      '    {\n'
146                      '      ret = TRUE;\n'
147                      '      goto out;\n'
148                      '    }\n'
149                      '  if (a == NULL || b == NULL)\n'
150                      '    goto out;\n'
151                      '  ret = g_variant_equal (a, b);\n'
152                      'out:\n'
153                      '  return ret;\n'
154                      '}\n'
155                      '\n')
156
157         # simplified - only supports the types we use
158         self.c.write('G_GNUC_UNUSED static gboolean\n'
159                      '_g_value_equal (const GValue *a, const GValue *b)\n'
160                      '{\n'
161                      '  gboolean ret = FALSE;\n'
162                      '  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n'
163                      '  switch (G_VALUE_TYPE (a))\n'
164                      '    {\n'
165                      '      case G_TYPE_BOOLEAN:\n'
166                      '        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n'
167                      '        break;\n'
168                      '      case G_TYPE_UCHAR:\n'
169                      '        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n'
170                      '        break;\n'
171                      '      case G_TYPE_INT:\n'
172                      '        ret = (g_value_get_int (a) == g_value_get_int (b));\n'
173                      '        break;\n'
174                      '      case G_TYPE_UINT:\n'
175                      '        ret = (g_value_get_uint (a) == g_value_get_uint (b));\n'
176                      '        break;\n'
177                      '      case G_TYPE_INT64:\n'
178                      '        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n'
179                      '        break;\n'
180                      '      case G_TYPE_UINT64:\n'
181                      '        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n'
182                      '        break;\n'
183                      '      case G_TYPE_DOUBLE:\n'
184                      '        ret = (g_value_get_double (a) == g_value_get_double (b));\n'
185                      '        break;\n'
186                      '      case G_TYPE_STRING:\n'
187                      '        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n'
188                      '        break;\n'
189                      '      case G_TYPE_VARIANT:\n'
190                      '        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n'
191                      '        break;\n'
192                      '      default:\n'
193                      '        if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n'
194                      '          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n'
195                      '        else\n'
196                      '          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
197                      '        break;\n'
198                      '    }\n'
199                      '  return ret;\n'
200                      '}\n'
201                      '\n')
202
203         self.h.write('/*\n'
204                      ' * Generated by gdbus-codegen %s. DO NOT EDIT.\n'
205                      ' *\n'
206                      ' * The license of this code is the same as for the source it was derived from.\n'
207                      ' */\n'
208                      '\n'
209                      '#ifndef __%s__\n'
210                      '#define __%s__\n'
211                      '\n'%(config.VERSION, self.header_guard, self.header_guard))
212         self.h.write('#include <gio/gio.h>\n'
213                      '\n'
214                      'G_BEGIN_DECLS\n'
215                      '\n')
216
217     # ----------------------------------------------------------------------------------------------------
218
219     def declare_types(self):
220         for i in self.ifaces:
221             self.h.write('\n')
222             self.h.write('/* ------------------------------------------------------------------------ */\n')
223             self.h.write('/* Declarations for %s */\n'%i.name)
224             self.h.write('\n')
225
226             # First the GInterface
227             self.h.write('#define %sTYPE_%s (%s_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
228             self.h.write('#define %s%s(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s, %s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
229             self.h.write('#define %sIS_%s(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
230             self.h.write('#define %s%s_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_%s, %s))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
231             self.h.write('\n')
232             self.h.write('struct _%s;\n'%(i.camel_name))
233             self.h.write('typedef struct _%s %s;\n'%(i.camel_name, i.camel_name))
234             self.h.write('typedef struct _%sIface %sIface;\n'%(i.camel_name, i.camel_name))
235             self.h.write('\n')
236             self.h.write('struct _%sIface\n'%(i.camel_name))
237             self.h.write('{\n')
238             self.h.write('  GTypeInterface parent_iface;\n')
239
240             function_pointers = {}
241
242             if len(i.methods) > 0:
243                 self.h.write('\n')
244                 for m in i.methods:
245                     key = (m.since, '_method_%s'%m.name_lower)
246                     value  = '  gboolean (*handle_%s) (\n'%(m.name_lower)
247                     value += '    %s *object,\n'%(i.camel_name)
248                     value += '    GDBusMethodInvocation *invocation'%()
249                     for a in m.in_args:
250                         value += ',\n    %s%s'%(a.ctype_in, a.name)
251                     value += ');\n\n'
252                     function_pointers[key] = value
253
254             if len(i.signals) > 0:
255                 self.h.write('\n')
256                 for s in i.signals:
257                     key = (s.since, '_signal_%s'%s.name_lower)
258                     value  = '  void (*%s) (\n'%(s.name_lower)
259                     value += '    %s *object'%(i.camel_name)
260                     for a in s.args:
261                         value += ',\n    %s%s'%(a.ctype_in, a.name)
262                     value += ');\n\n'
263                     function_pointers[key] = value
264
265             # Sort according to @since tag, then name.. this ensures
266             # that the function pointers don't change order assuming
267             # judicious use of @since
268             #
269             # Also use a proper version comparison function so e.g.
270             # 10.0 comes after 2.0.
271             #
272             # See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5
273             # for discussion
274             keys = function_pointers.keys()
275             if len(keys) > 0:
276                 keys.sort(cmp=utils.my_version_cmp)
277                 for key in keys:
278                     self.h.write('%s'%function_pointers[key])
279
280             self.h.write('};\n')
281             self.h.write('\n')
282             self.h.write('GType %s_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
283             self.h.write('\n')
284             self.h.write('GDBusInterfaceInfo *%s_interface_info (void);\n'%(i.name_lower))
285             if len(i.properties) > 0:
286                 self.h.write('guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n'%(i.name_lower))
287             self.h.write('\n')
288
289             # Then method call completion functions
290             if len(i.methods) > 0:
291                 self.h.write('\n')
292                 self.h.write('/* D-Bus method call completion functions: */\n')
293                 for m in i.methods:
294                     if m.deprecated:
295                         self.h.write('G_GNUC_DEPRECATED ')
296                     self.h.write('void %s_complete_%s (\n'
297                                  '    %s *object,\n'
298                                  '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
299                     for a in m.out_args:
300                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
301                     self.h.write(');\n')
302                     self.h.write('\n')
303                 self.h.write('\n')
304
305             # Then signal emission functions
306             if len(i.signals) > 0:
307                 self.h.write('\n')
308                 self.h.write('/* D-Bus signal emissions functions: */\n')
309                 for s in i.signals:
310                     if s.deprecated:
311                         self.h.write('G_GNUC_DEPRECATED ')
312                     self.h.write('void %s_emit_%s (\n'
313                                  '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
314                     for a in s.args:
315                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
316                     self.h.write(');\n')
317                     self.h.write('\n')
318                 self.h.write('\n')
319
320             # Then method call declarations
321             if len(i.methods) > 0:
322                 self.h.write('\n')
323                 self.h.write('/* D-Bus method calls: */\n')
324                 for m in i.methods:
325                     # async begin
326                     if m.deprecated:
327                         self.h.write('G_GNUC_DEPRECATED ')
328                     self.h.write('void %s_call_%s (\n'
329                                  '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
330                     for a in m.in_args:
331                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
332                     self.h.write(',\n'
333                                  '    GCancellable *cancellable,\n'
334                                  '    GAsyncReadyCallback callback,\n'
335                                  '    gpointer user_data);\n')
336                     self.h.write('\n')
337                     # async finish
338                     if m.deprecated:
339                         self.h.write('G_GNUC_DEPRECATED ')
340                     self.h.write('gboolean %s_call_%s_finish (\n'
341                                  '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
342                     for a in m.out_args:
343                         self.h.write(',\n    %sout_%s'%(a.ctype_out, a.name))
344                     self.h.write(',\n'
345                                  '    GAsyncResult *res,\n'
346                                  '    GError **error);\n')
347                     self.h.write('\n')
348                     # sync
349                     if m.deprecated:
350                         self.h.write('G_GNUC_DEPRECATED ')
351                     self.h.write('gboolean %s_call_%s_sync (\n'
352                                  '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
353                     for a in m.in_args:
354                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
355                     for a in m.out_args:
356                         self.h.write(',\n    %sout_%s'%(a.ctype_out, a.name))
357                     self.h.write(',\n'
358                                  '    GCancellable *cancellable,\n'
359                                  '    GError **error);\n')
360                     self.h.write('\n')
361                 self.h.write('\n')
362
363             # Then the property accessor declarations
364             if len(i.properties) > 0:
365                 self.h.write('\n')
366                 self.h.write('/* D-Bus property accessors: */\n')
367                 for p in i.properties:
368                     # getter
369                     if p.deprecated:
370                         self.h.write('G_GNUC_DEPRECATED ')
371                     self.h.write('%s%s_get_%s (%s *object);\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name))
372                     # setter
373                     if p.deprecated:
374                         self.h.write('G_GNUC_DEPRECATED ')
375                     self.h.write('void %s_set_%s (%s *object, %svalue);\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
376                     self.h.write('\n')
377
378             # Then the proxy
379             self.h.write('\n')
380             self.h.write('/* ---- */\n')
381             self.h.write('\n')
382             self.h.write('#define %sTYPE_%s_PROXY (%s_proxy_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
383             self.h.write('#define %s%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_PROXY, %sProxy))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
384             self.h.write('#define %s%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_PROXY, %sProxyClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
385             self.h.write('#define %s%s_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_PROXY, %sProxyClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
386             self.h.write('#define %sIS_%s_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_PROXY))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
387             self.h.write('#define %sIS_%s_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_PROXY))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
388             self.h.write('\n')
389             self.h.write('typedef struct _%sProxy %sProxy;\n'%(i.camel_name, i.camel_name))
390             self.h.write('typedef struct _%sProxyClass %sProxyClass;\n'%(i.camel_name, i.camel_name))
391             self.h.write('typedef struct _%sProxyPrivate %sProxyPrivate;\n'%(i.camel_name, i.camel_name))
392             self.h.write('\n')
393             self.h.write('struct _%sProxy\n'%(i.camel_name))
394             self.h.write('{\n')
395             self.h.write('  /*< private >*/\n')
396             self.h.write('  GDBusProxy parent_instance;\n')
397             self.h.write('  %sProxyPrivate *priv;\n'%(i.camel_name))
398             self.h.write('};\n')
399             self.h.write('\n')
400             self.h.write('struct _%sProxyClass\n'%(i.camel_name))
401             self.h.write('{\n')
402             self.h.write('  GDBusProxyClass parent_class;\n')
403             self.h.write('};\n')
404             self.h.write('\n')
405             self.h.write('GType %s_proxy_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
406
407             self.h.write('\n')
408             if i.deprecated:
409                 self.h.write('G_GNUC_DEPRECATED ')
410             self.h.write('void %s_proxy_new (\n'
411                          '    GDBusConnection     *connection,\n'
412                          '    GDBusProxyFlags      flags,\n'
413                          '    const gchar         *name,\n'
414                          '    const gchar         *object_path,\n'
415                          '    GCancellable        *cancellable,\n'
416                          '    GAsyncReadyCallback  callback,\n'
417                          '    gpointer             user_data);\n'
418                          %(i.name_lower))
419             if i.deprecated:
420                 self.h.write('G_GNUC_DEPRECATED ')
421             self.h.write('%s *%s_proxy_new_finish (\n'
422                          '    GAsyncResult        *res,\n'
423                          '    GError             **error);\n'
424                          %(i.camel_name, i.name_lower))
425             if i.deprecated:
426                 self.h.write('G_GNUC_DEPRECATED ')
427             self.h.write('%s *%s_proxy_new_sync (\n'
428                          '    GDBusConnection     *connection,\n'
429                          '    GDBusProxyFlags      flags,\n'
430                          '    const gchar         *name,\n'
431                          '    const gchar         *object_path,\n'
432                          '    GCancellable        *cancellable,\n'
433                          '    GError             **error);\n'
434                          %(i.camel_name, i.name_lower))
435             self.h.write('\n')
436             if i.deprecated:
437                 self.h.write('G_GNUC_DEPRECATED ')
438             self.h.write('void %s_proxy_new_for_bus (\n'
439                          '    GBusType             bus_type,\n'
440                          '    GDBusProxyFlags      flags,\n'
441                          '    const gchar         *name,\n'
442                          '    const gchar         *object_path,\n'
443                          '    GCancellable        *cancellable,\n'
444                          '    GAsyncReadyCallback  callback,\n'
445                          '    gpointer             user_data);\n'
446                          %(i.name_lower))
447             if i.deprecated:
448                 self.h.write('G_GNUC_DEPRECATED ')
449             self.h.write('%s *%s_proxy_new_for_bus_finish (\n'
450                          '    GAsyncResult        *res,\n'
451                          '    GError             **error);\n'
452                          %(i.camel_name, i.name_lower))
453             if i.deprecated:
454                 self.h.write('G_GNUC_DEPRECATED ')
455             self.h.write('%s *%s_proxy_new_for_bus_sync (\n'
456                          '    GBusType             bus_type,\n'
457                          '    GDBusProxyFlags      flags,\n'
458                          '    const gchar         *name,\n'
459                          '    const gchar         *object_path,\n'
460                          '    GCancellable        *cancellable,\n'
461                          '    GError             **error);\n'
462                          %(i.camel_name, i.name_lower))
463             self.h.write('\n')
464
465             # Then the skeleton
466             self.h.write('\n')
467             self.h.write('/* ---- */\n')
468             self.h.write('\n')
469             self.h.write('#define %sTYPE_%s_SKELETON (%s_skeleton_get_type ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
470             self.h.write('#define %s%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_SKELETON, %sSkeleton))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
471             self.h.write('#define %s%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_SKELETON, %sSkeletonClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
472             self.h.write('#define %s%s_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_SKELETON, %sSkeletonClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
473             self.h.write('#define %sIS_%s_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_SKELETON))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
474             self.h.write('#define %sIS_%s_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_SKELETON))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
475             self.h.write('\n')
476             self.h.write('typedef struct _%sSkeleton %sSkeleton;\n'%(i.camel_name, i.camel_name))
477             self.h.write('typedef struct _%sSkeletonClass %sSkeletonClass;\n'%(i.camel_name, i.camel_name))
478             self.h.write('typedef struct _%sSkeletonPrivate %sSkeletonPrivate;\n'%(i.camel_name, i.camel_name))
479             self.h.write('\n')
480             self.h.write('struct _%sSkeleton\n'%(i.camel_name))
481             self.h.write('{\n')
482             self.h.write('  /*< private >*/\n')
483             self.h.write('  GDBusInterfaceSkeleton parent_instance;\n')
484             self.h.write('  %sSkeletonPrivate *priv;\n'%(i.camel_name))
485             self.h.write('};\n')
486             self.h.write('\n')
487             self.h.write('struct _%sSkeletonClass\n'%(i.camel_name))
488             self.h.write('{\n')
489             self.h.write('  GDBusInterfaceSkeletonClass parent_class;\n')
490             self.h.write('};\n')
491             self.h.write('\n')
492             self.h.write('GType %s_skeleton_get_type (void) G_GNUC_CONST;\n'%(i.name_lower))
493             self.h.write('\n')
494             if i.deprecated:
495                 self.h.write('G_GNUC_DEPRECATED ')
496             self.h.write('%s *%s_skeleton_new (void);\n'%(i.camel_name, i.name_lower))
497
498             self.h.write('\n')
499
500         # Finally, the Object, ObjectProxy, ObjectSkeleton and ObjectManagerClient
501         if self.generate_objmanager:
502             self.h.write('\n')
503             self.h.write('/* ---- */\n')
504             self.h.write('\n')
505             self.h.write('#define %sTYPE_OBJECT (%sobject_get_type ())\n'%(self.ns_upper, self.ns_lower))
506             self.h.write('#define %sOBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace))
507             self.h.write('#define %sIS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT))\n'%(self.ns_upper, self.ns_upper))
508             self.h.write('#define %sOBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), %sTYPE_OBJECT, %sObject))\n'%(self.ns_upper, self.ns_upper, self.namespace))
509             self.h.write('\n')
510             self.h.write('struct _%sObject;\n'%(self.namespace))
511             self.h.write('typedef struct _%sObject %sObject;\n'%(self.namespace, self.namespace))
512             self.h.write('typedef struct _%sObjectIface %sObjectIface;\n'%(self.namespace, self.namespace))
513             self.h.write('\n')
514             self.h.write('struct _%sObjectIface\n'%(self.namespace))
515             self.h.write('{\n'
516                          '  GTypeInterface parent_iface;\n'
517                          '};\n'
518                          '\n')
519             self.h.write('GType %sobject_get_type (void) G_GNUC_CONST;\n'
520                          '\n'
521                          %(self.ns_lower))
522             for i in self.ifaces:
523                 if i.deprecated:
524                     self.h.write('G_GNUC_DEPRECATED ')
525                 self.h.write ('%s *%sobject_get_%s (%sObject *object);\n'
526                               %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
527             for i in self.ifaces:
528                 if i.deprecated:
529                     self.h.write('G_GNUC_DEPRECATED ')
530                 self.h.write ('%s *%sobject_peek_%s (%sObject *object);\n'
531                               %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
532             self.h.write('\n')
533             self.h.write('#define %sTYPE_OBJECT_PROXY (%sobject_proxy_get_type ())\n'%(self.ns_upper, self.ns_lower))
534             self.h.write('#define %sOBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_PROXY, %sObjectProxy))\n'%(self.ns_upper, self.ns_upper, self.namespace))
535             self.h.write('#define %sOBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
536             self.h.write('#define %sOBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_PROXY, %sObjectProxyClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
537             self.h.write('#define %sIS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper))
538             self.h.write('#define %sIS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_PROXY))\n'%(self.ns_upper, self.ns_upper))
539             self.h.write('\n')
540             self.h.write('typedef struct _%sObjectProxy %sObjectProxy;\n'%(self.namespace, self.namespace))
541             self.h.write('typedef struct _%sObjectProxyClass %sObjectProxyClass;\n'%(self.namespace, self.namespace))
542             self.h.write('typedef struct _%sObjectProxyPrivate %sObjectProxyPrivate;\n'%(self.namespace, self.namespace))
543             self.h.write('\n')
544             self.h.write('struct _%sObjectProxy\n'%(self.namespace))
545             self.h.write('{\n')
546             self.h.write('  /*< private >*/\n')
547             self.h.write('  GDBusObjectProxy parent_instance;\n')
548             self.h.write('  %sObjectProxyPrivate *priv;\n'%(self.namespace))
549             self.h.write('};\n')
550             self.h.write('\n')
551             self.h.write('struct _%sObjectProxyClass\n'%(self.namespace))
552             self.h.write('{\n')
553             self.h.write('  GDBusObjectProxyClass parent_class;\n')
554             self.h.write('};\n')
555             self.h.write('\n')
556             self.h.write('GType %sobject_proxy_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
557             self.h.write('%sObjectProxy *%sobject_proxy_new (GDBusConnection *connection, const gchar *object_path);\n'%(self.namespace, self.ns_lower))
558             self.h.write('\n')
559             self.h.write('#define %sTYPE_OBJECT_SKELETON (%sobject_skeleton_get_type ())\n'%(self.ns_upper, self.ns_lower))
560             self.h.write('#define %sOBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeleton))\n'%(self.ns_upper, self.ns_upper, self.namespace))
561             self.h.write('#define %sOBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
562             self.h.write('#define %sOBJECT_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_SKELETON, %sObjectSkeletonClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
563             self.h.write('#define %sIS_OBJECT_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper))
564             self.h.write('#define %sIS_OBJECT_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_SKELETON))\n'%(self.ns_upper, self.ns_upper))
565             self.h.write('\n')
566             self.h.write('typedef struct _%sObjectSkeleton %sObjectSkeleton;\n'%(self.namespace, self.namespace))
567             self.h.write('typedef struct _%sObjectSkeletonClass %sObjectSkeletonClass;\n'%(self.namespace, self.namespace))
568             self.h.write('typedef struct _%sObjectSkeletonPrivate %sObjectSkeletonPrivate;\n'%(self.namespace, self.namespace))
569             self.h.write('\n')
570             self.h.write('struct _%sObjectSkeleton\n'%(self.namespace))
571             self.h.write('{\n')
572             self.h.write('  /*< private >*/\n')
573             self.h.write('  GDBusObjectSkeleton parent_instance;\n')
574             self.h.write('  %sObjectSkeletonPrivate *priv;\n'%(self.namespace))
575             self.h.write('};\n')
576             self.h.write('\n')
577             self.h.write('struct _%sObjectSkeletonClass\n'%(self.namespace))
578             self.h.write('{\n')
579             self.h.write('  GDBusObjectSkeletonClass parent_class;\n')
580             self.h.write('};\n')
581             self.h.write('\n')
582             self.h.write('GType %sobject_skeleton_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
583             self.h.write('%sObjectSkeleton *%sobject_skeleton_new (const gchar *object_path);\n'
584                          %(self.namespace, self.ns_lower))
585             for i in self.ifaces:
586                 if i.deprecated:
587                     self.h.write('G_GNUC_DEPRECATED ')
588                 self.h.write ('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_);\n'
589                               %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name))
590             self.h.write('\n')
591
592             self.h.write('/* ---- */\n')
593             self.h.write('\n')
594             self.h.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_type ())\n'%(self.ns_upper, self.ns_lower))
595             self.h.write('#define %sOBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClient))\n'%(self.ns_upper, self.ns_upper, self.namespace))
596             self.h.write('#define %sOBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
597             self.h.write('#define %sOBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_OBJECT_MANAGER_CLIENT, %sObjectManagerClientClass))\n'%(self.ns_upper, self.ns_upper, self.namespace))
598             self.h.write('#define %sIS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
599             self.h.write('#define %sIS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_OBJECT_MANAGER_CLIENT))\n'%(self.ns_upper, self.ns_upper))
600             self.h.write('\n')
601             self.h.write('typedef struct _%sObjectManagerClient %sObjectManagerClient;\n'%(self.namespace, self.namespace))
602             self.h.write('typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n'%(self.namespace, self.namespace))
603             self.h.write('typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n'%(self.namespace, self.namespace))
604             self.h.write('\n')
605             self.h.write('struct _%sObjectManagerClient\n'%(self.namespace))
606             self.h.write('{\n')
607             self.h.write('  /*< private >*/\n')
608             self.h.write('  GDBusObjectManagerClient parent_instance;\n')
609             self.h.write('  %sObjectManagerClientPrivate *priv;\n'%(self.namespace))
610             self.h.write('};\n')
611             self.h.write('\n')
612             self.h.write('struct _%sObjectManagerClientClass\n'%(self.namespace))
613             self.h.write('{\n')
614             self.h.write('  GDBusObjectManagerClientClass parent_class;\n')
615             self.h.write('};\n')
616             self.h.write('\n')
617             self.h.write('GType %sobject_manager_client_get_type (void) G_GNUC_CONST;\n'%(self.ns_lower))
618             self.h.write('\n')
619             self.h.write('GType %sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data);\n'%(self.ns_lower))
620             self.h.write('\n')
621             self.h.write('void %sobject_manager_client_new (\n'
622                          '    GDBusConnection        *connection,\n'
623                          '    GDBusObjectManagerClientFlags  flags,\n'
624                          '    const gchar            *name,\n'
625                          '    const gchar            *object_path,\n'
626                          '    GCancellable           *cancellable,\n'
627                          '    GAsyncReadyCallback     callback,\n'
628                          '    gpointer                user_data);\n'
629                          %(self.ns_lower))
630             self.h.write('GDBusObjectManager *%sobject_manager_client_new_finish (\n'
631                          '    GAsyncResult        *res,\n'
632                          '    GError             **error);\n'
633                          %(self.ns_lower))
634             self.h.write('GDBusObjectManager *%sobject_manager_client_new_sync (\n'
635                          '    GDBusConnection        *connection,\n'
636                          '    GDBusObjectManagerClientFlags  flags,\n'
637                          '    const gchar            *name,\n'
638                          '    const gchar            *object_path,\n'
639                          '    GCancellable           *cancellable,\n'
640                          '    GError                **error);\n'
641                          %(self.ns_lower))
642             self.h.write('\n')
643             self.h.write('void %sobject_manager_client_new_for_bus (\n'
644                          '    GBusType                bus_type,\n'
645                          '    GDBusObjectManagerClientFlags  flags,\n'
646                          '    const gchar            *name,\n'
647                          '    const gchar            *object_path,\n'
648                          '    GCancellable           *cancellable,\n'
649                          '    GAsyncReadyCallback     callback,\n'
650                          '    gpointer                user_data);\n'
651                          %(self.ns_lower))
652             self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n'
653                          '    GAsyncResult        *res,\n'
654                          '    GError             **error);\n'
655                          %(self.ns_lower))
656             self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n'
657                          '    GBusType                bus_type,\n'
658                          '    GDBusObjectManagerClientFlags  flags,\n'
659                          '    const gchar            *name,\n'
660                          '    const gchar            *object_path,\n'
661                          '    GCancellable           *cancellable,\n'
662                          '    GError                **error);\n'
663                          %(self.ns_lower))
664             self.h.write('\n')
665
666     # ----------------------------------------------------------------------------------------------------
667
668     def generate_outro(self):
669         self.h.write('\n'
670                      'G_END_DECLS\n'
671                      '\n'
672                      '#endif /* __%s__ */\n'%(self.header_guard))
673
674     # ----------------------------------------------------------------------------------------------------
675
676     def generate_annotations(self, prefix, annotations):
677         if annotations == None:
678             return
679
680         n = 0
681         for a in annotations:
682             #self.generate_annotations('%s_%d'%(prefix, n), a.get_annotations())
683
684             # skip internal annotations
685             if a.key.startswith('org.gtk.GDBus'):
686                 continue
687
688             self.c.write('static const GDBusAnnotationInfo %s_%d =\n'
689                          '{\n'
690                          '  -1,\n'
691                          '  "%s",\n'
692                          '  "%s",\n'%(prefix, n, a.key, a.value))
693             if len(a.annotations) == 0:
694                 self.c.write('  NULL\n')
695             else:
696                 self.c.write('  (GDBusAnnotationInfo **) &%s_%d_pointers\n'%(prefix, n))
697             self.c.write('};\n'
698                          '\n')
699             n += 1
700
701         if n > 0:
702             self.c.write('static const GDBusAnnotationInfo * const %s_pointers[] =\n'
703                              '{\n'%(prefix))
704             m = 0;
705             for a in annotations:
706                 if a.key.startswith('org.gtk.GDBus'):
707                     continue
708                 self.c.write('  &%s_%d,\n'%(prefix, m))
709                 m += 1
710             self.c.write('  NULL\n'
711                          '};\n'
712                          '\n')
713         return n
714
715     def generate_args(self, prefix, args):
716         for a in args:
717             num_anno = self.generate_annotations('%s_arg_%s_annotation_info'%(prefix, a.name), a.annotations)
718
719             self.c.write('static const _ExtendedGDBusArgInfo %s_%s =\n'
720                          '{\n'
721                          '  {\n'
722                          '    -1,\n'
723                          '    "%s",\n'
724                          '    "%s",\n'%(prefix, a.name, a.name, a.signature))
725             if num_anno == 0:
726                 self.c.write('    NULL\n')
727             else:
728                 self.c.write('    (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n'%(prefix, a.name))
729             self.c.write('  },\n')
730             if not utils.lookup_annotation(a.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
731                 self.c.write('  FALSE\n')
732             else:
733                 self.c.write('  TRUE\n')
734             self.c.write('};\n'
735                          '\n')
736
737         if len(args) > 0:
738             self.c.write('static const _ExtendedGDBusArgInfo * const %s_pointers[] =\n'
739                              '{\n'%(prefix))
740             for a in args:
741                 self.c.write('  &%s_%s,\n'%(prefix, a.name))
742             self.c.write('  NULL\n'
743                          '};\n'
744                          '\n')
745
746     def generate_introspection_for_interface(self, i):
747             self.c.write('/* ---- Introspection data for %s ---- */\n'
748                          '\n'%(i.name))
749
750             if len(i.methods) > 0:
751                 for m in i.methods:
752                     self.generate_args('_%s_method_info_%s_IN_ARG'%(i.name_lower, m.name_lower), m.in_args)
753                     self.generate_args('_%s_method_info_%s_OUT_ARG'%(i.name_lower, m.name_lower), m.out_args)
754
755                     num_anno = self.generate_annotations('_%s_method_%s_annotation_info'%(i.name_lower, m.name_lower), m.annotations)
756
757                     self.c.write('static const _ExtendedGDBusMethodInfo _%s_method_info_%s =\n'
758                                  '{\n'
759                                  '  {\n'
760                                  '    -1,\n'
761                                  '    "%s",\n'%(i.name_lower, m.name_lower, m.name))
762                     if len(m.in_args) == 0:
763                         self.c.write('    NULL,\n')
764                     else:
765                         self.c.write('    (GDBusArgInfo **) &_%s_method_info_%s_IN_ARG_pointers,\n'%(i.name_lower, m.name_lower))
766                     if len(m.out_args) == 0:
767                         self.c.write('    NULL,\n')
768                     else:
769                         self.c.write('    (GDBusArgInfo **) &_%s_method_info_%s_OUT_ARG_pointers,\n'%(i.name_lower, m.name_lower))
770                     if num_anno == 0:
771                         self.c.write('    NULL\n')
772                     else:
773                         self.c.write('    (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n'%(i.name_lower, m.name_lower))
774                     self.c.write('  },\n'
775                                  '  "handle-%s"\n'
776                                  %(m.name_hyphen))
777                     self.c.write('};\n'
778                                  '\n')
779
780                 self.c.write('static const _ExtendedGDBusMethodInfo * const _%s_method_info_pointers[] =\n'
781                              '{\n'%(i.name_lower))
782                 for m in i.methods:
783                     self.c.write('  &_%s_method_info_%s,\n'%(i.name_lower, m.name_lower))
784                 self.c.write('  NULL\n'
785                              '};\n'
786                              '\n')
787
788             # ---
789
790             if len(i.signals) > 0:
791                 for s in i.signals:
792                     self.generate_args('_%s_signal_info_%s_ARG'%(i.name_lower, s.name_lower), s.args)
793
794                     num_anno = self.generate_annotations('_%s_signal_%s_annotation_info'%(i.name_lower, s.name_lower), s.annotations)
795                     self.c.write('static const _ExtendedGDBusSignalInfo _%s_signal_info_%s =\n'
796                                  '{\n'
797                                  '  {\n'
798                                  '    -1,\n'
799                                  '    "%s",\n'%(i.name_lower, s.name_lower, s.name))
800                     if len(s.args) == 0:
801                         self.c.write('    NULL,\n')
802                     else:
803                         self.c.write('    (GDBusArgInfo **) &_%s_signal_info_%s_ARG_pointers,\n'%(i.name_lower, s.name_lower))
804                     if num_anno == 0:
805                         self.c.write('    NULL\n')
806                     else:
807                         self.c.write('    (GDBusAnnotationInfo **) &_%s_signal_%s_annotation_info_pointers\n'%(i.name_lower, s.name_lower))
808                     self.c.write('  },\n'
809                                  '  "%s"\n'
810                                  %(s.name_hyphen))
811                     self.c.write('};\n'
812                                  '\n')
813
814                 self.c.write('static const _ExtendedGDBusSignalInfo * const _%s_signal_info_pointers[] =\n'
815                              '{\n'%(i.name_lower))
816                 for s in i.signals:
817                     self.c.write('  &_%s_signal_info_%s,\n'%(i.name_lower, s.name_lower))
818                 self.c.write('  NULL\n'
819                              '};\n'
820                              '\n')
821
822             # ---
823
824             if len(i.properties) > 0:
825                 for p in i.properties:
826                     if p.readable and p.writable:
827                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
828                     elif p.readable:
829                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE'
830                     elif p.writable:
831                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
832                     else:
833                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_NONE'
834                     num_anno = self.generate_annotations('_%s_property_%s_annotation_info'%(i.name_lower, p.name_lower), p.annotations)
835                     self.c.write('static const _ExtendedGDBusPropertyInfo _%s_property_info_%s =\n'
836                                  '{\n'
837                                  '  {\n'
838                                  '    -1,\n'
839                                  '    "%s",\n'
840                                  '    "%s",\n'
841                                  '    %s,\n'%(i.name_lower, p.name_lower, p.name, p.arg.signature, access))
842                     if num_anno == 0:
843                         self.c.write('    NULL\n')
844                     else:
845                         self.c.write('    (GDBusAnnotationInfo **) &_%s_property_%s_annotation_info_pointers\n'%(i.name_lower, p.name_lower))
846                     self.c.write('  },\n'
847                                  '  "%s",\n'
848                                  %(p.name_hyphen))
849                     if not utils.lookup_annotation(p.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
850                         self.c.write('  FALSE\n')
851                     else:
852                         self.c.write('  TRUE\n')
853                     self.c.write('};\n'
854                                  '\n')
855
856                 self.c.write('static const _ExtendedGDBusPropertyInfo * const _%s_property_info_pointers[] =\n'
857                              '{\n'%(i.name_lower))
858                 for p in i.properties:
859                     self.c.write('  &_%s_property_info_%s,\n'%(i.name_lower, p.name_lower))
860                 self.c.write('  NULL\n'
861                              '};\n'
862                              '\n')
863
864             num_anno = self.generate_annotations('_%s_annotation_info'%(i.name_lower), i.annotations)
865             self.c.write('static const _ExtendedGDBusInterfaceInfo _%s_interface_info =\n'
866                          '{\n'
867                          '  {\n'
868                          '    -1,\n'
869                          '    "%s",\n'%(i.name_lower, i.name))
870             if len(i.methods) == 0:
871                 self.c.write('    NULL,\n')
872             else:
873                 self.c.write('    (GDBusMethodInfo **) &_%s_method_info_pointers,\n'%(i.name_lower))
874             if len(i.signals) == 0:
875                 self.c.write('    NULL,\n')
876             else:
877                 self.c.write('    (GDBusSignalInfo **) &_%s_signal_info_pointers,\n'%(i.name_lower))
878             if len(i.properties) == 0:
879                 self.c.write('    NULL,\n')
880             else:
881                 self.c.write('    (GDBusPropertyInfo **) &_%s_property_info_pointers,\n'%(i.name_lower))
882             if num_anno == 0:
883                 self.c.write('    NULL\n')
884             else:
885                 self.c.write('    (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n'%(i.name_lower))
886             self.c.write('  },\n'
887                          '  "%s",\n'
888                          '};\n'
889                          '\n'
890                          %(i.name_hyphen))
891             self.c.write('\n')
892             self.c.write(self.docbook_gen.expand(
893                     '/**\n'
894                     ' * %s_interface_info:\n'
895                     ' *\n'
896                     ' * Gets a machine-readable description of the #%s D-Bus interface.\n'
897                     ' *\n'
898                     ' * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.\n'
899                     %(i.name_lower, i.name), False))
900             self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
901             self.c.write('GDBusInterfaceInfo *\n'
902                          '%s_interface_info (void)\n'
903                          '{\n'
904                          '  return (GDBusInterfaceInfo *) &_%s_interface_info;\n'
905                          '}\n'
906                          '\n'%(i.name_lower, i.name_lower))
907
908             if len(i.properties) > 0:
909                 self.c.write(self.docbook_gen.expand(
910                         '/**\n'
911                         ' * %s_override_properties:\n'
912                         ' * @klass: The class structure for a #GObject<!-- -->-derived class.\n'
913                         ' * @property_id_begin: The property id to assign to the first overridden property.\n'
914                         ' *\n'
915                         ' * Overrides all #GObject properties in the #%s interface for a concrete class.\n'
916                         ' * The properties are overridden in the order they are defined.\n'
917                         ' *\n'
918                         ' * Returns: The last property id.\n'
919                         %(i.name_lower, i.camel_name), False))
920                 self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
921                 self.c.write('guint\n'
922                              '%s_override_properties (GObjectClass *klass, guint property_id_begin)\n'
923                              '{\n'%(i.name_lower))
924                 for p in i.properties:
925                     self.c.write ('  g_object_class_override_property (klass, property_id_begin++, "%s");\n'%(p.name_hyphen))
926                 self.c.write('  return property_id_begin - 1;\n'
927                              '}\n'
928                              '\n')
929             self.c.write('\n')
930
931     # ----------------------------------------------------------------------------------------------------
932
933     def generate_interface(self, i):
934         self.c.write('\n')
935
936         self.c.write(self.docbook_gen.expand(
937                 '/**\n'
938                 ' * %s:\n'
939                 ' *\n'
940                 ' * Abstract interface type for the D-Bus interface #%s.\n'
941                 %(i.camel_name, i.name), False))
942         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
943         self.c.write('\n')
944
945         self.c.write(self.docbook_gen.expand(
946                 '/**\n'
947                 ' * %sIface:\n'
948                 ' * @parent_iface: The parent interface.\n'
949                 %(i.camel_name), False))
950
951         doc_bits = {}
952         if len(i.methods) > 0:
953             for m in i.methods:
954                 key = (m.since, '_method_%s'%m.name_lower)
955                 value  = '@handle_%s: '%(m.name_lower)
956                 value += 'Handler for the #%s::handle-%s signal.'%(i.camel_name, m.name_hyphen)
957                 doc_bits[key] = value
958         if len(i.signals) > 0:
959             for s in i.signals:
960                 key = (s.since, '_signal_%s'%s.name_lower)
961                 value  = '@%s: '%(s.name_lower)
962                 value += 'Handler for the #%s::%s signal.'%(i.camel_name, s.name_hyphen)
963                 doc_bits[key] = value
964         keys = doc_bits.keys()
965         if len(keys) > 0:
966             keys.sort(cmp=utils.my_version_cmp)
967             for key in keys:
968                 self.c.write(' * %s\n'%doc_bits[key])
969         self.c.write(self.docbook_gen.expand(
970                 ' *\n'
971                 ' * Virtual table for the D-Bus interface #%s.\n'
972                 %(i.name), False))
973         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
974         self.c.write('\n')
975
976         self.c.write('static void\n'
977                      '%s_default_init (%sIface *iface)\n'
978                      '{\n'%(i.name_lower, i.camel_name));
979
980         if len(i.methods) > 0:
981             self.c.write('  /* GObject signals for incoming D-Bus method calls: */\n')
982             for m in i.methods:
983                 self.c.write(self.docbook_gen.expand(
984                         '  /**\n'
985                         '   * %s::handle-%s:\n'
986                         '   * @object: A #%s.\n'
987                         '   * @invocation: A #GDBusMethodInvocation.\n'
988                         %(i.camel_name, m.name_hyphen, i.camel_name), False))
989                 for a in m.in_args:
990                     self.c.write ('   * @%s: Argument passed by remote caller.\n'%(a.name))
991                 self.c.write(self.docbook_gen.expand(
992                         '   *\n'
993                         '   * Signal emitted when a remote caller is invoking the %s.%s() D-Bus method.\n'
994                         '   *\n'
995                         '   * If a signal handler returns %%TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call %s_complete_%s() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %%G_DBUS_ERROR_UNKNOWN_METHOD error is returned.\n'
996                         '   *\n'
997                         '   * Returns: %%TRUE if the invocation was handled, %%FALSE to let other signal handlers run.\n'
998                         %(i.name, m.name, i.name_lower, m.name_lower), False))
999                 self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 2)
1000                 self.c.write('  g_signal_new ("handle-%s",\n'
1001                              '    G_TYPE_FROM_INTERFACE (iface),\n'
1002                              '    G_SIGNAL_RUN_LAST,\n'
1003                              '    G_STRUCT_OFFSET (%sIface, handle_%s),\n'
1004                              '    g_signal_accumulator_true_handled,\n'
1005                              '    NULL,\n' # accu_data
1006                              '    g_cclosure_marshal_generic,\n'
1007                              '    G_TYPE_BOOLEAN,\n'
1008                              '    %d,\n'
1009                              '    G_TYPE_DBUS_METHOD_INVOCATION'
1010                              %(m.name_hyphen, i.camel_name, m.name_lower, len(m.in_args) + 1))
1011                 for a in m.in_args:
1012                     self.c.write (', %s'%(a.gtype))
1013                 self.c.write(');\n')
1014                 self.c.write('\n')
1015
1016         if len(i.signals) > 0:
1017             self.c.write('  /* GObject signals for received D-Bus signals: */\n')
1018             for s in i.signals:
1019                 self.c.write(self.docbook_gen.expand(
1020                         '  /**\n'
1021                         '   * %s::%s:\n'
1022                         '   * @object: A #%s.\n'
1023                         %(i.camel_name, s.name_hyphen, i.camel_name), False))
1024                 for a in s.args:
1025                     self.c.write ('   * @%s: Argument.\n'%(a.name))
1026                 self.c.write(self.docbook_gen.expand(
1027                         '   *\n'
1028                         '   * On the client-side, this signal is emitted whenever the D-Bus signal #%s::%s is received.\n'
1029                         '   *\n'
1030                         '   * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.\n'
1031                         %(i.name, s.name), False))
1032                 self.write_gtkdoc_deprecated_and_since_and_close(s, self.c, 2)
1033                 self.c.write('  g_signal_new ("%s",\n'
1034                              '    G_TYPE_FROM_INTERFACE (iface),\n'
1035                              '    G_SIGNAL_RUN_LAST,\n'
1036                              '    G_STRUCT_OFFSET (%sIface, %s),\n'
1037                              '    NULL,\n' # accumulator
1038                              '    NULL,\n' # accu_data
1039                              '    g_cclosure_marshal_generic,\n'
1040                              '    G_TYPE_NONE,\n'
1041                              '    %d'
1042                              %(s.name_hyphen, i.camel_name, s.name_lower, len(s.args)))
1043                 for a in s.args:
1044                     self.c.write (', %s'%(a.gtype))
1045                 self.c.write(');\n')
1046                 self.c.write('\n')
1047
1048         if len(i.properties) > 0:
1049             self.c.write('  /* GObject properties for D-Bus properties: */\n')
1050             for p in i.properties:
1051                 if p.readable and p.writable:
1052                     hint = 'Since the D-Bus property for this #GObject property is both readable and writable, it is meaningful to both read from it and write to it on both the service- and client-side.'
1053                 elif p.readable:
1054                     hint = 'Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side.'
1055                 elif p.writable:
1056                     hint = 'Since the D-Bus property for this #GObject property is writable but not readable, it is meaningful to write to it on both the client- and service-side. It is only meaningful, however, to read from it on the service-side.'
1057                 else:
1058                     raise RuntimeError('Cannot handle property %s that neither readable nor writable'%(p.name))
1059                 self.c.write(self.docbook_gen.expand(
1060                         '  /**\n'
1061                         '   * %s:%s:\n'
1062                         '   *\n'
1063                         '   * Represents the D-Bus property #%s:%s.\n'
1064                         '   *\n'
1065                         '   * %s\n'
1066                         %(i.camel_name, p.name_hyphen, i.name, p.name, hint), False))
1067                 self.write_gtkdoc_deprecated_and_since_and_close(p, self.c, 2)
1068                 self.c.write('  g_object_interface_install_property (iface,\n')
1069                 if p.arg.gtype == 'G_TYPE_VARIANT':
1070                     s = 'g_param_spec_variant ("%s", "%s", "%s", G_VARIANT_TYPE ("%s"), NULL'%(p.name_hyphen, p.name, p.name, p.arg.signature)
1071                 elif p.arg.signature == 'b':
1072                     s = 'g_param_spec_boolean ("%s", "%s", "%s", FALSE'%(p.name_hyphen, p.name, p.name)
1073                 elif p.arg.signature == 'y':
1074                     s = 'g_param_spec_uchar ("%s", "%s", "%s", 0, 255, 0'%(p.name_hyphen, p.name, p.name)
1075                 elif p.arg.signature == 'n':
1076                     s = 'g_param_spec_int ("%s", "%s", "%s", G_MININT16, G_MAXINT16, 0'%(p.name_hyphen, p.name, p.name)
1077                 elif p.arg.signature == 'q':
1078                     s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT16, 0'%(p.name_hyphen, p.name, p.name)
1079                 elif p.arg.signature == 'i':
1080                     s = 'g_param_spec_int ("%s", "%s", "%s", G_MININT32, G_MAXINT32, 0'%(p.name_hyphen, p.name, p.name)
1081                 elif p.arg.signature == 'u':
1082                     s = 'g_param_spec_uint ("%s", "%s", "%s", 0, G_MAXUINT32, 0'%(p.name_hyphen, p.name, p.name)
1083                 elif p.arg.signature == 'x':
1084                     s = 'g_param_spec_int64 ("%s", "%s", "%s", G_MININT64, G_MAXINT64, 0'%(p.name_hyphen, p.name, p.name)
1085                 elif p.arg.signature == 't':
1086                     s = 'g_param_spec_uint64 ("%s", "%s", "%s", 0, G_MAXUINT64, 0'%(p.name_hyphen, p.name, p.name)
1087                 elif p.arg.signature == 'd':
1088                     s = 'g_param_spec_double ("%s", "%s", "%s", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0'%(p.name_hyphen, p.name, p.name)
1089                 elif p.arg.signature == 's':
1090                     s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
1091                 elif p.arg.signature == 'o':
1092                     s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
1093                 elif p.arg.signature == 'g':
1094                     s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
1095                 elif p.arg.signature == 'ay':
1096                     s = 'g_param_spec_string ("%s", "%s", "%s", NULL'%(p.name_hyphen, p.name, p.name)
1097                 elif p.arg.signature == 'as':
1098                     s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV'%(p.name_hyphen, p.name, p.name)
1099                 elif p.arg.signature == 'aay':
1100                     s = 'g_param_spec_boxed ("%s", "%s", "%s", G_TYPE_STRV'%(p.name_hyphen, p.name, p.name)
1101                 else:
1102                     raise RuntimeError('Unsupported gtype %s for GParamSpec'%(p.arg.gtype))
1103                 self.c.write('    %s, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));'%s);
1104                 self.c.write('\n')
1105
1106         self.c.write('}\n'
1107                      '\n')
1108
1109         self.c.write('typedef %sIface %sInterface;\n'%(i.camel_name, i.camel_name))
1110         self.c.write('G_DEFINE_INTERFACE (%s, %s, G_TYPE_OBJECT);\n'%(i.camel_name, i.name_lower))
1111         self.c.write('\n')
1112
1113     # ----------------------------------------------------------------------------------------------------
1114
1115     def generate_property_accessors(self, i):
1116         for p in i.properties:
1117             # getter
1118             if p.readable and p.writable:
1119                 hint = 'Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.'
1120             elif p.readable:
1121                 hint = 'Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.'
1122             elif p.writable:
1123                 hint = 'Since this D-Bus property is not readable, it is only meaningful to use this function on the service-side.'
1124             else:
1125                 raise RuntimeError('Cannot handle property %s that neither readable nor writable'%(p.name))
1126             self.c.write(self.docbook_gen.expand(
1127                     '/**\n'
1128                     ' * %s_get_%s:\n'
1129                     ' * @object: A #%s.\n'
1130                     ' *\n'
1131                     ' * Gets the value of the #%s:%s D-Bus property.\n'
1132                     ' *\n'
1133                     ' * %s\n'
1134                     ' *\n'
1135                     ' * Returns: (transfer none): The property value.\n'
1136                     %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), False))
1137             self.write_gtkdoc_deprecated_and_since_and_close(p, self.c, 0)
1138             self.c.write('%s\n'
1139                          '%s_get_%s (%s *object)\n'
1140                          '{\n'
1141                          '  %svalue;\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in_g))
1142             self.c.write('  g_object_get (G_OBJECT (object), "%s", &value, NULL);\n'%(p.name_hyphen))
1143             if p.arg.free_func:
1144                 self.c.write('  if (value != NULL)\n'
1145                              '    g_object_set_data_full (G_OBJECT (object), "-x-memoizing-%s", (gpointer) value, (GDestroyNotify) %s);\n'
1146                              '  else\n'
1147                              '    g_object_set_data_full (G_OBJECT (object), "-x-memoizing-%s", (gpointer) value, NULL);\n'
1148                              %(p.name_hyphen, p.arg.free_func, p.name_hyphen))
1149             self.c.write('  return value;\n')
1150             self.c.write('}\n')
1151             self.c.write('\n')
1152             # setter
1153             if p.readable and p.writable:
1154                 hint = 'Since this D-Bus property is both readable and writable, it is meaningful to use this function on both the client- and service-side.'
1155             elif p.readable:
1156                 hint = 'Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.'
1157             elif p.writable:
1158                 hint = 'Since this D-Bus property is writable, it is meaningful to use this function on both the client- and service-side.'
1159             else:
1160                 raise RuntimeError('Cannot handle property %s that neither readable nor writable'%(p.name))
1161             self.c.write(self.docbook_gen.expand(
1162                     '/**\n'
1163                     ' * %s_set_%s:\n'
1164                     ' * @object: A #%s.\n'
1165                     ' * @value: The value to set.\n'
1166                     ' *\n'
1167                     ' * Sets the #%s:%s D-Bus property to @value.\n'
1168                     ' *\n'
1169                     ' * %s\n'
1170                     %(i.name_lower, p.name_lower, i.camel_name, i.name, p.name, hint), False))
1171             self.write_gtkdoc_deprecated_and_since_and_close(p, self.c, 0)
1172             self.c.write('void\n'
1173                          '%s_set_%s (%s *object, %svalue)\n'
1174                          '{\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
1175             self.c.write('  g_object_set (G_OBJECT (object), "%s", value, NULL);\n'%(p.name_hyphen))
1176             self.c.write('}\n')
1177             self.c.write('\n')
1178
1179     # ---------------------------------------------------------------------------------------------------
1180
1181     def generate_signal_emitters(self, i):
1182         for s in i.signals:
1183             self.c.write(self.docbook_gen.expand(
1184                     '/**\n'
1185                     ' * %s_emit_%s:\n'
1186                     ' * @object: A #%s.\n'
1187                     %(i.name_lower, s.name_lower, i.camel_name), False))
1188             for a in s.args:
1189                 self.c.write(' * @%s: Argument to pass with the signal.\n'%(a.name))
1190             self.c.write(self.docbook_gen.expand(
1191                     ' *\n'
1192                     ' * Emits the #%s::%s D-Bus signal.\n'
1193                     %(i.name, s.name), False))
1194             self.write_gtkdoc_deprecated_and_since_and_close(s, self.c, 0)
1195             self.c.write('void\n'
1196                          '%s_emit_%s (\n'
1197                          '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
1198             for a in s.args:
1199                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
1200             self.c.write(')\n'
1201                          '{\n'
1202                          '  g_signal_emit_by_name (object, "%s"'%(s.name_hyphen))
1203             for a in s.args:
1204                 self.c.write(', %s'%a.name)
1205             self.c.write(');\n')
1206             self.c.write('}\n'
1207                          '\n')
1208
1209     # ---------------------------------------------------------------------------------------------------
1210
1211     def generate_method_calls(self, i):
1212         for m in i.methods:
1213             # async begin
1214             self.c.write('/**\n'
1215                          ' * %s_call_%s:\n'
1216                          ' * @proxy: A #%sProxy.\n'
1217                          %(i.name_lower, m.name_lower, i.camel_name))
1218             for a in m.in_args:
1219                 self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
1220             self.c.write(self.docbook_gen.expand(
1221                     ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
1222                     ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %%NULL.\n'
1223                     ' * @user_data: User data to pass to @callback.\n'
1224                     ' *\n'
1225                     ' * Asynchronously invokes the %s.%s() D-Bus method on @proxy.\n'
1226                     ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
1227                     ' * You can then call %s_call_%s_finish() to get the result of the operation.\n'
1228                     ' *\n'
1229                     ' * See %s_call_%s_sync() for the synchronous, blocking version of this method.\n'
1230                     %(i.name, m.name, i.name_lower, m.name_lower, i.name_lower, m.name_lower), False))
1231             self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
1232             self.c.write('void\n'
1233                          '%s_call_%s (\n'
1234                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
1235             for a in m.in_args:
1236                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
1237             self.c.write(',\n'
1238                          '    GCancellable *cancellable,\n'
1239                          '    GAsyncReadyCallback callback,\n'
1240                          '    gpointer user_data)\n'
1241                          '{\n')
1242             self.c.write('  g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n'
1243                          '    "%s",\n'
1244                          '    g_variant_new ("('%(m.name))
1245             for a in m.in_args:
1246                 self.c.write('%s'%(a.format_in))
1247             self.c.write(')"')
1248             for a in m.in_args:
1249                 self.c.write(',\n                   %s'%(a.name))
1250             self.c.write('),\n'
1251                          '    G_DBUS_CALL_FLAGS_NONE,\n'
1252                          '    -1,\n'
1253                          '    cancellable,\n'
1254                          '    callback,\n'
1255                          '    user_data);\n')
1256             self.c.write('}\n'
1257                          '\n')
1258             # async finish
1259             self.c.write('/**\n'
1260                          ' * %s_call_%s_finish:\n'
1261                          ' * @proxy: A #%sProxy.\n'
1262                          %(i.name_lower, m.name_lower, i.camel_name))
1263             for a in m.out_args:
1264                 self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
1265             self.c.write(self.docbook_gen.expand(
1266                     ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_call_%s().\n'
1267                     ' * @error: Return location for error or %%NULL.\n'
1268                     ' *\n'
1269                     ' * Finishes an operation started with %s_call_%s().\n'
1270                     ' *\n'
1271                     ' * Returns: (skip): %%TRUE if the call succeded, %%FALSE if @error is set.\n'
1272                     %(i.name_lower, m.name_lower, i.name_lower, m.name_lower), False))
1273             self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
1274             self.c.write('gboolean\n'
1275                          '%s_call_%s_finish (\n'
1276                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
1277             for a in m.out_args:
1278                 self.c.write(',\n    %sout_%s'%(a.ctype_out, a.name))
1279             self.c.write(',\n'
1280                          '    GAsyncResult *res,\n'
1281                          '    GError **error)\n'
1282                          '{\n'
1283                          '  GVariant *_ret;\n'
1284                          '  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n'
1285                          '  if (_ret == NULL)\n'
1286                          '    goto _out;\n')
1287             self.c.write('  g_variant_get (_ret,\n'
1288                          '                 \"(')
1289             for a in m.out_args:
1290                 self.c.write('%s'%(a.format_out))
1291             self.c.write(')"')
1292             for a in m.out_args:
1293                 self.c.write(',\n                 out_%s'%(a.name))
1294             self.c.write(');\n'
1295                          '  g_variant_unref (_ret);\n')
1296             self.c.write('_out:\n'
1297                          '  return _ret != NULL;\n'
1298                          '}\n'
1299                          '\n')
1300
1301
1302             # sync
1303             self.c.write('/**\n'
1304                          ' * %s_call_%s_sync:\n'
1305                          ' * @proxy: A #%sProxy.\n'
1306                          %(i.name_lower, m.name_lower, i.camel_name))
1307             for a in m.in_args:
1308                 self.c.write(' * @%s: Argument to pass with the method invocation.\n'%(a.name))
1309             for a in m.out_args:
1310                 self.c.write(' * @out_%s: (out): Return location for return parameter or %%NULL to ignore.\n'%(a.name))
1311             self.c.write(self.docbook_gen.expand(
1312                     ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
1313                     ' * @error: Return location for error or %%NULL.\n'
1314                     ' *\n'
1315                     ' * Synchronously invokes the %s.%s() D-Bus method on @proxy. The calling thread is blocked until a reply is received.\n'
1316                     ' *\n'
1317                     ' * See %s_call_%s() for the asynchronous version of this method.\n'
1318                     ' *\n'
1319                     ' * Returns: (skip): %%TRUE if the call succeded, %%FALSE if @error is set.\n'
1320                     %(i.name, m.name, i.name_lower, m.name_lower), False))
1321             self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
1322             self.c.write('gboolean\n'
1323                          '%s_call_%s_sync (\n'
1324                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
1325             for a in m.in_args:
1326                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
1327             for a in m.out_args:
1328                 self.c.write(',\n    %sout_%s'%(a.ctype_out, a.name))
1329             self.c.write(',\n'
1330                          '    GCancellable *cancellable,\n'
1331                          '    GError **error)\n'
1332                          '{\n'
1333                          '  GVariant *_ret;\n')
1334             self.c.write('  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n'
1335                          '    "%s",\n'
1336                          '    g_variant_new ("('%(m.name))
1337             for a in m.in_args:
1338                 self.c.write('%s'%(a.format_in))
1339             self.c.write(')"')
1340             for a in m.in_args:
1341                 self.c.write(',\n                   %s'%(a.name))
1342             self.c.write('),\n'
1343                          '    G_DBUS_CALL_FLAGS_NONE,\n'
1344                          '    -1,\n'
1345                          '    cancellable,\n'
1346                          '    error);\n'
1347                          '  if (_ret == NULL)\n'
1348                          '    goto _out;\n')
1349             self.c.write('  g_variant_get (_ret,\n'
1350                          '                 \"(')
1351             for a in m.out_args:
1352                 self.c.write('%s'%(a.format_out))
1353             self.c.write(')"')
1354             for a in m.out_args:
1355                 self.c.write(',\n                 out_%s'%(a.name))
1356             self.c.write(');\n'
1357                          '  g_variant_unref (_ret);\n')
1358             self.c.write('_out:\n'
1359                          '  return _ret != NULL;\n'
1360                          '}\n'
1361                          '\n')
1362
1363     # ---------------------------------------------------------------------------------------------------
1364
1365     def generate_method_completers(self, i):
1366         for m in i.methods:
1367             self.c.write('/**\n'
1368                          ' * %s_complete_%s:\n'
1369                          ' * @object: A #%s.\n'
1370                          ' * @invocation: (transfer full): A #GDBusMethodInvocation.\n'
1371                          %(i.name_lower, m.name_lower, i.camel_name))
1372             for a in m.out_args:
1373                 self.c.write(' * @%s: Parameter to return.\n'%(a.name))
1374             self.c.write(self.docbook_gen.expand(
1375                     ' *\n'
1376                     ' * Helper function used in service implementations to finish handling invocations of the %s.%s() D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.\n'
1377                     ' *\n'
1378                     ' * This method will free @invocation, you cannot use it afterwards.\n'
1379                     %(i.name, m.name), False))
1380             self.write_gtkdoc_deprecated_and_since_and_close(m, self.c, 0)
1381             self.c.write('void\n'
1382                          '%s_complete_%s (\n'
1383                          '    %s *object,\n'
1384                          '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
1385             for a in m.out_args:
1386                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
1387             self.c.write(')\n'
1388                          '{\n')
1389
1390             self.c.write('  g_dbus_method_invocation_return_value (invocation,\n'
1391                          '    g_variant_new ("(')
1392             for a in m.out_args:
1393                 self.c.write('%s'%(a.format_in))
1394             self.c.write(')"')
1395             for a in m.out_args:
1396                 self.c.write(',\n                   %s'%(a.name))
1397             self.c.write('));\n'
1398                          '}\n'
1399                          '\n')
1400
1401     # ---------------------------------------------------------------------------------------------------
1402
1403     def generate_proxy(self, i):
1404         # class boilerplate
1405         self.c.write('/* ------------------------------------------------------------------------ */\n'
1406                      '\n')
1407
1408         self.c.write(self.docbook_gen.expand(
1409                 '/**\n'
1410                 ' * %sProxy:\n'
1411                 ' *\n'
1412                 ' * The #%sProxy structure contains only private data and should only be accessed using the provided API.\n'
1413                 %(i.camel_name, i.camel_name), False))
1414         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1415         self.c.write('\n')
1416
1417         self.c.write(self.docbook_gen.expand(
1418                 '/**\n'
1419                 ' * %sProxyClass:\n'
1420                 ' * @parent_class: The parent class.\n'
1421                 ' *\n'
1422                 ' * Class structure for #%sProxy.\n'
1423                 %(i.camel_name, i.camel_name), False))
1424         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1425         self.c.write('\n')
1426
1427         self.c.write('static void\n'
1428                      '%s_proxy_iface_init (%sIface *iface)\n'
1429                      '{\n'
1430                      '}\n'
1431                      '\n'%(i.name_lower, i.camel_name))
1432         self.c.write('#define %s_proxy_get_type %s_proxy_get_type\n'%(i.name_lower, i.name_lower))
1433         self.c.write('G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n'%(i.camel_name, i.name_lower))
1434         self.c.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init));\n'%(i.ns_upper, i.name_upper, i.name_lower))
1435         self.c.write('#undef %s_proxy_get_type\n'
1436                      '\n'%(i.name_lower))
1437
1438         # property accessors
1439         #
1440         # Note that we are guaranteed that prop_id starts at 1 and is
1441         # laid out in the same order as introspection data pointers
1442         #
1443         self.c.write('static void\n'
1444                      '%s_proxy_get_property (GObject      *object,\n'
1445                      '  guint         prop_id,\n'
1446                      '  GValue       *value,\n'
1447                      '  GParamSpec   *pspec)\n'
1448                      '{\n'%(i.name_lower))
1449         if len(i.properties) > 0:
1450             self.c.write('  const _ExtendedGDBusPropertyInfo *info;\n'
1451                          '  GVariant *variant;\n'
1452                          '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
1453                          '  info = _%s_property_info_pointers[prop_id - 1];\n'
1454                          '  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);\n'
1455                          '  if (info->use_gvariant)\n'
1456                          '    {\n'
1457                          '      g_value_set_variant (value, variant);\n'
1458                          '    }\n'
1459                          '  else\n'
1460                          '    {\n'
1461                          # could be that we don't have the value in cache - in that case, we do
1462                          # nothing and the user gets the default value for the GType
1463                          '      if (variant != NULL)\n'
1464                          '        g_dbus_gvariant_to_gvalue (variant, value);\n'
1465                          '    }\n'
1466                          '  if (variant != NULL)\n'
1467                          '    g_variant_unref (variant);\n'
1468                          %(len(i.properties), i.name_lower))
1469         self.c.write('}\n'
1470                      '\n')
1471         if len(i.properties) > 0:
1472             self.c.write('static void\n'
1473                          '%s_proxy_set_property_cb (GDBusProxy *proxy,\n'
1474                          '  GAsyncResult *res,\n'
1475                          '  gpointer      user_data)\n'
1476                          '{\n'%(i.name_lower))
1477             self.c.write('  const _ExtendedGDBusPropertyInfo *info = user_data;\n'
1478                          '  GError *error;\n'
1479                          '  error = NULL;\n'
1480                          '  if (!g_dbus_proxy_call_finish (proxy, res, &error))\n'
1481                          '    {\n'
1482                          '      g_warning ("Error setting property `%%s\' on interface %s: %%s (%%s, %%d)",\n'
1483                          '                 info->parent_struct.name, \n'
1484                          '                 error->message, g_quark_to_string (error->domain), error->code);\n'
1485                          '      g_error_free (error);\n'
1486                          '    }\n'
1487                          %(i.name))
1488             self.c.write('}\n'
1489                          '\n')
1490         self.c.write('static void\n'
1491                      '%s_proxy_set_property (GObject      *object,\n'
1492                      '  guint         prop_id,\n'
1493                      '  const GValue *value,\n'
1494                      '  GParamSpec   *pspec)\n'
1495                      '{\n'%(i.name_lower))
1496         if len(i.properties) > 0:
1497             self.c.write('  const _ExtendedGDBusPropertyInfo *info;\n'
1498                          '  GVariant *variant;\n'
1499                          '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
1500                          '  info = _%s_property_info_pointers[prop_id - 1];\n'
1501                          '  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));\n'
1502                          '  g_dbus_proxy_call (G_DBUS_PROXY (object),\n'
1503                          '    "org.freedesktop.DBus.Properties.Set",\n'
1504                          '    g_variant_new ("(ssv)", "%s", info->parent_struct.name, variant),\n'
1505                          '    G_DBUS_CALL_FLAGS_NONE,\n'
1506                          '    -1,\n'
1507                          '    NULL, (GAsyncReadyCallback) %s_proxy_set_property_cb, (gpointer) info);\n'
1508                          '  g_variant_unref (variant);\n'
1509                          %(len(i.properties), i.name_lower, i.name, i.name_lower))
1510         self.c.write('}\n'
1511                      '\n')
1512
1513         # signal received
1514         self.c.write('static void\n'
1515                      '%s_proxy_g_signal (GDBusProxy *proxy,\n'
1516                      '  const gchar *sender_name,\n'
1517                      '  const gchar *signal_name,\n'
1518                      '  GVariant *parameters)\n'
1519                      '{\n'%(i.name_lower))
1520         self.c.write('  _ExtendedGDBusSignalInfo *info;\n'
1521                      '  GVariantIter iter;\n'
1522                      '  GVariant *child;\n'
1523                      '  GValue *paramv;\n'
1524                      '  guint num_params;\n'
1525                      '  guint n;\n'
1526                      '  guint signal_id;\n');
1527         # Note: info could be NULL if we are talking to a newer version of the interface
1528         self.c.write('  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_%s_interface_info, signal_name);\n'
1529                      '  if (info == NULL)\n'
1530                      '    return;\n'
1531                      %(i.name_lower))
1532         self.c.write ('  num_params = g_variant_n_children (parameters);\n'
1533                       '  paramv = g_new0 (GValue, num_params + 1);\n'
1534                       '  g_value_init (&paramv[0], %sTYPE_%s);\n'
1535                       '  g_value_set_object (&paramv[0], proxy);\n'
1536                       %(i.ns_upper, i.name_upper))
1537         self.c.write('  g_variant_iter_init (&iter, parameters);\n'
1538                      '  n = 1;\n'
1539                      '  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
1540                      '    {\n'
1541                      '      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];\n'
1542                      '      if (arg_info->use_gvariant)\n'
1543                      '        {\n'
1544                      '          g_value_init (&paramv[n], G_TYPE_VARIANT);\n'
1545                      '          g_value_set_variant (&paramv[n], child);\n'
1546                      '          n++;\n'
1547                      '        }\n'
1548                      '      else\n'
1549                      '        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n'
1550                      '      g_variant_unref (child);\n'
1551                      '    }\n'
1552                      )
1553         self.c.write('  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n'
1554                      %(i.ns_upper, i.name_upper))
1555         self.c.write('  g_signal_emitv (paramv, signal_id, 0, NULL);\n')
1556         self.c.write('  for (n = 0; n < num_params + 1; n++)\n'
1557                      '    g_value_unset (&paramv[n]);\n'
1558                      '  g_free (paramv);\n')
1559         self.c.write('}\n'
1560                      '\n')
1561
1562         # property changed
1563         self.c.write('static void\n'
1564                      '%s_proxy_g_properties_changed (GDBusProxy *proxy,\n'
1565                      '  GVariant *changed_properties,\n'
1566                      '  const gchar *const *invalidated_properties)\n'
1567                      '{\n'%(i.name_lower))
1568         # Note: info could be NULL if we are talking to a newer version of the interface
1569         self.c.write('  guint n;\n'
1570                      '  const gchar *key;\n'
1571                      '  GVariantIter *iter;\n'
1572                      '  _ExtendedGDBusPropertyInfo *info;\n'
1573                      '  g_variant_get (changed_properties, "a{sv}", &iter);\n'
1574                      '  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))\n'
1575                      '    {\n'
1576                      '      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, key);\n'
1577                      '      if (info != NULL)\n'
1578                      '        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n'
1579                      '    }\n'
1580                      '  g_variant_iter_free (iter);\n'
1581                      '  for (n = 0; invalidated_properties[n] != NULL; n++)\n'
1582                      '    {\n'
1583                      '      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, invalidated_properties[n]);\n'
1584                      '      if (info != NULL)\n'
1585                      '        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n'
1586                      '    }\n'
1587                      '}\n'
1588                      '\n'
1589                      %(i.name_lower, i.name_lower))
1590
1591         # class boilerplate
1592         self.c.write('static void\n'
1593                      '%s_proxy_init (%sProxy *proxy)\n'
1594                      '{\n'
1595                      '  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), %s_interface_info ());\n'
1596                      '}\n'
1597                      '\n'%(i.name_lower, i.camel_name, i.name_lower))
1598         self.c.write('static void\n'
1599                      '%s_proxy_class_init (%sProxyClass *klass)\n'
1600                      '{\n'
1601                      '  GObjectClass *gobject_class;\n'
1602                      '  GDBusProxyClass *proxy_class;\n'
1603                      '\n'
1604                      '  gobject_class = G_OBJECT_CLASS (klass);\n'
1605                      '  gobject_class->get_property = %s_proxy_get_property;\n'
1606                      '  gobject_class->set_property = %s_proxy_set_property;\n'
1607                      '\n'
1608                      '  proxy_class = G_DBUS_PROXY_CLASS (klass);\n'
1609                      '  proxy_class->g_signal = %s_proxy_g_signal;\n'
1610                      '  proxy_class->g_properties_changed = %s_proxy_g_properties_changed;\n'
1611                      '\n'%(i.name_lower, i.camel_name, i.name_lower, i.name_lower, i.name_lower, i.name_lower))
1612         if len(i.properties) > 0:
1613             self.c.write('\n'
1614                          '  %s_override_properties (gobject_class, 1);\n'%(i.name_lower))
1615         self.c.write('}\n'
1616                      '\n')
1617
1618         # constructors
1619         self.c.write(self.docbook_gen.expand(
1620                 '/**\n'
1621                 ' * %s_proxy_new:\n'
1622                 ' * @connection: A #GDBusConnection.\n'
1623                 ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
1624                 ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
1625                 ' * @object_path: An object path.\n'
1626                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
1627                 ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
1628                 ' * @user_data: User data to pass to @callback.\n'
1629                 ' *\n'
1630                 ' * Asynchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new() for more details.\n'
1631                 ' *\n'
1632                 ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
1633                 ' * You can then call %s_proxy_new_finish() to get the result of the operation.\n'
1634                 ' *\n'
1635                 ' * See %s_proxy_new_sync() for the synchronous, blocking version of this constructor.\n'
1636                 %(i.name_lower, i.name, i.name_lower, i.name_lower), False))
1637         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1638         self.c.write('void\n'
1639                      '%s_proxy_new (\n'
1640                      '    GDBusConnection     *connection,\n'
1641                      '    GDBusProxyFlags      flags,\n'
1642                      '    const gchar         *name,\n'
1643                      '    const gchar         *object_path,\n'
1644                      '    GCancellable        *cancellable,\n'
1645                      '    GAsyncReadyCallback  callback,\n'
1646                      '    gpointer             user_data)\n'
1647                      '{\n'
1648                      '  g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
1649                      '}\n'
1650                      '\n'
1651                      %(i.name_lower, i.ns_upper, i.name_upper, i.name))
1652         self.c.write('/**\n'
1653                      ' * %s_proxy_new_finish:\n'
1654                      ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new().\n'
1655                      ' * @error: Return location for error or %%NULL\n'
1656                      ' *\n'
1657                      ' * Finishes an operation started with %s_proxy_new().\n'
1658                      ' *\n'
1659                      ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
1660                      %(i.name_lower, i.name_lower, i.name_lower, i.camel_name))
1661         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1662         self.c.write('%s *\n'
1663                      '%s_proxy_new_finish (\n'
1664                      '    GAsyncResult        *res,\n'
1665                      '    GError             **error)\n'
1666                      '{\n'
1667                      '  GObject *ret;\n'
1668                      '  GObject *source_object;\n'
1669                      '  source_object = g_async_result_get_source_object (res);\n'
1670                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
1671                      '  g_object_unref (source_object);\n'
1672                      '  if (ret != NULL)\n'
1673                      '    return %s%s (ret);\n'
1674                      '  else\n'
1675                      '    return NULL;\n'
1676                      '}\n'
1677                      '\n'
1678                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
1679         self.c.write(self.docbook_gen.expand(
1680                 '/**\n'
1681                 ' * %s_proxy_new_sync:\n'
1682                 ' * @connection: A #GDBusConnection.\n'
1683                 ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
1684                 ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
1685                 ' * @object_path: An object path.\n'
1686                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
1687                 ' * @error: Return location for error or %%NULL\n'
1688                 ' *\n'
1689                 ' * Synchronously creates a proxy for the D-Bus interface #%s. See g_dbus_proxy_new_sync() for more details.\n'
1690                 ' *\n'
1691                 ' * The calling thread is blocked until a reply is received.\n'
1692                 ' *\n'
1693                 ' * See %s_proxy_new() for the asynchronous version of this constructor.\n'
1694                 ' *\n'
1695                 ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
1696                 %(i.name_lower, i.name, i.name_lower, i.camel_name), False))
1697         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1698         self.c.write('%s *\n'
1699                      '%s_proxy_new_sync (\n'
1700                      '    GDBusConnection     *connection,\n'
1701                      '    GDBusProxyFlags      flags,\n'
1702                      '    const gchar         *name,\n'
1703                      '    const gchar         *object_path,\n'
1704                      '    GCancellable        *cancellable,\n'
1705                      '    GError             **error)\n'
1706                      '{\n'
1707                      '  GInitable *ret;\n'
1708                      '  ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
1709                      '  if (ret != NULL)\n'
1710                      '    return %s%s (ret);\n'
1711                      '  else\n'
1712                      '    return NULL;\n'
1713                      '}\n'
1714                      '\n'
1715                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
1716         self.c.write('\n')
1717         self.c.write(self.docbook_gen.expand(
1718                 '/**\n'
1719                 ' * %s_proxy_new_for_bus:\n'
1720                 ' * @bus_type: A #GBusType.\n'
1721                 ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
1722                 ' * @name: A bus name (well-known or unique).\n'
1723                 ' * @object_path: An object path.\n'
1724                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
1725                 ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
1726                 ' * @user_data: User data to pass to @callback.\n'
1727                 ' *\n'
1728                 ' * Like %s_proxy_new() but takes a #GBusType instead of a #GDBusConnection.\n'
1729                 ' *\n'
1730                 ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
1731                 ' * You can then call %s_proxy_new_for_bus_finish() to get the result of the operation.\n'
1732                 ' *\n'
1733                 ' * See %s_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n'
1734                 %(i.name_lower, i.name_lower, i.name_lower, i.name_lower), False))
1735         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1736         self.c.write('void\n'
1737                      '%s_proxy_new_for_bus (\n'
1738                      '    GBusType             bus_type,\n'
1739                      '    GDBusProxyFlags      flags,\n'
1740                      '    const gchar         *name,\n'
1741                      '    const gchar         *object_path,\n'
1742                      '    GCancellable        *cancellable,\n'
1743                      '    GAsyncReadyCallback  callback,\n'
1744                      '    gpointer             user_data)\n'
1745                      '{\n'
1746                      '  g_async_initable_new_async (%sTYPE_%s_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
1747                      '}\n'
1748                      '\n'
1749                      %(i.name_lower, i.ns_upper, i.name_upper, i.name))
1750         self.c.write('/**\n'
1751                      ' * %s_proxy_new_for_bus_finish:\n'
1752                      ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %s_proxy_new_for_bus().\n'
1753                      ' * @error: Return location for error or %%NULL\n'
1754                      ' *\n'
1755                      ' * Finishes an operation started with %s_proxy_new_for_bus().\n'
1756                      ' *\n'
1757                      ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
1758                      %(i.name_lower, i.name_lower, i.name_lower, i.camel_name))
1759         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1760         self.c.write('%s *\n'
1761                      '%s_proxy_new_for_bus_finish (\n'
1762                      '    GAsyncResult        *res,\n'
1763                      '    GError             **error)\n'
1764                      '{\n'
1765                      '  GObject *ret;\n'
1766                      '  GObject *source_object;\n'
1767                      '  source_object = g_async_result_get_source_object (res);\n'
1768                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
1769                      '  g_object_unref (source_object);\n'
1770                      '  if (ret != NULL)\n'
1771                      '    return %s%s (ret);\n'
1772                      '  else\n'
1773                      '    return NULL;\n'
1774                      '}\n'
1775                      '\n'
1776                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
1777         self.c.write(self.docbook_gen.expand(
1778                 '/**\n'
1779                 ' * %s_proxy_new_for_bus_sync:\n'
1780                 ' * @bus_type: A #GBusType.\n'
1781                 ' * @flags: Flags from the #GDBusProxyFlags enumeration.\n'
1782                 ' * @name: A bus name (well-known or unique).\n'
1783                 ' * @object_path: An object path.\n'
1784                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
1785                 ' * @error: Return location for error or %%NULL\n'
1786                 ' *\n'
1787                 ' * Like %s_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n'
1788                 ' *\n'
1789                 ' * The calling thread is blocked until a reply is received.\n'
1790                 ' *\n'
1791                 ' * See %s_proxy_new_for_bus() for the asynchronous version of this constructor.\n'
1792                 ' *\n'
1793                 ' * Returns: (transfer full) (type %sProxy): The constructed proxy object or %%NULL if @error is set.\n'
1794                 %(i.name_lower, i.name_lower, i.name_lower, i.camel_name), False))
1795         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1796         self.c.write('%s *\n'
1797                      '%s_proxy_new_for_bus_sync (\n'
1798                      '    GBusType             bus_type,\n'
1799                      '    GDBusProxyFlags      flags,\n'
1800                      '    const gchar         *name,\n'
1801                      '    const gchar         *object_path,\n'
1802                      '    GCancellable        *cancellable,\n'
1803                      '    GError             **error)\n'
1804                      '{\n'
1805                      '  GInitable *ret;\n'
1806                      '  ret = g_initable_new (%sTYPE_%s_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "%s", NULL);\n'
1807                      '  if (ret != NULL)\n'
1808                      '    return %s%s (ret);\n'
1809                      '  else\n'
1810                      '    return NULL;\n'
1811                      '}\n'
1812                      '\n'
1813                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
1814         self.c.write('\n')
1815
1816     # ---------------------------------------------------------------------------------------------------
1817
1818     def generate_skeleton(self, i):
1819         # class boilerplate
1820         self.c.write('/* ------------------------------------------------------------------------ */\n'
1821                      '\n')
1822
1823         self.c.write(self.docbook_gen.expand(
1824                 '/**\n'
1825                 ' * %sSkeleton:\n'
1826                 ' *\n'
1827                 ' * The #%sSkeleton structure contains only private data and should only be accessed using the provided API.\n'
1828                 %(i.camel_name, i.camel_name), False))
1829         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1830         self.c.write('\n')
1831
1832         self.c.write(self.docbook_gen.expand(
1833                 '/**\n'
1834                 ' * %sSkeletonClass:\n'
1835                 ' * @parent_class: The parent class.\n'
1836                 ' *\n'
1837                 ' * Class structure for #%sSkeleton.\n'
1838                 %(i.camel_name, i.camel_name), False))
1839         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
1840         self.c.write('\n')
1841
1842         self.c.write('struct _%sSkeletonPrivate\n'
1843                      '{\n'
1844                      '  GValueArray *properties;\n'
1845                      '  GList *changed_properties;\n'
1846                      '  GSource *changed_properties_idle_source;\n'
1847                      '  GMainContext *context;\n'
1848                      '  GMutex *lock;\n'
1849                      '};\n'
1850                      '\n'%i.camel_name)
1851
1852         self.c.write('static void\n'
1853                      '_%s_skeleton_handle_method_call (\n'
1854                      '  GDBusConnection *connection,\n'
1855                      '  const gchar *sender,\n'
1856                      '  const gchar *object_path,\n'
1857                      '  const gchar *interface_name,\n'
1858                      '  const gchar *method_name,\n'
1859                      '  GVariant *parameters,\n'
1860                      '  GDBusMethodInvocation *invocation,\n'
1861                      '  gpointer user_data)\n'
1862                      '{\n'
1863                      '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
1864                      '  _ExtendedGDBusMethodInfo *info;\n'
1865                      '  GVariantIter iter;\n'
1866                      '  GVariant *child;\n'
1867                      '  GValue *paramv;\n'
1868                      '  guint num_params;\n'
1869                      '  guint n;\n'
1870                      '  guint signal_id;\n'
1871                      '  GValue return_value = {0};\n'
1872                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1873         self.c.write('  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);\n'
1874                      '  g_assert (info != NULL);\n'
1875                      %())
1876         self.c.write ('  num_params = g_variant_n_children (parameters);\n'
1877                       '  paramv = g_new0 (GValue, num_params + 2);\n'
1878                       '  g_value_init (&paramv[0], %sTYPE_%s);\n'
1879                       '  g_value_set_object (&paramv[0], skeleton);\n'
1880                       '  g_value_init (&paramv[1], G_TYPE_DBUS_METHOD_INVOCATION);\n'
1881                       '  g_value_set_object (&paramv[1], invocation);\n'
1882                       %(i.ns_upper, i.name_upper))
1883         self.c.write('  g_variant_iter_init (&iter, parameters);\n'
1884                      '  n = 2;\n'
1885                      '  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
1886                      '    {\n'
1887                      '      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - 2];\n'
1888                      '      if (arg_info->use_gvariant)\n'
1889                      '        {\n'
1890                      '          g_value_init (&paramv[n], G_TYPE_VARIANT);\n'
1891                      '          g_value_set_variant (&paramv[n], child);\n'
1892                      '          n++;\n'
1893                      '        }\n'
1894                      '      else\n'
1895                      '        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n'
1896                      '      g_variant_unref (child);\n'
1897                      '    }\n'
1898                      )
1899         self.c.write('  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n'
1900                      %(i.ns_upper, i.name_upper))
1901         self.c.write('  g_value_init (&return_value, G_TYPE_BOOLEAN);\n'
1902                      '  g_signal_emitv (paramv, signal_id, 0, &return_value);\n'
1903                      '  if (!g_value_get_boolean (&return_value))\n'
1904                      '    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);\n'
1905                      '  g_value_unset (&return_value);\n'
1906                      )
1907         self.c.write('  for (n = 0; n < num_params + 2; n++)\n'
1908                      '    g_value_unset (&paramv[n]);\n'
1909                      '  g_free (paramv);\n')
1910         self.c.write('}\n'
1911                      '\n')
1912
1913         self.c.write('static GVariant *\n'
1914                      '_%s_skeleton_handle_get_property (\n'
1915                      '  GDBusConnection *connection,\n'
1916                      '  const gchar *sender,\n'
1917                      '  const gchar *object_path,\n'
1918                      '  const gchar *interface_name,\n'
1919                      '  const gchar *property_name,\n'
1920                      '  GError **error,\n'
1921                      '  gpointer user_data)\n'
1922                      '{\n'
1923                      '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
1924                      '  GValue value = {0};\n'
1925                      '  GParamSpec *pspec;\n'
1926                      '  _ExtendedGDBusPropertyInfo *info;\n'
1927                      '  GVariant *ret;\n'
1928                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1929         self.c.write('  ret = NULL;\n'
1930                      '  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, property_name);\n'
1931                      '  g_assert (info != NULL);\n'
1932                      '  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n'
1933                      '  if (pspec == NULL)\n'
1934                      '    {\n'
1935                      '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
1936                      '    }\n'
1937                      '  else\n'
1938                      '    {\n'
1939                      '      g_value_init (&value, pspec->value_type);\n'
1940                      '      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n'
1941                      '      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));\n'
1942                      '      g_value_unset (&value);\n'
1943                      '    }\n'
1944                      '  return ret;\n'
1945                      '}\n'
1946                      '\n'
1947                      %(i.name_lower))
1948
1949         self.c.write('static gboolean\n'
1950                      '_%s_skeleton_handle_set_property (\n'
1951                      '  GDBusConnection *connection,\n'
1952                      '  const gchar *sender,\n'
1953                      '  const gchar *object_path,\n'
1954                      '  const gchar *interface_name,\n'
1955                      '  const gchar *property_name,\n'
1956                      '  GVariant *variant,\n'
1957                      '  GError **error,\n'
1958                      '  gpointer user_data)\n'
1959                      '{\n'
1960                      '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
1961                      '  GValue value = {0};\n'
1962                      '  GParamSpec *pspec;\n'
1963                      '  _ExtendedGDBusPropertyInfo *info;\n'
1964                      '  gboolean ret;\n'
1965                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1966         self.c.write('  ret = FALSE;\n'
1967                      '  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, property_name);\n'
1968                      '  g_assert (info != NULL);\n'
1969                      '  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);\n'
1970                      '  if (pspec == NULL)\n'
1971                      '    {\n'
1972                      '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
1973                      '    }\n'
1974                      '  else\n'
1975                      '    {\n'
1976                      '      if (info->use_gvariant)\n'
1977                      '        g_value_set_variant (&value, variant);\n'
1978                      '      else\n'
1979                      '        g_dbus_gvariant_to_gvalue (variant, &value);\n'
1980                      '      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);\n'
1981                      '      g_value_unset (&value);\n'
1982                      '      ret = TRUE;\n'
1983                      '    }\n'
1984                      '  return ret;\n'
1985                      '}\n'
1986                      '\n'
1987                      %(i.name_lower))
1988
1989
1990         self.c.write('static const GDBusInterfaceVTable _%s_skeleton_vtable =\n'
1991                      '{\n'
1992                      '  _%s_skeleton_handle_method_call,\n'
1993                      '  _%s_skeleton_handle_get_property,\n'
1994                      '  _%s_skeleton_handle_set_property\n'
1995                      '};\n'
1996                      '\n'%(i.name_lower, i.name_lower, i.name_lower, i.name_lower))
1997
1998         self.c.write('static GDBusInterfaceInfo *\n'
1999                      '%s_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton)\n'
2000                      '{\n'
2001                      '  return %s_interface_info ();\n'
2002                      %(i.name_lower, i.name_lower))
2003         self.c.write('}\n'
2004                      '\n')
2005
2006         self.c.write('static GDBusInterfaceVTable *\n'
2007                      '%s_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton)\n'
2008                      '{\n'
2009                      '  return (GDBusInterfaceVTable *) &_%s_skeleton_vtable;\n'
2010                      %(i.name_lower, i.name_lower))
2011         self.c.write('}\n'
2012                      '\n')
2013
2014         self.c.write('static GVariant *\n'
2015                      '%s_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)\n'
2016                      '{\n'
2017                      '  %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n'
2018                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
2019         self.c.write('\n'
2020                      '  GVariantBuilder builder;\n'
2021                      '  guint n;\n'
2022                      '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
2023                      '  if (_%s_interface_info.parent_struct.properties == NULL)\n'
2024                      '    goto out;\n'
2025                      '  for (n = 0; _%s_interface_info.parent_struct.properties[n] != NULL; n++)\n'
2026                      '    {\n'
2027                      '      GDBusPropertyInfo *info = _%s_interface_info.parent_struct.properties[n];\n'
2028                      '      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n'
2029                      '        {\n'
2030                      '          GVariant *value;\n'
2031                      '          value = _%s_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", info->name, NULL, skeleton);\n'
2032                      '          if (value != NULL)\n'
2033                      '            {\n'
2034                      '              g_variant_take_ref (value);\n'
2035                      '              g_variant_builder_add (&builder, "{sv}", info->name, value);\n'
2036                      '              g_variant_unref (value);\n'
2037                      '            }\n'
2038                      '        }\n'
2039                      '    }\n'
2040                      'out:\n'
2041                      '  return g_variant_builder_end (&builder);\n'
2042                      '}\n'
2043                      '\n'
2044                      %(i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name))
2045
2046         if len(i.properties) > 0:
2047             self.c.write('static gboolean _%s_emit_changed (gpointer user_data);\n'
2048                          '\n'
2049                          %(i.name_lower))
2050
2051         self.c.write('static void\n'
2052                      '%s_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)\n'
2053                      '{\n'
2054                      %(i.name_lower))
2055         if len(i.properties) > 0:
2056             self.c.write('  %sSkeleton *skeleton = %s%s_SKELETON (_skeleton);\n'
2057                          '  gboolean emit_changed = FALSE;\n'
2058                          '\n'
2059                          '  g_mutex_lock (skeleton->priv->lock);\n'
2060                          '  if (skeleton->priv->changed_properties_idle_source != NULL)\n'
2061                          '    {\n'
2062                          '      g_source_destroy (skeleton->priv->changed_properties_idle_source);\n'
2063                          '      skeleton->priv->changed_properties_idle_source = NULL;\n'
2064                          '      emit_changed = TRUE;\n'
2065                          '    }\n'
2066                          '  g_mutex_unlock (skeleton->priv->lock);\n'
2067                          '\n'
2068                          '  if (emit_changed)\n'
2069                          '    _%s_emit_changed (skeleton);\n'
2070                          %(i.camel_name, i.ns_upper, i.name_upper, i.name_lower))
2071         self.c.write('}\n'
2072                      '\n')
2073
2074         for s in i.signals:
2075             self.c.write('static void\n'
2076                          '_%s_on_signal_%s (\n'
2077                          '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
2078             for a in s.args:
2079                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
2080             self.c.write(')\n'
2081                          '{\n'
2082                          '  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
2083                          '  GDBusConnection *connection = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton));\n'
2084                          %(i.camel_name, i.ns_upper, i.name_upper))
2085             self.c.write('  if (connection == NULL)\n'
2086                          '    return;\n'
2087                          '  g_dbus_connection_emit_signal (connection,\n'
2088                          '    NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "%s", "%s",\n'
2089                          '    g_variant_new ("('
2090                          %(i.name, s.name))
2091             for a in s.args:
2092                 self.c.write('%s'%(a.format_in))
2093             self.c.write(')"')
2094             for a in s.args:
2095                 self.c.write(',\n                   %s'%(a.name))
2096             self.c.write('), NULL);\n')
2097             self.c.write('}\n'
2098                          '\n')
2099
2100         self.c.write('static void\n'
2101                      '%s_skeleton_iface_init (%sIface *iface)\n'
2102                      '{\n'
2103                      %(i.name_lower, i.camel_name))
2104         for s in i.signals:
2105             self.c.write('  iface->%s = _%s_on_signal_%s;\n'
2106                          %(s.name_lower, i.name_lower, s.name_lower))
2107         self.c.write('}\n'
2108                      '\n')
2109         self.c.write('#define %s_skeleton_get_type %s_skeleton_get_type\n'%(i.name_lower, i.name_lower))
2110         self.c.write('G_DEFINE_TYPE_WITH_CODE (%sSkeleton, %s_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,\n'%(i.camel_name, i.name_lower))
2111         self.c.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_skeleton_iface_init));\n'%(i.ns_upper, i.name_upper, i.name_lower))
2112         self.c.write('#undef %s_skeleton_get_type\n'
2113                      '\n'%(i.name_lower))
2114
2115         # finalize
2116         self.c.write('static void\n'
2117                      '%s_skeleton_finalize (GObject *object)\n'
2118                      '{\n'%(i.name_lower))
2119         self.c.write('  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'%(i.camel_name, i.ns_upper, i.name_upper))
2120         if len(i.properties) > 0:
2121             self.c.write('  g_value_array_free (skeleton->priv->properties);\n')
2122         self.c.write('  g_list_foreach (skeleton->priv->changed_properties, (GFunc) _changed_property_free, NULL);\n')
2123         self.c.write('  g_list_free (skeleton->priv->changed_properties);\n')
2124         self.c.write('  if (skeleton->priv->changed_properties_idle_source != NULL)\n')
2125         self.c.write('    g_source_destroy (skeleton->priv->changed_properties_idle_source);\n')
2126         self.c.write('  if (skeleton->priv->context != NULL)\n')
2127         self.c.write('    g_main_context_unref (skeleton->priv->context);\n')
2128         self.c.write('  g_mutex_free (skeleton->priv->lock);\n')
2129         self.c.write('  G_OBJECT_CLASS (%s_skeleton_parent_class)->finalize (object);\n'
2130                      '}\n'
2131                      '\n'%(i.name_lower))
2132
2133         # property accessors (TODO: generate PropertiesChanged signals in setter)
2134         if len(i.properties) > 0:
2135             self.c.write('static void\n'
2136                          '%s_skeleton_get_property (GObject      *object,\n'
2137                          '  guint         prop_id,\n'
2138                          '  GValue       *value,\n'
2139                          '  GParamSpec   *pspec)\n'
2140                          '{\n'%(i.name_lower))
2141             self.c.write('  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
2142                          '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
2143                          '  g_mutex_lock (skeleton->priv->lock);\n'
2144                          '  g_value_copy (&skeleton->priv->properties->values[prop_id - 1], value);\n'
2145                          '  g_mutex_unlock (skeleton->priv->lock);\n'
2146                          %(i.camel_name, i.ns_upper, i.name_upper, len(i.properties)))
2147             self.c.write('}\n'
2148                          '\n')
2149
2150             # if property is already scheduled then re-use entry.. though it could be
2151             # that the user did
2152             #
2153             #  foo_set_prop_bar (object, "");
2154             #  foo_set_prop_bar (object, "blah");
2155             #
2156             # say, every update... In this case, where nothing happens, we obviously
2157             # don't want a PropertiesChanged() event. We can easily check for this
2158             # by comparing against the _original value_ recorded before the first
2159             # change event. If the latest value is not different from the original
2160             # one, we can simply ignore the ChangedProperty
2161             #
2162             self.c.write('static gboolean\n'
2163                          '_%s_emit_changed (gpointer user_data)\n'
2164                          '{\n'
2165                          '  %sSkeleton *skeleton = %s%s_SKELETON (user_data);\n'
2166                          %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
2167             self.c.write('  GList *l;\n'
2168                          '  GVariantBuilder builder;\n'
2169                          '  GVariantBuilder invalidated_builder;\n'
2170                          '  guint num_changes;\n'
2171                          '\n'
2172                          '  g_mutex_lock (skeleton->priv->lock);\n'
2173                          '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
2174                          '  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));\n'
2175                          '  for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)\n'
2176                          '    {\n'
2177                          '      ChangedProperty *cp = l->data;\n'
2178                          '      GVariant *variant;\n'
2179                          '      const GValue *cur_value;\n'
2180                          '\n'
2181                          '      cur_value = &skeleton->priv->properties->values[cp->prop_id - 1];\n'
2182                          '      if (!_g_value_equal (cur_value, &cp->orig_value))\n'
2183                          '        {\n'
2184                          '          variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));\n'
2185                          '          g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);\n'
2186                          '          g_variant_unref (variant);\n'
2187                          '          num_changes++;\n'
2188                          '        }\n'
2189                          '    }\n'
2190                          '  if (num_changes > 0)\n'
2191                          '    {\n'
2192                          '      g_dbus_connection_emit_signal (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)),\n'
2193                          '                                     NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),\n'
2194                          '                                     "org.freedesktop.DBus.Properties",\n'
2195                          '                                     "PropertiesChanged",\n'
2196                          '                                     g_variant_new ("(sa{sv}as)",\n'
2197                          '                                                    "%s",\n'
2198                          '                                                    &builder, &invalidated_builder),\n'
2199                          '                                     NULL);\n'
2200                          '    }\n'
2201                          '  else\n'
2202                          '    {\n'
2203                          '      g_variant_builder_clear (&builder);\n'
2204                          '      g_variant_builder_clear (&invalidated_builder);\n'
2205                          '    }\n'
2206                          %(i.name))
2207             self.c.write('  g_list_foreach (skeleton->priv->changed_properties, (GFunc) _changed_property_free, NULL);\n')
2208             self.c.write('  g_list_free (skeleton->priv->changed_properties);\n')
2209             self.c.write('  skeleton->priv->changed_properties = NULL;\n')
2210             self.c.write('  skeleton->priv->changed_properties_idle_source = NULL;\n')
2211             self.c.write('  g_mutex_unlock (skeleton->priv->lock);\n')
2212             self.c.write('  return FALSE;\n'
2213                          '}\n'
2214                          '\n')
2215             # holding lock while being called
2216             self.c.write('static void\n'
2217                          '_%s_schedule_emit_changed (%sSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)\n'
2218                          '{\n'
2219                          '  ChangedProperty *cp;\n'
2220                          '  GList *l;\n'
2221                          '  cp = NULL;\n'
2222                          '  for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)\n'
2223                          '    {\n'
2224                          '      ChangedProperty *i_cp = l->data;\n'
2225                          '      if (i_cp->info == info)\n'
2226                          '        {\n'
2227                          '          cp = i_cp;\n'
2228                          '          break;\n'
2229                          '        }\n'
2230                          '    }\n'
2231                          %(i.name_lower, i.camel_name))
2232             self.c.write('  if (cp == NULL)\n'
2233                          '    {\n'
2234                          '      cp = g_new0 (ChangedProperty, 1);\n'
2235                          '      cp->prop_id = prop_id;\n'
2236                          '      cp->info = info;\n'
2237                          '      skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);\n'
2238                          '      g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));\n'
2239                          '      g_value_copy (orig_value, &cp->orig_value);\n'
2240                          '    }\n'
2241                          '}\n'
2242                          '\n'
2243                          %())
2244
2245             # Postpone setting up the refresh source until the ::notify signal is emitted as
2246             # this allows use of g_object_freeze_notify()/g_object_thaw_notify() ...
2247             # This is useful when updating several properties from another thread than
2248             # where the idle will be emitted from
2249             self.c.write('static void\n'
2250                          '%s_skeleton_notify (GObject      *object,\n'
2251                          '  GParamSpec *pspec)\n'
2252                          '{\n'
2253                          '  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
2254                          '  g_mutex_lock (skeleton->priv->lock);\n'
2255                          '  if (skeleton->priv->changed_properties != NULL &&\n'
2256                          '      skeleton->priv->changed_properties_idle_source == NULL)\n'
2257                          '    {\n'
2258                          '      skeleton->priv->changed_properties_idle_source = g_idle_source_new ();\n'
2259                          '      g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);\n'
2260                          '      g_source_set_callback (skeleton->priv->changed_properties_idle_source, _%s_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);\n'
2261                          '      g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);\n'
2262                          '      g_source_unref (skeleton->priv->changed_properties_idle_source);\n'
2263                          '    }\n'
2264                          '  g_mutex_unlock (skeleton->priv->lock);\n'
2265                          '}\n'
2266                          '\n'
2267                          %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper, i.name_lower))
2268
2269             self.c.write('static void\n'
2270                          '%s_skeleton_set_property (GObject      *object,\n'
2271                          '  guint         prop_id,\n'
2272                          '  const GValue *value,\n'
2273                          '  GParamSpec   *pspec)\n'
2274                          '{\n'%(i.name_lower))
2275             self.c.write('  %sSkeleton *skeleton = %s%s_SKELETON (object);\n'
2276                          '  g_assert (prop_id != 0 && prop_id - 1 < %d);\n'
2277                          '  g_mutex_lock (skeleton->priv->lock);\n'
2278                          '  g_object_freeze_notify (object);\n'
2279                          '  if (!_g_value_equal (value, &skeleton->priv->properties->values[prop_id - 1]))\n'
2280                          '    {\n'
2281                          '      if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL)\n'
2282                          '        _%s_schedule_emit_changed (skeleton, _%s_property_info_pointers[prop_id - 1], prop_id, &skeleton->priv->properties->values[prop_id - 1]);\n'
2283                          '      g_value_copy (value, &skeleton->priv->properties->values[prop_id - 1]);\n'
2284                          '      g_object_notify_by_pspec (object, pspec);\n'
2285                          '    }\n'
2286                          '  g_mutex_unlock (skeleton->priv->lock);\n'
2287                          '  g_object_thaw_notify (object);\n'
2288                          %(i.camel_name, i.ns_upper, i.name_upper, len(i.properties), i.name_lower, i.name_lower))
2289             self.c.write('}\n'
2290                          '\n')
2291
2292         self.c.write('static void\n'
2293                      '%s_skeleton_init (%sSkeleton *skeleton)\n'
2294                      '{\n'
2295                      '  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, %sTYPE_%s_SKELETON, %sSkeletonPrivate);\n'
2296                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper, i.camel_name))
2297         self.c.write('  skeleton->priv->lock = g_mutex_new ();\n')
2298         self.c.write('  skeleton->priv->context = g_main_context_get_thread_default ();\n')
2299         self.c.write('  if (skeleton->priv->context != NULL)\n')
2300         self.c.write('    g_main_context_ref (skeleton->priv->context);\n')
2301         if len(i.properties) > 0:
2302             self.c.write('  skeleton->priv->properties = g_value_array_new (%d);\n'%(len(i.properties)))
2303             n = 0
2304             for p in i.properties:
2305                 self.c.write('  g_value_array_append (skeleton->priv->properties, NULL);\n')
2306                 self.c.write('  g_value_init (&skeleton->priv->properties->values[%d], %s);\n'%(n, p.arg.gtype))
2307                 n += 1
2308         self.c.write('}\n'
2309                      '\n')
2310         self.c.write('static void\n'
2311                      '%s_skeleton_class_init (%sSkeletonClass *klass)\n'
2312                      '{\n'
2313                      '  GObjectClass *gobject_class;\n'
2314                      '  GDBusInterfaceSkeletonClass *skeleton_class;\n'
2315                      '\n'
2316                      '  g_type_class_add_private (klass, sizeof (%sSkeletonPrivate));\n'
2317                      '\n'
2318                      '  gobject_class = G_OBJECT_CLASS (klass);\n'
2319                      '  gobject_class->finalize = %s_skeleton_finalize;\n'
2320                      %(i.name_lower, i.camel_name, i.camel_name, i.name_lower))
2321         if len(i.properties) > 0:
2322             self.c.write('  gobject_class->get_property = %s_skeleton_get_property;\n'
2323                          '  gobject_class->set_property = %s_skeleton_set_property;\n'
2324                          '  gobject_class->notify       = %s_skeleton_notify;\n'
2325                          '\n'%(i.name_lower, i.name_lower, i.name_lower))
2326             self.c.write('\n'
2327                          '  %s_override_properties (gobject_class, 1);\n'%(i.name_lower))
2328         self.c.write('\n'
2329                      '  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);\n');
2330         self.c.write('  skeleton_class->get_info = %s_skeleton_dbus_interface_get_info;\n'%(i.name_lower))
2331         self.c.write('  skeleton_class->get_properties = %s_skeleton_dbus_interface_get_properties;\n'%(i.name_lower))
2332         self.c.write('  skeleton_class->flush = %s_skeleton_dbus_interface_flush;\n'%(i.name_lower))
2333         self.c.write('  skeleton_class->get_vtable = %s_skeleton_dbus_interface_get_vtable;\n'%(i.name_lower))
2334         self.c.write('}\n'
2335                      '\n')
2336
2337         # constructors
2338         self.c.write(self.docbook_gen.expand(
2339                 '/**\n'
2340                 ' * %s_skeleton_new:\n'
2341                 ' *\n'
2342                 ' * Creates a skeleton object for the D-Bus interface #%s.\n'
2343                 ' *\n'
2344                 ' * Returns: (transfer full) (type %sSkeleton): The skeleton object.\n'
2345                 %(i.name_lower, i.name, i.camel_name), False))
2346         self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
2347         self.c.write('%s *\n'
2348                      '%s_skeleton_new (void)\n'
2349                      '{\n'
2350                      '  return %s%s (g_object_new (%sTYPE_%s_SKELETON, NULL));\n'
2351                      '}\n'
2352                      '\n'%(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
2353
2354     # ---------------------------------------------------------------------------------------------------
2355
2356     def generate_object(self):
2357         self.c.write('/* ------------------------------------------------------------------------\n'
2358                      ' * Code for Object, ObjectProxy and ObjectSkeleton\n'
2359                      ' * ------------------------------------------------------------------------\n'
2360                      ' */\n'
2361                      '\n')
2362
2363         self.c.write(self.docbook_gen.expand(
2364                 '/**\n'
2365                 ' * SECTION:%sObject\n'
2366                 ' * @title: %sObject\n'
2367                 ' * @short_description: Specialized GDBusObject types\n'
2368                 ' *\n'
2369                 ' * This section contains the #%sObject, #%sObjectProxy, and #%sObjectSkeleton types which make it easier to work with objects implementing generated types for D-Bus interfaces.\n'
2370                 ' */\n'
2371                 %(self.namespace, self.namespace, self.namespace, self.namespace, self.namespace), False))
2372         self.c.write('\n')
2373
2374         self.c.write(self.docbook_gen.expand(
2375                 '/**\n'
2376                 ' * %sObject:\n'
2377                 ' *\n'
2378                 ' * The #%sObject type is a specialized container of interfaces.\n'
2379                 ' */\n'
2380                 %(self.namespace, self.namespace), False))
2381         self.c.write('\n')
2382
2383         self.c.write(self.docbook_gen.expand(
2384                 '/**\n'
2385                 ' * %sObjectIface:\n'
2386                 ' * @parent_iface: The parent interface.\n'
2387                 ' *\n'
2388                 ' * Virtual table for the #%sObject interface.\n'
2389                 ' */\n'
2390                 %(self.namespace, self.namespace), False))
2391         self.c.write('\n')
2392
2393         self.c.write('static void\n'
2394                      '%sobject_default_init (%sObjectIface *iface)\n'
2395                      '{\n'
2396                      %(self.ns_lower, self.namespace));
2397         for i in self.ifaces:
2398             self.c.write(self.docbook_gen.expand(
2399                     '  /**\n'
2400                     '   * %sObject:%s:\n'
2401                     '   *\n'
2402                     '   * The #%s instance corresponding to the D-Bus interface #%s, if any.\n'
2403                     '   *\n'
2404                     '   * Connect to the #GObject::notify signal to get informed of property changes.\n'
2405                     %(self.namespace, i.name_hyphen, i.camel_name, i.name), False))
2406             self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 2)
2407             self.c.write('  g_object_interface_install_property (iface, g_param_spec_object ("%s", "%s", "%s", %sTYPE_%s, G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS));\n'
2408                          '\n'
2409                          %(i.name_hyphen, i.name_hyphen, i.name_hyphen, self.ns_upper, i.name_upper))
2410         self.c.write('}\n'
2411                      '\n')
2412
2413         self.c.write('typedef %sObjectIface %sObjectInterface;\n'%(self.namespace, self.namespace))
2414         self.c.write('G_DEFINE_INTERFACE_WITH_CODE (%sObject, %sobject, G_TYPE_OBJECT, g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_DBUS_OBJECT));\n'%(self.namespace, self.ns_lower))
2415         self.c.write('\n')
2416
2417         for i in self.ifaces:
2418             self.c.write(self.docbook_gen.expand(
2419                     '/**\n'
2420                     ' * %sobject_get_%s:\n'
2421                     ' * @object: A #%sObject.\n'
2422                     ' *\n'
2423                     ' * Gets the #%s instance for the D-Bus interface #%s on @object, if any.\n'
2424                     ' *\n'
2425                     ' * Returns: (transfer full): A #%s that must be freed with g_object_unref() or %%NULL if @object does not implement the interface.\n'
2426                     %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name, i.name, i.camel_name), False))
2427             self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
2428             self.c.write ('%s *%sobject_get_%s (%sObject *object)\n'
2429                           %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
2430             self.c.write('{\n'
2431                          '  GDBusInterface *ret;\n'
2432                          '  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
2433                          '  if (ret == NULL)\n'
2434                          '    return NULL;\n'
2435                          '  return %s%s (ret);\n'
2436                          '}\n'
2437                          '\n'
2438                          %(i.name, self.ns_upper, i.name_upper))
2439         self.c.write('\n')
2440         for i in self.ifaces:
2441             self.c.write(self.docbook_gen.expand(
2442                     '/**\n'
2443                     ' * %sobject_peek_%s: (skip)\n'
2444                     ' * @object: A #%sObject.\n'
2445                     ' *\n'
2446                     ' * Like %sobject_get_%s() but doesn\' increase the reference count on the returned object.\n'
2447                     ' *\n'
2448                     ' * <warning>It is not safe to use the returned object if you are on another thread than the one where the #GDBusObjectManagerClient or #GDBusObjectManagerServer for @object is running.</warning>\n'
2449                     ' *\n'
2450                     ' * Returns: (transfer none): A #%s or %%NULL if @object does not implement the interface. Do not free the returned object, it is owned by @object.\n'
2451                     %(self.ns_lower, i.name_upper.lower(), self.namespace, self.ns_lower, i.name_upper.lower(), i.camel_name), False))
2452             self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
2453             self.c.write ('%s *%sobject_peek_%s (%sObject *object)\n'
2454                           %(i.camel_name, self.ns_lower, i.name_upper.lower(), self.namespace))
2455             self.c.write('{\n'
2456                          '  GDBusInterface *ret;\n'
2457                          '  ret = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
2458                          '  if (ret == NULL)\n'
2459                          '    return NULL;\n'
2460                          '  g_object_unref (ret);\n'
2461                          '  return %s%s (ret);\n'
2462                          '}\n'
2463                          '\n'
2464                          %(i.name, self.ns_upper, i.name_upper))
2465         self.c.write('\n')
2466         # shared by ObjectProxy and ObjectSkeleton classes
2467         self.c.write('static void\n'
2468                      '%sobject_notify (GDBusObject *object, GDBusInterface *interface)\n'
2469                      '{\n'
2470                      '  g_object_notify (G_OBJECT (object), ((_ExtendedGDBusInterfaceInfo *) g_dbus_interface_get_info (interface))->hyphen_name);\n'
2471                      '}\n'
2472                      '\n'
2473                      %(self.ns_lower))
2474
2475         self.c.write(self.docbook_gen.expand(
2476                 '/**\n'
2477                 ' * %sObjectProxy:\n'
2478                 ' *\n'
2479                 ' * The #%sObjectProxy structure contains only private data and should only be accessed using the provided API.\n'
2480                 %(self.namespace, self.namespace), False))
2481         self.c.write(' */\n')
2482         self.c.write('\n')
2483         self.c.write(self.docbook_gen.expand(
2484                 '/**\n'
2485                 ' * %sObjectProxyClass:\n'
2486                 ' * @parent_class: The parent class.\n'
2487                 ' *\n'
2488                 ' * Class structure for #%sObjectProxy.\n'
2489                 %(self.namespace, self.namespace), False))
2490         self.c.write(' */\n')
2491         self.c.write('\n')
2492         # class boilerplate
2493         self.c.write('static void\n'
2494                      '%sobject_proxy__%sobject_iface_init (%sObjectIface *iface)\n'
2495                      '{\n'
2496                      '}\n'
2497                      '\n'
2498                      %(self.ns_lower, self.ns_lower, self.namespace))
2499         self.c.write('static void\n'
2500                      '%sobject_proxy__g_dbus_object_iface_init (GDBusObjectIface *iface)\n'
2501                      '{\n'
2502                      '  iface->interface_added = %sobject_notify;\n'
2503                      '  iface->interface_removed = %sobject_notify;\n'
2504                      '}\n'
2505                      '\n'
2506                      %(self.ns_lower, self.ns_lower, self.ns_lower))
2507         self.c.write('\n')
2508         self.c.write('G_DEFINE_TYPE_WITH_CODE (%sObjectProxy, %sobject_proxy, G_TYPE_DBUS_OBJECT_PROXY,\n'
2509                      '                         G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_proxy__%sobject_iface_init)\n'
2510                      '                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_proxy__g_dbus_object_iface_init));\n'
2511                      '\n'
2512                      %(self.namespace, self.ns_lower, self.ns_upper, self.ns_lower, self.ns_lower, self.ns_lower))
2513         # class boilerplate
2514         self.c.write('static void\n'
2515                      '%sobject_proxy_init (%sObjectProxy *object)\n'
2516                      '{\n'
2517                      '}\n'
2518                      '\n'%(self.ns_lower, self.namespace))
2519         self.c.write('static void\n'
2520                      '%sobject_proxy_set_property (GObject      *_object,\n'
2521                      '  guint         prop_id,\n'
2522                      '  const GValue *value,\n'
2523                      '  GParamSpec   *pspec)\n'
2524                      '{\n'
2525                      '  G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n'
2526                      %(self.ns_lower))
2527         self.c.write('}\n'
2528                      '\n'%())
2529         self.c.write('static void\n'
2530                      '%sobject_proxy_get_property (GObject      *_object,\n'
2531                      '  guint         prop_id,\n'
2532                      '  GValue       *value,\n'
2533                      '  GParamSpec   *pspec)\n'
2534                      '{\n'
2535                      '  %sObjectProxy *object = %sOBJECT_PROXY (_object);\n'
2536                      '  GDBusInterface *interface;\n'
2537                      '\n'
2538                      '  switch (prop_id)\n'
2539                      '    {\n'
2540                      %(self.ns_lower, self.namespace, self.ns_upper))
2541         n = 1
2542         for i in self.ifaces:
2543             self.c.write('    case %d:\n'
2544                          '      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
2545                          '      g_value_take_object (value, interface);\n'
2546                          '      break;\n'
2547                          '\n'
2548                          %(n, i.name))
2549             n += 1
2550         self.c.write('    default:\n'
2551                      '      G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n'
2552                      '      break;\n'
2553                      '  }\n'
2554                      '}\n'
2555                      '\n'%())
2556         self.c.write('static void\n'
2557                      '%sobject_proxy_class_init (%sObjectProxyClass *klass)\n'
2558                      '{\n'
2559                      '  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n'
2560                      '\n'
2561                      '  gobject_class->set_property = %sobject_proxy_set_property;\n'
2562                      '  gobject_class->get_property = %sobject_proxy_get_property;\n'
2563                      '\n'
2564                      %(self.ns_lower, self.namespace, self.ns_lower, self.ns_lower))
2565         n = 1
2566         for i in self.ifaces:
2567             self.c.write('  g_object_class_override_property (gobject_class, %d, "%s");'
2568                          '\n'
2569                          %(n, i.name_hyphen))
2570             n += 1
2571         self.c.write('}\n'
2572                      '\n')
2573
2574         self.c.write(self.docbook_gen.expand(
2575                 '/**\n'
2576                 ' * %sobject_proxy_new:\n'
2577                 ' * @connection: A #GDBusConnection.\n'
2578                 ' * @object_path: An object path.\n'
2579                 ' *\n'
2580                 ' * Creates a new proxy object.\n'
2581                 ' *\n'
2582                 ' * Returns: (transfer full): The proxy object.\n'
2583                 ' */\n'
2584                 %(self.ns_lower), False))
2585         self.c.write('%sObjectProxy *\n'
2586                      '%sobject_proxy_new (GDBusConnection *connection,\n'
2587                      '  const gchar *object_path)\n'
2588                      '{\n'
2589                      '  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);\n'
2590                      '  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n'
2591                      '  return %sOBJECT_PROXY (g_object_new (%sTYPE_OBJECT_PROXY, "connection", connection, "object-path", object_path, NULL));\n'
2592                      '}\n'
2593                      '\n'%(self.namespace, self.ns_lower, self.ns_upper, self.ns_upper))
2594
2595         self.c.write(self.docbook_gen.expand(
2596                 '/**\n'
2597                 ' * %sObjectSkeleton:\n'
2598                 ' *\n'
2599                 ' * The #%sObjectSkeleton structure contains only private data and should only be accessed using the provided API.\n'
2600                 %(self.namespace, self.namespace), False))
2601         self.c.write(' */\n')
2602         self.c.write('\n')
2603         self.c.write(self.docbook_gen.expand(
2604                 '/**\n'
2605                 ' * %sObjectSkeletonClass:\n'
2606                 ' * @parent_class: The parent class.\n'
2607                 ' *\n'
2608                 ' * Class structure for #%sObjectSkeleton.\n'
2609                 %(self.namespace, self.namespace), False))
2610         self.c.write(' */\n')
2611         self.c.write('\n')
2612         # class boilerplate
2613         self.c.write('static void\n'
2614                      '%sobject_skeleton__%sobject_iface_init (%sObjectIface *iface)\n'
2615                      '{\n'
2616                      '}\n'
2617                      '\n'
2618                      %(self.ns_lower, self.ns_lower, self.namespace))
2619         self.c.write('\n')
2620         self.c.write('static void\n'
2621                      '%sobject_skeleton__g_dbus_object_iface_init (GDBusObjectIface *iface)\n'
2622                      '{\n'
2623                      '  iface->interface_added = %sobject_notify;\n'
2624                      '  iface->interface_removed = %sobject_notify;\n'
2625                      '}\n'
2626                      '\n'
2627                      %(self.ns_lower, self.ns_lower, self.ns_lower))
2628         self.c.write('G_DEFINE_TYPE_WITH_CODE (%sObjectSkeleton, %sobject_skeleton, G_TYPE_DBUS_OBJECT_SKELETON,\n'
2629                      '                         G_IMPLEMENT_INTERFACE (%sTYPE_OBJECT, %sobject_skeleton__%sobject_iface_init)\n'
2630                      '                         G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, %sobject_skeleton__g_dbus_object_iface_init));\n'
2631                      '\n'
2632                      %(self.namespace, self.ns_lower, self.ns_upper, self.ns_lower, self.ns_lower, self.ns_lower))
2633         # class boilerplate
2634         self.c.write('static void\n'
2635                      '%sobject_skeleton_init (%sObjectSkeleton *object)\n'
2636                      '{\n'
2637                      '}\n'
2638                      '\n'%(self.ns_lower, self.namespace))
2639         self.c.write('static void\n'
2640                      '%sobject_skeleton_set_property (GObject      *_object,\n'
2641                      '  guint         prop_id,\n'
2642                      '  const GValue *value,\n'
2643                      '  GParamSpec   *pspec)\n'
2644                      '{\n'
2645                      '  %sObjectSkeleton *object = %sOBJECT_SKELETON (_object);\n'
2646                      '  GDBusInterfaceSkeleton *interface;\n'
2647                      '\n'
2648                      '  switch (prop_id)\n'
2649                      '    {\n'
2650                      %(self.ns_lower, self.namespace, self.ns_upper))
2651         n = 1
2652         for i in self.ifaces:
2653             self.c.write('    case %d:\n'
2654                          '      interface = g_value_get_object (value);\n'
2655                          '      if (interface != NULL)\n'
2656                          '        {\n'
2657                          '          g_warn_if_fail (%sIS_%s (interface));\n'
2658                          '          g_dbus_object_skeleton_add_interface (G_DBUS_OBJECT_SKELETON (object), interface);\n'
2659                          '        }\n'
2660                          '      else\n'
2661                          '        {\n'
2662                          '          g_dbus_object_skeleton_remove_interface_by_name (G_DBUS_OBJECT_SKELETON (object), "%s");\n'
2663                          '        }\n'
2664                          '      break;\n'
2665                          '\n'
2666                          %(n, self.ns_upper, i.name_upper, i.name))
2667             n += 1
2668         self.c.write('    default:\n'
2669                      '      G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n'
2670                      '      break;\n'
2671                      '  }\n'
2672                      '}\n'
2673                      '\n'%())
2674         self.c.write('static void\n'
2675                      '%sobject_skeleton_get_property (GObject      *_object,\n'
2676                      '  guint         prop_id,\n'
2677                      '  GValue       *value,\n'
2678                      '  GParamSpec   *pspec)\n'
2679                      '{\n'
2680                      '  %sObjectSkeleton *object = %sOBJECT_SKELETON (_object);\n'
2681                      '  GDBusInterface *interface;\n'
2682                      '\n'
2683                      '  switch (prop_id)\n'
2684                      '    {\n'
2685                      %(self.ns_lower, self.namespace, self.ns_upper))
2686         n = 1
2687         for i in self.ifaces:
2688             self.c.write('    case %d:\n'
2689                          '      interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object), "%s");\n'
2690                          '      g_value_take_object (value, interface);\n'
2691                          '      break;\n'
2692                          '\n'
2693                          %(n, i.name))
2694             n += 1
2695         self.c.write('    default:\n'
2696                      '      G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);\n'
2697                      '      break;\n'
2698                      '  }\n'
2699                      '}\n'
2700                      '\n'%())
2701         self.c.write('static void\n'
2702                      '%sobject_skeleton_class_init (%sObjectSkeletonClass *klass)\n'
2703                      '{\n'
2704                      '  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);\n'
2705                      '\n'
2706                      '  gobject_class->set_property = %sobject_skeleton_set_property;\n'
2707                      '  gobject_class->get_property = %sobject_skeleton_get_property;\n'
2708                      '\n'
2709                      %(self.ns_lower, self.namespace, self.ns_lower, self.ns_lower))
2710         n = 1
2711         for i in self.ifaces:
2712             self.c.write('  g_object_class_override_property (gobject_class, %d, "%s");'
2713                          '\n'
2714                          %(n, i.name_hyphen))
2715             n += 1
2716         self.c.write('}\n'
2717                      '\n')
2718         self.c.write(self.docbook_gen.expand(
2719                 '/**\n'
2720                 ' * %sobject_skeleton_new:\n'
2721                 ' * @object_path: An object path.\n'
2722                 ' *\n'
2723                 ' * Creates a new skeleton object.\n'
2724                 ' *\n'
2725                 ' * Returns: (transfer full): The skeleton object.\n'
2726                 ' */\n'
2727                 %(self.ns_lower), False))
2728         self.c.write('%sObjectSkeleton *\n'
2729                      '%sobject_skeleton_new (const gchar *object_path)\n'
2730                      '{\n'
2731                      '  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);\n'
2732                      '  return %sOBJECT_SKELETON (g_object_new (%sTYPE_OBJECT_SKELETON, "object-path", object_path, NULL));\n'
2733                      '}\n'
2734                      '\n'%(self.namespace, self.ns_lower, self.ns_upper, self.ns_upper))
2735         for i in self.ifaces:
2736             self.c.write(self.docbook_gen.expand(
2737                     '/**\n'
2738                     ' * %sobject_skeleton_set_%s:\n'
2739                     ' * @object: A #%sObjectSkeleton.\n'
2740                     ' * @interface_: (allow-none): A #%s or %%NULL to clear the interface.\n'
2741                     ' *\n'
2742                     ' * Sets the #%s instance for the D-Bus interface #%s on @object.\n'
2743                     %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name, i.camel_name, i.name), False))
2744             self.write_gtkdoc_deprecated_and_since_and_close(i, self.c, 0)
2745             self.c.write ('void %sobject_skeleton_set_%s (%sObjectSkeleton *object, %s *interface_)\n'
2746                           %(self.ns_lower, i.name_upper.lower(), self.namespace, i.camel_name))
2747             self.c.write('{\n'
2748                          '  g_object_set (G_OBJECT (object), "%s", interface_, NULL);\n'
2749                          '}\n'
2750                          '\n'
2751                          %(i.name_hyphen))
2752         self.c.write('\n')
2753
2754
2755     def generate_object_manager_client(self):
2756         self.c.write('/* ------------------------------------------------------------------------\n'
2757                      ' * Code for ObjectManager client\n'
2758                      ' * ------------------------------------------------------------------------\n'
2759                      ' */\n'
2760                      '\n')
2761
2762         self.c.write(self.docbook_gen.expand(
2763                 '/**\n'
2764                 ' * SECTION:%sObjectManagerClient\n'
2765                 ' * @title: %sObjectManagerClient\n'
2766                 ' * @short_description: Generated GDBusObjectManagerClient type\n'
2767                 ' *\n'
2768                 ' * This section contains a #GDBusObjectManagerClient that uses %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc.\n'
2769                 ' */\n'
2770                 %(self.namespace, self.namespace, self.ns_lower), False))
2771         self.c.write('\n')
2772
2773         self.c.write(self.docbook_gen.expand(
2774                 '/**\n'
2775                 ' * %sObjectManagerClient:\n'
2776                 ' *\n'
2777                 ' * The #%sObjectManagerClient structure contains only private data and should only be accessed using the provided API.\n'
2778                 %(self.namespace, self.namespace), False))
2779         self.c.write(' */\n')
2780         self.c.write('\n')
2781
2782         self.c.write(self.docbook_gen.expand(
2783                 '/**\n'
2784                 ' * %sObjectManagerClientClass:\n'
2785                 ' * @parent_class: The parent class.\n'
2786                 ' *\n'
2787                 ' * Class structure for #%sObjectManagerClient.\n'
2788                 %(self.namespace, self.namespace), False))
2789         self.c.write(' */\n')
2790         self.c.write('\n')
2791
2792         # class boilerplate
2793         self.c.write('G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT);\n'
2794                      '\n'
2795                      %(self.namespace, self.ns_lower))
2796
2797         # class boilerplate
2798         self.c.write('static void\n'
2799                      '%sobject_manager_client_init (%sObjectManagerClient *manager)\n'
2800                      '{\n'
2801                      '}\n'
2802                      '\n'%(self.ns_lower, self.namespace))
2803         self.c.write('static void\n'
2804                      '%sobject_manager_client_class_init (%sObjectManagerClientClass *klass)\n'
2805                      '{\n'
2806                      '}\n'
2807                      '\n'%(self.ns_lower, self.namespace))
2808
2809         self.c.write(self.docbook_gen.expand(
2810                 '/**\n'
2811                 ' * %sobject_manager_client_get_proxy_type:\n'
2812                 ' * @manager: A #GDBusObjectManagerClient.\n'
2813                 ' * @object_path: The object path of the remote object (unused).\n'
2814                 ' * @interface_name: (allow-none): Interface name of the remote object or %%NULL to get the object proxy #GType.\n'
2815                 ' * @user_data: User data (unused).\n'
2816                 ' *\n'
2817                 ' * A #GDBusProxyTypeFunc that maps @interface_name to the generated #GDBusObjectProxy<!-- -->- and #GDBusProxy<!-- -->-derived types.\n'
2818                 ' *\n'
2819                 ' * Returns: A #GDBusProxy<!-- -->-derived #GType if @interface_name is not %%NULL, otherwise the #GType for #%sObjectProxy.\n'
2820                 %(self.ns_lower, self.namespace), False))
2821         self.c.write(' */\n')
2822         self.c.write('GType\n'
2823                      '%sobject_manager_client_get_proxy_type (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data)\n'
2824                      '{\n'
2825                      %(self.ns_lower))
2826         self.c.write('  static gsize once_init_value = 0;\n'
2827                      '  static GHashTable *lookup_hash;\n'
2828                      '  GType ret;\n'
2829                      '\n'
2830                      '  if (interface_name == NULL)\n'
2831                      '    return %sTYPE_OBJECT_PROXY;\n'
2832                      '  if (g_once_init_enter (&once_init_value))\n'
2833                      '    {\n'
2834                      '      lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n'
2835                      %(self.ns_upper))
2836         for i in self.ifaces:
2837             self.c.write('      g_hash_table_insert (lookup_hash, "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n'
2838                          %(i.name, i.ns_upper, i.name_upper))
2839         self.c.write('      g_once_init_leave (&once_init_value, 1);\n'
2840                      '    }\n')
2841         self.c.write('  ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n'
2842                      '  if (ret == (GType) 0)\n'
2843                      '    ret = G_TYPE_DBUS_PROXY;\n')
2844         self.c.write('  return ret;\n'
2845                      '}\n'
2846                      '\n')
2847
2848         # constructors
2849         self.c.write(self.docbook_gen.expand(
2850                 '/**\n'
2851                 ' * %sobject_manager_client_new:\n'
2852                 ' * @connection: A #GDBusConnection.\n'
2853                 ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
2854                 ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
2855                 ' * @object_path: An object path.\n'
2856                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
2857                 ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
2858                 ' * @user_data: User data to pass to @callback.\n'
2859                 ' *\n'
2860                 ' * Asynchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new() for more details.\n'
2861                 ' *\n'
2862                 ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
2863                 ' * You can then call %sobject_manager_client_new_finish() to get the result of the operation.\n'
2864                 ' *\n'
2865                 ' * See %sobject_manager_client_new_sync() for the synchronous, blocking version of this constructor.\n'
2866                 %(self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), False))
2867         self.c.write(' */\n')
2868         self.c.write('void\n'
2869                      '%sobject_manager_client_new (\n'
2870                      '    GDBusConnection        *connection,\n'
2871                      '    GDBusObjectManagerClientFlags  flags,\n'
2872                      '    const gchar            *name,\n'
2873                      '    const gchar            *object_path,\n'
2874                      '    GCancellable           *cancellable,\n'
2875                      '    GAsyncReadyCallback     callback,\n'
2876                      '    gpointer                user_data)\n'
2877                      '{\n'
2878                      '  g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
2879                      '}\n'
2880                      '\n'
2881                      %(self.ns_lower, self.ns_upper, self.ns_lower))
2882         self.c.write('/**\n'
2883                      ' * %sobject_manager_client_new_finish:\n'
2884                      ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new().\n'
2885                      ' * @error: Return location for error or %%NULL\n'
2886                      ' *\n'
2887                      ' * Finishes an operation started with %sobject_manager_client_new().\n'
2888                      ' *\n'
2889                      ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
2890                      %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace))
2891         self.c.write(' */\n')
2892         self.c.write('GDBusObjectManager *\n'
2893                      '%sobject_manager_client_new_finish (\n'
2894                      '    GAsyncResult        *res,\n'
2895                      '    GError             **error)\n'
2896                      '{\n'
2897                      '  GObject *ret;\n'
2898                      '  GObject *source_object;\n'
2899                      '  source_object = g_async_result_get_source_object (res);\n'
2900                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
2901                      '  g_object_unref (source_object);\n'
2902                      '  if (ret != NULL)\n'
2903                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
2904                      '  else\n'
2905                      '    return NULL;\n'
2906                      '}\n'
2907                      '\n'
2908                      %(self.ns_lower))
2909         self.c.write(self.docbook_gen.expand(
2910                 '/**\n'
2911                 ' * %sobject_manager_client_new_sync:\n'
2912                 ' * @connection: A #GDBusConnection.\n'
2913                 ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
2914                 ' * @name: (allow-none): A bus name (well-known or unique) or %%NULL if @connection is not a message bus connection.\n'
2915                 ' * @object_path: An object path.\n'
2916                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
2917                 ' * @error: Return location for error or %%NULL\n'
2918                 ' *\n'
2919                 ' * Synchronously creates #GDBusObjectManagerClient using %sobject_manager_client_get_proxy_type() as the #GDBusProxyTypeFunc. See g_dbus_object_manager_client_new_sync() for more details.\n'
2920                 ' *\n'
2921                 ' * The calling thread is blocked until a reply is received.\n'
2922                 ' *\n'
2923                 ' * See %sobject_manager_client_new() for the asynchronous version of this constructor.\n'
2924                 ' *\n'
2925                 ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
2926                 %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), False))
2927         self.c.write(' */\n')
2928         self.c.write('GDBusObjectManager *\n'
2929                      '%sobject_manager_client_new_sync (\n'
2930                      '    GDBusConnection        *connection,\n'
2931                      '    GDBusObjectManagerClientFlags  flags,\n'
2932                      '    const gchar            *name,\n'
2933                      '    const gchar            *object_path,\n'
2934                      '    GCancellable           *cancellable,\n'
2935                      '    GError                **error)\n'
2936                      '{\n'
2937                      '  GInitable *ret;\n'
2938                      '  ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "connection", connection, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
2939                      '  if (ret != NULL)\n'
2940                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
2941                      '  else\n'
2942                      '    return NULL;\n'
2943                      '}\n'
2944                      '\n'
2945                      %(self.ns_lower, self.ns_upper, self.ns_lower))
2946         self.c.write('\n')
2947         self.c.write(self.docbook_gen.expand(
2948                 '/**\n'
2949                 ' * %sobject_manager_client_new_for_bus:\n'
2950                 ' * @bus_type: A #GBusType.\n'
2951                 ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
2952                 ' * @name: A bus name (well-known or unique).\n'
2953                 ' * @object_path: An object path.\n'
2954                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
2955                 ' * @callback: A #GAsyncReadyCallback to call when the request is satisfied.\n'
2956                 ' * @user_data: User data to pass to @callback.\n'
2957                 ' *\n'
2958                 ' * Like %sobject_manager_client_new() but takes a #GBusType instead of a #GDBusConnection.\n'
2959                 ' *\n'
2960                 ' * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.\n'
2961                 ' * You can then call %sobject_manager_client_new_for_bus_finish() to get the result of the operation.\n'
2962                 ' *\n'
2963                 ' * See %sobject_manager_client_new_for_bus_sync() for the synchronous, blocking version of this constructor.\n'
2964                 %(self.ns_lower, self.ns_lower, self.ns_lower, self.ns_lower), False))
2965         self.c.write(' */\n')
2966         self.c.write('void\n'
2967                      '%sobject_manager_client_new_for_bus (\n'
2968                      '    GBusType                bus_type,\n'
2969                      '    GDBusObjectManagerClientFlags  flags,\n'
2970                      '    const gchar            *name,\n'
2971                      '    const gchar            *object_path,\n'
2972                      '    GCancellable           *cancellable,\n'
2973                      '    GAsyncReadyCallback     callback,\n'
2974                      '    gpointer                user_data)\n'
2975                      '{\n'
2976                      '  g_async_initable_new_async (%sTYPE_OBJECT_MANAGER_CLIENT, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
2977                      '}\n'
2978                      '\n'
2979                      %(self.ns_lower, self.ns_upper, self.ns_lower))
2980         self.c.write('/**\n'
2981                      ' * %sobject_manager_client_new_for_bus_finish:\n'
2982                      ' * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to %sobject_manager_client_new_for_bus().\n'
2983                      ' * @error: Return location for error or %%NULL\n'
2984                      ' *\n'
2985                      ' * Finishes an operation started with %sobject_manager_client_new_for_bus().\n'
2986                      ' *\n'
2987                      ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
2988                      %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace))
2989         self.c.write(' */\n')
2990         self.c.write('GDBusObjectManager *\n'
2991                      '%sobject_manager_client_new_for_bus_finish (\n'
2992                      '    GAsyncResult        *res,\n'
2993                      '    GError             **error)\n'
2994                      '{\n'
2995                      '  GObject *ret;\n'
2996                      '  GObject *source_object;\n'
2997                      '  source_object = g_async_result_get_source_object (res);\n'
2998                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
2999                      '  g_object_unref (source_object);\n'
3000                      '  if (ret != NULL)\n'
3001                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
3002                      '  else\n'
3003                      '    return NULL;\n'
3004                      '}\n'
3005                      '\n'
3006                      %(self.ns_lower))
3007         self.c.write(self.docbook_gen.expand(
3008                 '/**\n'
3009                 ' * %sobject_manager_client_new_for_bus_sync:\n'
3010                 ' * @bus_type: A #GBusType.\n'
3011                 ' * @flags: Flags from the #GDBusObjectManagerClientFlags enumeration.\n'
3012                 ' * @name: A bus name (well-known or unique).\n'
3013                 ' * @object_path: An object path.\n'
3014                 ' * @cancellable: (allow-none): A #GCancellable or %%NULL.\n'
3015                 ' * @error: Return location for error or %%NULL\n'
3016                 ' *\n'
3017                 ' * Like %sobject_manager_client_new_sync() but takes a #GBusType instead of a #GDBusConnection.\n'
3018                 ' *\n'
3019                 ' * The calling thread is blocked until a reply is received.\n'
3020                 ' *\n'
3021                 ' * See %sobject_manager_client_new_for_bus() for the asynchronous version of this constructor.\n'
3022                 ' *\n'
3023                 ' * Returns: (transfer full) (type %sObjectManagerClient): The constructed object manager client or %%NULL if @error is set.\n'
3024                 %(self.ns_lower, self.ns_lower, self.ns_lower, self.namespace), False))
3025         self.c.write(' */\n')
3026         self.c.write('GDBusObjectManager *\n'
3027                      '%sobject_manager_client_new_for_bus_sync (\n'
3028                      '    GBusType                bus_type,\n'
3029                      '    GDBusObjectManagerClientFlags  flags,\n'
3030                      '    const gchar            *name,\n'
3031                      '    const gchar            *object_path,\n'
3032                      '    GCancellable           *cancellable,\n'
3033                      '    GError                **error)\n'
3034                      '{\n'
3035                      '  GInitable *ret;\n'
3036                      '  ret = g_initable_new (%sTYPE_OBJECT_MANAGER_CLIENT, cancellable, error, "flags", flags, "name", name, "bus-type", bus_type, "object-path", object_path, "get-proxy-type-func", %sobject_manager_client_get_proxy_type, NULL);\n'
3037                      '  if (ret != NULL)\n'
3038                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
3039                      '  else\n'
3040                      '    return NULL;\n'
3041                      '}\n'
3042                      '\n'
3043                      %(self.ns_lower, self.ns_upper, self.ns_lower))
3044         self.c.write('\n')
3045
3046     # ---------------------------------------------------------------------------------------------------
3047
3048     def write_gtkdoc_deprecated_and_since_and_close(self, obj, f, indent):
3049         if len(obj.since) > 0:
3050             f.write('%*s *\n'
3051                     '%*s * Since: %s\n'
3052                     %(indent, '', indent, '', obj.since))
3053         if obj.deprecated:
3054             if isinstance(obj, dbustypes.Interface):
3055                 thing = 'The D-Bus interface'
3056             elif isinstance(obj, dbustypes.Method):
3057                 thing = 'The D-Bus method'
3058             elif isinstance(obj, dbustypes.Signal):
3059                 thing = 'The D-Bus signal'
3060             elif isinstance(obj, dbustypes.Property):
3061                 thing = 'The D-Bus property'
3062             else:
3063                 raise RuntimeError('Cannot handle object ', obj)
3064             f.write(self.docbook_gen.expand(
3065                     '%*s *\n'
3066                     '%*s * Deprecated: %s has been deprecated.\n'
3067                     %(indent, '', indent, '', thing), False))
3068         f.write('%*s */\n'%(indent, ''))
3069
3070     # ---------------------------------------------------------------------------------------------------
3071
3072     def generate_interface_intro(self, i):
3073         self.c.write('/* ------------------------------------------------------------------------\n'
3074                      ' * Code for interface %s\n'
3075                      ' * ------------------------------------------------------------------------\n'
3076                      ' */\n'
3077                      '\n'%(i.name))
3078
3079         self.c.write(self.docbook_gen.expand(
3080                 '/**\n'
3081                 ' * SECTION:%s\n'
3082                 ' * @title: %s\n'
3083                 ' * @short_description: Generated C code for the %s D-Bus interface\n'
3084                 ' *\n'
3085                 ' * This section contains code for working with the #%s D-Bus interface in C.\n'
3086                 ' */\n'
3087                 %(i.camel_name, i.camel_name, i.name, i.name), False))
3088         self.c.write('\n')
3089
3090     def generate(self):
3091         self.generate_intro()
3092         self.declare_types()
3093         for i in self.ifaces:
3094             self.generate_interface_intro(i)
3095             self.generate_introspection_for_interface(i)
3096             self.generate_interface(i)
3097             self.generate_property_accessors(i)
3098             self.generate_signal_emitters(i)
3099             self.generate_method_calls(i)
3100             self.generate_method_completers(i)
3101             self.generate_proxy(i)
3102             self.generate_skeleton(i)
3103         if self.generate_objmanager:
3104             self.generate_object()
3105             self.generate_object_manager_client()
3106         self.generate_outro()