974e6e99800d363adecdff0c8ac8972ff4088abb
[platform/upstream/glib.git] / gio / gdbus-codegen / codegen.py
1 # -*- Mode: Python -*-
2
3 import sys
4 import argparse
5
6 import config
7 import utils
8 import dbustypes
9
10 # ----------------------------------------------------------------------------------------------------
11
12 class CodeGenerator:
13     def __init__(self, ifaces, namespace, interface_prefix, h, c):
14         self.ifaces = ifaces
15         self.h = h
16         self.c = c
17         self.namespace = namespace
18         if len(namespace) > 1:
19             self.ns_upper = utils.camel_case_to_uscore(namespace).upper() + '_'
20             self.ns_lower = utils.camel_case_to_uscore(namespace).lower() + '_'
21         else:
22             self.ns_upper = ''
23             self.ns_lower = ''
24         self.interface_prefix = interface_prefix
25         self.header_guard = self.h.name.upper().replace('.', '_').replace('-', '_')
26
27     # ----------------------------------------------------------------------------------------------------
28
29     def generate_intro(self):
30         self.c.write('/*\n'
31                      ' * Generated by gdbus-codegen.py %s. DO NOT EDIT.\n'
32                      ' */\n'
33                      '\n'
34                      %(config.VERSION))
35         self.c.write('#ifdef HAVE_CONFIG_H\n'
36                      '#  include "config.h"\n'
37                      '#endif\n'
38                      '\n'
39                      '#include "%s"\n'
40                      '\n'%(self.h.name))
41
42         self.c.write('typedef struct\n'
43                      '{\n'
44                      '  GDBusArgInfo parent_struct;\n'
45                      '  gboolean use_gvariant;\n'
46                      '} _ExtendedGDBusArgInfo;\n'
47                      '\n')
48
49         self.c.write('typedef struct\n'
50                      '{\n'
51                      '  GDBusMethodInfo parent_struct;\n'
52                      '  const gchar *signal_name;\n'
53                      '} _ExtendedGDBusMethodInfo;\n'
54                      '\n')
55
56         self.c.write('typedef struct\n'
57                      '{\n'
58                      '  GDBusSignalInfo parent_struct;\n'
59                      '  const gchar *signal_name;\n'
60                      '} _ExtendedGDBusSignalInfo;\n'
61                      '\n')
62
63         self.c.write('typedef struct\n'
64                      '{\n'
65                      '  GDBusPropertyInfo parent_struct;\n'
66                      '  const gchar *hyphen_name;\n'
67                      '  gboolean use_gvariant;\n'
68                      '} _ExtendedGDBusPropertyInfo;\n'
69                      '\n')
70
71         self.c.write('typedef struct\n'
72                      '{\n'
73                      '  const _ExtendedGDBusPropertyInfo *info;\n'
74                      '  GParamSpec *pspec;\n'
75                      '  GValue value;\n'
76                      '} ChangedProperty;\n'
77                      '\n'
78                      'static void\n'
79                      '_changed_property_free (ChangedProperty *data)\n'
80                      '{\n'
81                      '  g_value_unset (&data->value);\n'
82                      '  g_free (data);\n'
83                      '}\n'
84                      '\n')
85
86         self.c.write('static gboolean\n'
87                      '_g_strv_equal0 (gchar **a, gchar **b)\n'
88                      '{\n'
89                      '  gboolean ret = FALSE;\n'
90                      '  guint n;\n'
91                      '  if (a == NULL && b == NULL)\n'
92                      '    {\n'
93                      '      ret = TRUE;\n'
94                      '      goto out;\n'
95                      '    }\n'
96                      '  if (a == NULL || b == NULL)\n'
97                      '    goto out;\n'
98                      '  if (g_strv_length (a) != g_strv_length (b))\n'
99                      '    goto out;\n'
100                      '  for (n = 0; a[n] != NULL; n++)\n'
101                      '    if (g_strcmp0 (a[n], b[n]) != 0)\n'
102                      '      goto out;\n'
103                      '  ret = TRUE;\n'
104                      'out:\n'
105                      '  return ret;\n'
106                      '}\n'
107                      '\n')
108
109         self.c.write('static gboolean\n'
110                      '_g_variant_equal0 (GVariant *a, GVariant *b)\n'
111                      '{\n'
112                      '  gboolean ret = FALSE;\n'
113                      '  if (a == NULL && b == NULL)\n'
114                      '    goto out;\n'
115                      '  if (a == NULL || b == NULL)\n'
116                      '    goto out;\n'
117                      '  ret = g_variant_equal (a, b);\n'
118                      'out:\n'
119                      '  return ret;\n'
120                      '}\n'
121                      '\n')
122
123         # simplified - only supports the types we use
124         self.c.write('static gboolean\n'
125                      '_g_value_equal (const GValue *a, const GValue *b)\n'
126                      '{\n'
127                      '  gboolean ret = FALSE;\n'
128                      '  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n'
129                      '  switch (G_VALUE_TYPE (a))\n'
130                      '    {\n'
131                      '      case G_TYPE_BOOLEAN:\n'
132                      '        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n'
133                      '        break;\n'
134                      '      case G_TYPE_UCHAR:\n'
135                      '        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n'
136                      '        break;\n'
137                      '      case G_TYPE_INT:\n'
138                      '        ret = (g_value_get_int (a) == g_value_get_int (b));\n'
139                      '        break;\n'
140                      '      case G_TYPE_UINT:\n'
141                      '        ret = (g_value_get_uint (a) == g_value_get_uint (b));\n'
142                      '        break;\n'
143                      '      case G_TYPE_INT64:\n'
144                      '        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n'
145                      '        break;\n'
146                      '      case G_TYPE_UINT64:\n'
147                      '        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n'
148                      '        break;\n'
149                      '      case G_TYPE_DOUBLE:\n'
150                      '        ret = (g_value_get_double (a) == g_value_get_double (b));\n'
151                      '        break;\n'
152                      '      case G_TYPE_STRING:\n'
153                      '        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n'
154                      '        break;\n'
155                      '      case G_TYPE_VARIANT:\n'
156                      '        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n'
157                      '        break;\n'
158                      '      default:\n'
159                      '        if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n'
160                      '          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n'
161                      '        else\n'
162                      '          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
163                      '        break;\n'
164                      '    }\n'
165                      '  return ret;\n'
166                      '}\n'
167                      '\n')
168
169         self.h.write('/*\n'
170                      ' * Generated by gdbus-codegen.py %s. DO NOT EDIT.\n'
171                      ' */\n'
172                      '\n'
173                      '#ifndef __%s__\n'
174                      '#define __%s__\n'
175                      '\n'%(config.VERSION, self.header_guard, self.header_guard))
176         self.h.write('#include <gio/gio.h>\n'
177                      '\n'
178                      'G_BEGIN_DECLS\n'
179                      '\n')
180
181     # ----------------------------------------------------------------------------------------------------
182
183     def declare_types(self):
184         for i in self.ifaces:
185             self.h.write('\n')
186             self.h.write('/* ------------------------------------------------------------------------ */\n')
187             self.h.write('/* Declarations for %s */\n'%i.name)
188             self.h.write('\n')
189
190             # First the GInterface
191             self.h.write('#define %sTYPE_%s (%s_get_gtype ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
192             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))
193             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))
194             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))
195             self.h.write('\n')
196             self.h.write('struct _%s;\n'%(i.camel_name))
197             self.h.write('typedef struct _%s %s;\n'%(i.camel_name, i.camel_name))
198             self.h.write('typedef struct _%sIface %sIface;\n'%(i.camel_name, i.camel_name))
199             self.h.write('\n')
200             self.h.write('struct _%sIface\n'%(i.camel_name))
201             self.h.write('{\n')
202             self.h.write('  GTypeInterface parent_iface;\n')
203             if len(i.methods) > 0:
204                 self.h.write('\n')
205                 self.h.write('  /* GObject signal class handlers for incoming D-Bus method calls: */\n')
206                 for m in i.methods:
207                     self.h.write('  gboolean (*handle_%s) (\n'
208                                  '    %s *object,\n'
209                                  '    GDBusMethodInvocation *invocation'%(m.name_lower, i.camel_name))
210                     for a in m.in_args:
211                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
212                     self.h.write(');\n')
213                     self.h.write('\n')
214             if len(i.signals) > 0:
215                 self.h.write('\n')
216                 self.h.write('  /* GObject signal class handlers for received D-Bus signals: */\n')
217                 for s in i.signals:
218                     self.h.write('  void (*%s) (\n'
219                                  '    %s *object'%(s.name_lower, i.camel_name))
220                     for a in s.args:
221                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
222                     self.h.write(');\n')
223                     self.h.write('\n')
224             self.h.write('};\n')
225             self.h.write('\n')
226             self.h.write('GType %s_get_gtype (void) G_GNUC_CONST;\n'%(i.name_lower))
227             self.h.write('\n')
228             self.h.write('GDBusInterfaceInfo *%s_interface_info (void);\n'%(i.name_lower))
229             if len(i.properties) > 0:
230                 self.h.write('guint %s_override_properties (GObjectClass *klass, guint property_id_begin);\n'%(i.name_lower))
231             self.h.write('\n')
232
233             # Then method call completion functions
234             if len(i.methods) > 0:
235                 self.h.write('\n')
236                 self.h.write('/* D-Bus method call completion functions: */\n')
237                 for m in i.methods:
238                     self.h.write('void %s_complete_%s (\n'
239                                  '    %s *object,\n'
240                                  '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
241                     for a in m.out_args:
242                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
243                     self.h.write(');\n')
244                     self.h.write('\n')
245                 self.h.write('\n')
246
247             # Then signal emission functions
248             if len(i.signals) > 0:
249                 self.h.write('\n')
250                 self.h.write('/* D-Bus signal emissions functions: */\n')
251                 for s in i.signals:
252                     self.h.write('void %s_emit_%s (\n'
253                                  '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
254                     for a in s.args:
255                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
256                     self.h.write(');\n')
257                     self.h.write('\n')
258                 self.h.write('\n')
259
260             # Then method call declarations
261             if len(i.methods) > 0:
262                 self.h.write('\n')
263                 self.h.write('/* D-Bus method calls: */\n')
264                 for m in i.methods:
265                     # async begin
266                     self.h.write('void %s_call_%s (\n'
267                                  '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
268                     for a in m.in_args:
269                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
270                     self.h.write(',\n'
271                                  '    GCancellable *cancellable,\n'
272                                  '    GAsyncReadyCallback callback,\n'
273                                  '    gpointer user_data);\n')
274                     self.h.write('\n')
275                     # async finish
276                     self.h.write('gboolean %s_call_%s_finish (\n'
277                                  '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
278                     for a in m.out_args:
279                         self.h.write(',\n    %sout_%s'%(a.ctype_out, a.name))
280                     self.h.write(',\n'
281                                  '    GAsyncResult *res,\n'
282                                  '    GError **error);\n')
283                     self.h.write('\n')
284                     # sync
285                     self.h.write('gboolean %s_call_%s_sync (\n'
286                                  '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
287                     for a in m.in_args:
288                         self.h.write(',\n    %s%s'%(a.ctype_in, a.name))
289                     for a in m.out_args:
290                         self.h.write(',\n    %sout_%s'%(a.ctype_out, a.name))
291                     self.h.write(',\n'
292                                  '    GCancellable *cancellable,\n'
293                                  '    GError **error);\n')
294                     self.h.write('\n')
295                 self.h.write('\n')
296
297             # Then the property accessor declarations
298             if len(i.properties) > 0:
299                 self.h.write('\n')
300                 self.h.write('/* D-Bus property accessors: */\n')
301                 for p in i.properties:
302                     # getter
303                     self.h.write('%s%s_get_%s (%s *object);\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name))
304                     # setter
305                     self.h.write('void %s_set_%s (%s *object, %svalue);\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
306                     self.h.write('\n')
307
308             # Then the proxy
309             self.h.write('\n')
310             self.h.write('/* ---- */\n')
311             self.h.write('\n')
312             self.h.write('#define %sTYPE_%s_PROXY (%s_proxy_get_gtype ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
313             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))
314             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))
315             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))
316             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))
317             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))
318             self.h.write('\n')
319             self.h.write('typedef struct _%sProxy %sProxy;\n'%(i.camel_name, i.camel_name))
320             self.h.write('typedef struct _%sProxyClass %sProxyClass;\n'%(i.camel_name, i.camel_name))
321             self.h.write('typedef struct _%sProxyPrivate %sProxyPrivate;\n'%(i.camel_name, i.camel_name))
322             self.h.write('\n')
323             self.h.write('struct _%sProxy\n'%(i.camel_name))
324             self.h.write('{\n')
325             self.h.write('  GDBusProxy parent_instance;\n')
326             self.h.write('  %sProxyPrivate *priv;\n'%(i.camel_name))
327             self.h.write('};\n')
328             self.h.write('\n')
329             self.h.write('struct _%sProxyClass\n'%(i.camel_name))
330             self.h.write('{\n')
331             self.h.write('  GDBusProxyClass parent_class;\n')
332             self.h.write('};\n')
333             self.h.write('\n')
334             self.h.write('GType %s_proxy_get_gtype (void) G_GNUC_CONST;\n'%(i.name_lower))
335
336             self.h.write('\n')
337             self.h.write('void %s_proxy_new (\n'
338                          '    GDBusConnection     *connection,\n'
339                          '    GDBusProxyFlags      flags,\n'
340                          '    const gchar         *name,\n'
341                          '    const gchar         *object_path,\n'
342                          '    GCancellable        *cancellable,\n'
343                          '    GAsyncReadyCallback  callback,\n'
344                          '    gpointer             user_data);\n'
345                          %(i.name_lower))
346             self.h.write('%s *%s_proxy_new_finish (\n'
347                          '    GAsyncResult        *res,\n'
348                          '    GError             **error);\n'
349                          %(i.camel_name, i.name_lower))
350             self.h.write('%s *%s_proxy_new_sync (\n'
351                          '    GDBusConnection     *connection,\n'
352                          '    GDBusProxyFlags      flags,\n'
353                          '    const gchar         *name,\n'
354                          '    const gchar         *object_path,\n'
355                          '    GCancellable        *cancellable,\n'
356                          '    GError             **error);\n'
357                          %(i.camel_name, i.name_lower))
358             self.h.write('\n')
359             self.h.write('void %s_proxy_new_for_bus (\n'
360                          '    GBusType             bus_type,\n'
361                          '    GDBusProxyFlags      flags,\n'
362                          '    const gchar         *name,\n'
363                          '    const gchar         *object_path,\n'
364                          '    GCancellable        *cancellable,\n'
365                          '    GAsyncReadyCallback  callback,\n'
366                          '    gpointer             user_data);\n'
367                          %(i.name_lower))
368             self.h.write('%s *%s_proxy_new_for_bus_finish (\n'
369                          '    GAsyncResult        *res,\n'
370                          '    GError             **error);\n'
371                          %(i.camel_name, i.name_lower))
372             self.h.write('%s *%s_proxy_new_for_bus_sync (\n'
373                          '    GBusType             bus_type,\n'
374                          '    GDBusProxyFlags      flags,\n'
375                          '    const gchar         *name,\n'
376                          '    const gchar         *object_path,\n'
377                          '    GCancellable        *cancellable,\n'
378                          '    GError             **error);\n'
379                          %(i.camel_name, i.name_lower))
380             self.h.write('\n')
381
382             # Interface proxy accessors
383             self.h.write('#define %sGET_%s(object) (g_dbus_object_lookup_with_typecheck (G_DBUS_OBJECT (object), "%s", %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
384             self.h.write('#define %sPEEK_%s(object) (g_dbus_object_peek_with_typecheck (G_DBUS_OBJECT (object), "%s", %sTYPE_%s))\n'%(i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
385             self.h.write('\n')
386
387             # Then the stub
388             self.h.write('\n')
389             self.h.write('/* ---- */\n')
390             self.h.write('\n')
391             self.h.write('#define %sTYPE_%s_STUB (%s_stub_get_gtype ())\n'%(i.ns_upper, i.name_upper, i.name_lower))
392             self.h.write('#define %s%s_STUB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), %sTYPE_%s_STUB, %sStub))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
393             self.h.write('#define %s%s_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), %sTYPE_%s_STUB, %sStubClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
394             self.h.write('#define %s%s_STUB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), %sTYPE_%s_STUB, %sStubClass))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper, i.camel_name))
395             self.h.write('#define %sIS_%s_STUB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), %sTYPE_%s_STUB))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
396             self.h.write('#define %sIS_%s_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), %sTYPE_%s_STUB))\n'%(i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
397             self.h.write('\n')
398             self.h.write('typedef struct _%sStub %sStub;\n'%(i.camel_name, i.camel_name))
399             self.h.write('typedef struct _%sStubClass %sStubClass;\n'%(i.camel_name, i.camel_name))
400             self.h.write('typedef struct _%sStubPrivate %sStubPrivate;\n'%(i.camel_name, i.camel_name))
401             self.h.write('\n')
402             self.h.write('struct _%sStub\n'%(i.camel_name))
403             self.h.write('{\n')
404             self.h.write('  GDBusInterfaceStub parent_instance;\n')
405             self.h.write('  %sStubPrivate *priv;\n'%(i.camel_name))
406             self.h.write('};\n')
407             self.h.write('\n')
408             self.h.write('struct _%sStubClass\n'%(i.camel_name))
409             self.h.write('{\n')
410             self.h.write('  GDBusInterfaceStubClass parent_class;\n')
411             self.h.write('};\n')
412             self.h.write('\n')
413             self.h.write('GType %s_stub_get_gtype (void) G_GNUC_CONST;\n'%(i.name_lower))
414             self.h.write('\n')
415             self.h.write('%s *%s_stub_new (void);\n'%(i.camel_name, i.name_lower))
416
417             self.h.write('\n')
418
419         # Finally, the proxy manager
420         self.h.write('\n')
421         self.h.write('/* ---- */\n')
422         self.h.write('\n')
423         self.h.write('#define %sTYPE_OBJECT_MANAGER_CLIENT (%sobject_manager_client_get_gtype ())\n'%(self.ns_upper, self.ns_lower))
424         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))
425         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))
426         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))
427         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))
428         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))
429         self.h.write('\n')
430         self.h.write('typedef struct _%sObjectManagerClient %sObjectManagerClient;\n'%(self.namespace, self.namespace))
431         self.h.write('typedef struct _%sObjectManagerClientClass %sObjectManagerClientClass;\n'%(self.namespace, self.namespace))
432         self.h.write('typedef struct _%sObjectManagerClientPrivate %sObjectManagerClientPrivate;\n'%(self.namespace, self.namespace))
433         self.h.write('\n')
434         self.h.write('struct _%sObjectManagerClient\n'%(self.namespace))
435         self.h.write('{\n')
436         self.h.write('  GDBusObjectManagerClient parent_instance;\n')
437         self.h.write('  %sObjectManagerClientPrivate *priv;\n'%(self.namespace))
438         self.h.write('};\n')
439         self.h.write('\n')
440         self.h.write('struct _%sObjectManagerClientClass\n'%(self.namespace))
441         self.h.write('{\n')
442         self.h.write('  GDBusObjectManagerClientClass parent_class;\n')
443         self.h.write('};\n')
444         self.h.write('\n')
445         self.h.write('GType %sobject_manager_client_get_gtype (void) G_GNUC_CONST;\n'%(self.ns_lower))
446         self.h.write('\n')
447         self.h.write('GDBusProxyTypeFunc %sobject_manager_client_get_proxy_type_func (void);\n'%(self.ns_lower))
448         self.h.write('\n')
449         self.h.write('void %sobject_manager_client_new (\n'
450                      '    GDBusConnection        *connection,\n'
451                      '    GDBusObjectManagerClientFlags  flags,\n'
452                      '    const gchar            *name,\n'
453                      '    const gchar            *object_path,\n'
454                      '    GCancellable           *cancellable,\n'
455                      '    GAsyncReadyCallback     callback,\n'
456                      '    gpointer                user_data);\n'
457                      %(self.ns_lower))
458         self.h.write('GDBusObjectManager *%sobject_manager_client_new_finish (\n'
459                      '    GAsyncResult        *res,\n'
460                      '    GError             **error);\n'
461                      %(self.ns_lower))
462         self.h.write('GDBusObjectManager *%sobject_manager_client_new_sync (\n'
463                      '    GDBusConnection        *connection,\n'
464                      '    GDBusObjectManagerClientFlags  flags,\n'
465                      '    const gchar            *name,\n'
466                      '    const gchar            *object_path,\n'
467                      '    GCancellable           *cancellable,\n'
468                      '    GError                **error);\n'
469                      %(self.ns_lower))
470         self.h.write('\n')
471         self.h.write('void %sobject_manager_client_new_for_bus (\n'
472                      '    GBusType                bus_type,\n'
473                      '    GDBusObjectManagerClientFlags  flags,\n'
474                      '    const gchar            *name,\n'
475                      '    const gchar            *object_path,\n'
476                      '    GCancellable           *cancellable,\n'
477                      '    GAsyncReadyCallback     callback,\n'
478                      '    gpointer                user_data);\n'
479                      %(self.ns_lower))
480         self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_finish (\n'
481                      '    GAsyncResult        *res,\n'
482                      '    GError             **error);\n'
483                      %(self.ns_lower))
484         self.h.write('GDBusObjectManager *%sobject_manager_client_new_for_bus_sync (\n'
485                      '    GBusType                bus_type,\n'
486                      '    GDBusObjectManagerClientFlags  flags,\n'
487                      '    const gchar            *name,\n'
488                      '    const gchar            *object_path,\n'
489                      '    GCancellable           *cancellable,\n'
490                      '    GError                **error);\n'
491                      %(self.ns_lower))
492         self.h.write('\n')
493
494     # ----------------------------------------------------------------------------------------------------
495
496     def generate_outro(self):
497         self.h.write('\n'
498                      'G_END_DECLS\n'
499                      '\n'
500                      '#endif /* __%s__ */\n'%(self.header_guard))
501
502     # ----------------------------------------------------------------------------------------------------
503
504     def generate_annotations(self, prefix, annotations):
505         if annotations == None:
506             return
507
508         n = 0
509         for a in annotations:
510             #self.generate_annotations('%s_%d'%(prefix, n), a.get_annotations())
511
512             # skip internal annotations
513             if a.key.startswith('org.gtk.GDBus'):
514                 continue
515
516             self.c.write('static const GDBusAnnotationInfo %s_%d =\n'
517                          '{\n'
518                          '  -1,\n'
519                          '  "%s",\n'
520                          '  "%s",\n'%(prefix, n, a.key, a.value))
521             if len(a.annotations) == 0:
522                 self.c.write('  NULL\n')
523             else:
524                 self.c.write('  (GDBusAnnotationInfo **) &%s_%d_pointers\n'%(prefix, n))
525             self.c.write('};\n'
526                          '\n')
527             n += 1
528
529         if n > 0:
530             self.c.write('static const GDBusAnnotationInfo * const %s_pointers[] =\n'
531                              '{\n'%(prefix))
532             m = 0;
533             for a in annotations:
534                 if a.key.startswith('org.gtk.GDBus'):
535                     continue
536                 self.c.write('  &%s_%d,\n'%(prefix, m))
537                 m += 1
538             self.c.write('  NULL\n'
539                          '};\n'
540                          '\n')
541         return n
542
543     def generate_args(self, prefix, args):
544         for a in args:
545             num_anno = self.generate_annotations('%s_arg_%s_annotation_info'%(prefix, a.name), a.annotations)
546
547             self.c.write('static const _ExtendedGDBusArgInfo %s_%s =\n'
548                          '{\n'
549                          '  {\n'
550                          '    -1,\n'
551                          '    "%s",\n'
552                          '    "%s",\n'%(prefix, a.name, a.name, a.signature))
553             if num_anno == 0:
554                 self.c.write('    NULL\n')
555             else:
556                 self.c.write('    (GDBusAnnotationInfo **) &%s_arg_%s_annotation_info_pointers\n'%(prefix, a.name))
557             self.c.write('  },\n')
558             if not utils.lookup_annotation(a.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
559                 self.c.write('  FALSE\n')
560             else:
561                 self.c.write('  TRUE\n')
562             self.c.write('};\n'
563                          '\n')
564
565         if len(args) > 0:
566             self.c.write('static const _ExtendedGDBusArgInfo * const %s_pointers[] =\n'
567                              '{\n'%(prefix))
568             for a in args:
569                 self.c.write('  &%s_%s,\n'%(prefix, a.name))
570             self.c.write('  NULL\n'
571                          '};\n'
572                          '\n')
573
574     def generate_introspection_for_interface(self, i):
575             self.c.write('/* ---- Introspection data for %s ---- */\n'
576                          '\n'%(i.name))
577
578             if len(i.methods) > 0:
579                 for m in i.methods:
580                     self.generate_args('_%s_method_info_%s_IN_ARG'%(i.name_lower, m.name_lower), m.in_args)
581                     self.generate_args('_%s_method_info_%s_OUT_ARG'%(i.name_lower, m.name_lower), m.out_args)
582
583                     num_anno = self.generate_annotations('_%s_method_%s_annotation_info'%(i.name_lower, m.name_lower), m.annotations)
584
585                     self.c.write('static const _ExtendedGDBusMethodInfo _%s_method_info_%s =\n'
586                                  '{\n'
587                                  '  {\n'
588                                  '    -1,\n'
589                                  '    "%s",\n'%(i.name_lower, m.name_lower, m.name))
590                     if len(m.in_args) == 0:
591                         self.c.write('    NULL,\n')
592                     else:
593                         self.c.write('    (GDBusArgInfo **) &_%s_method_info_%s_IN_ARG_pointers,\n'%(i.name_lower, m.name_lower))
594                     if len(m.out_args) == 0:
595                         self.c.write('    NULL,\n')
596                     else:
597                         self.c.write('    (GDBusArgInfo **) &_%s_method_info_%s_OUT_ARG_pointers,\n'%(i.name_lower, m.name_lower))
598                     if num_anno == 0:
599                         self.c.write('    NULL\n')
600                     else:
601                         self.c.write('    (GDBusAnnotationInfo **) &_%s_method_%s_annotation_info_pointers\n'%(i.name_lower, m.name_lower))
602                     self.c.write('  },\n'
603                                  '  "handle-%s"\n'
604                                  %(m.name_hyphen))
605                     self.c.write('};\n'
606                                  '\n')
607
608                 self.c.write('static const _ExtendedGDBusMethodInfo * const _%s_method_info_pointers[] =\n'
609                              '{\n'%(i.name_lower))
610                 for m in i.methods:
611                     self.c.write('  &_%s_method_info_%s,\n'%(i.name_lower, m.name_lower))
612                 self.c.write('  NULL\n'
613                              '};\n'
614                              '\n')
615
616             # ---
617
618             if len(i.signals) > 0:
619                 for s in i.signals:
620                     self.generate_args('_%s_signal_info_%s_ARG'%(i.name_lower, s.name_lower), s.args)
621
622                     num_anno = self.generate_annotations('_%s_signal_%s_annotation_info'%(i.name_lower, s.name_lower), s.annotations)
623                     self.c.write('static const _ExtendedGDBusSignalInfo _%s_signal_info_%s =\n'
624                                  '{\n'
625                                  '  {\n'
626                                  '    -1,\n'
627                                  '    "%s",\n'%(i.name_lower, s.name_lower, s.name))
628                     if len(s.args) == 0:
629                         self.c.write('    NULL,\n')
630                     else:
631                         self.c.write('    (GDBusArgInfo **) &_%s_signal_info_%s_ARG_pointers,\n'%(i.name_lower, s.name_lower))
632                     if num_anno == 0:
633                         self.c.write('    NULL\n')
634                     else:
635                         self.c.write('    (GDBusAnnotationInfo **) &_%s_signal_%s_annotation_info_pointers\n'%(i.name_lower, s.name_lower))
636                     self.c.write('  },\n'
637                                  '  "%s"\n'
638                                  %(s.name_hyphen))
639                     self.c.write('};\n'
640                                  '\n')
641
642                 self.c.write('static const _ExtendedGDBusSignalInfo * const _%s_signal_info_pointers[] =\n'
643                              '{\n'%(i.name_lower))
644                 for s in i.signals:
645                     self.c.write('  &_%s_signal_info_%s,\n'%(i.name_lower, s.name_lower))
646                 self.c.write('  NULL\n'
647                              '};\n'
648                              '\n')
649
650             # ---
651
652             if len(i.properties) > 0:
653                 for p in i.properties:
654                     if p.readable and p.writable:
655                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
656                     elif p.readable:
657                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_READABLE'
658                     elif p.writable:
659                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE'
660                     else:
661                         access = 'G_DBUS_PROPERTY_INFO_FLAGS_NONE'
662                     num_anno = self.generate_annotations('_%s_property_%s_annotation_info'%(i.name_lower, p.name_lower), p.annotations)
663                     self.c.write('static const _ExtendedGDBusPropertyInfo _%s_property_info_%s =\n'
664                                  '{\n'
665                                  '  {\n'
666                                  '    -1,\n'
667                                  '    "%s",\n'
668                                  '    "%s",\n'
669                                  '    %s,\n'%(i.name_lower, p.name_lower, p.name, p.arg.signature, access))
670                     if num_anno == 0:
671                         self.c.write('    NULL\n')
672                     else:
673                         self.c.write('    (GDBusAnnotationInfo **) &_%s_property_%s_annotation_info_pointers\n'%(i.name_lower, p.name_lower))
674                     self.c.write('  },\n'
675                                  '  "%s",\n'
676                                  %(p.name_hyphen))
677                     if not utils.lookup_annotation(p.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
678                         self.c.write('  FALSE\n')
679                     else:
680                         self.c.write('  TRUE\n')
681                     self.c.write('};\n'
682                                  '\n')
683
684                 self.c.write('static const _ExtendedGDBusPropertyInfo * const _%s_property_info_pointers[] =\n'
685                              '{\n'%(i.name_lower))
686                 for p in i.properties:
687                     self.c.write('  &_%s_property_info_%s,\n'%(i.name_lower, p.name_lower))
688                 self.c.write('  NULL\n'
689                              '};\n'
690                              '\n')
691
692             num_anno = self.generate_annotations('_%s_annotation_info'%(i.name_lower), i.annotations)
693             self.c.write('static const GDBusInterfaceInfo _%s_interface_info =\n'
694                          '{\n'
695                          '  -1,\n'
696                          '  "%s",\n'%(i.name_lower, i.name))
697             if len(i.methods) == 0:
698                 self.c.write('  NULL,\n')
699             else:
700                 self.c.write('  (GDBusMethodInfo **) &_%s_method_info_pointers,\n'%(i.name_lower))
701             if len(i.signals) == 0:
702                 self.c.write('  NULL,\n')
703             else:
704                 self.c.write('  (GDBusSignalInfo **) &_%s_signal_info_pointers,\n'%(i.name_lower))
705             if len(i.properties) == 0:
706                 self.c.write('  NULL,\n')
707             else:
708                 self.c.write('  (GDBusPropertyInfo **) &_%s_property_info_pointers,\n'%(i.name_lower))
709             if num_anno == 0:
710                 self.c.write('  NULL\n')
711             else:
712                 self.c.write('  (GDBusAnnotationInfo **) &_%s_annotation_info_pointers\n'%(i.name_lower))
713             self.c.write('};\n'
714                          '\n')
715             self.c.write('\n')
716             self.c.write('GDBusInterfaceInfo *\n'
717                          '%s_interface_info (void)\n'
718                          '{\n'
719                          '  return (GDBusInterfaceInfo *) &_%s_interface_info;\n'
720                          '}\n'
721                          '\n'%(i.name_lower, i.name_lower))
722
723             if len(i.properties) > 0:
724                 self.c.write('guint\n'
725                              '%s_override_properties (GObjectClass *klass, guint property_id_begin)\n'
726                              '{\n'%(i.name_lower))
727                 for p in i.properties:
728                     self.c.write ('  g_object_class_override_property (klass, property_id_begin++, "%s");\n'%(p.name_hyphen))
729                 self.c.write('  return property_id_begin - 1;\n'
730                              '}\n'
731                              '\n')
732             self.c.write('\n')
733
734     # ----------------------------------------------------------------------------------------------------
735
736     def generate_interface(self, i):
737         self.c.write('\n')
738
739         self.c.write('static void\n'
740                      '%s_default_init (%sIface *iface)\n'
741                      '{\n'%(i.name_lower, i.camel_name));
742
743         if len(i.methods) > 0:
744             self.c.write('  /* GObject signals for incoming D-Bus method calls: */\n')
745             for m in i.methods:
746                 self.c.write('  g_signal_new ("handle-%s",\n'
747                              '    G_TYPE_FROM_INTERFACE (iface),\n'
748                              '    G_SIGNAL_RUN_LAST,\n'
749                              '    G_STRUCT_OFFSET (%sIface, handle_%s),\n'
750                              '    g_signal_accumulator_true_handled,\n'
751                              '    NULL,\n' # accu_data
752                              '    _cclosure_marshal_generic,\n'
753                              '    G_TYPE_BOOLEAN,\n'
754                              '    %d,\n'
755                              '    G_TYPE_DBUS_METHOD_INVOCATION'
756                              %(m.name_hyphen, i.camel_name, m.name_lower, len(m.in_args) + 1))
757                 for a in m.in_args:
758                     self.c.write (', %s'%(a.gtype))
759                 self.c.write(');\n')
760                 self.c.write('\n')
761
762         if len(i.signals) > 0:
763             self.c.write('  /* GObject signals for received D-Bus signals: */\n')
764             for s in i.signals:
765                 self.c.write('  g_signal_new ("%s",\n'
766                              '    G_TYPE_FROM_INTERFACE (iface),\n'
767                              '    G_SIGNAL_RUN_LAST,\n'
768                              '    G_STRUCT_OFFSET (%sIface, %s),\n'
769                              '    NULL,\n' # accumulator
770                              '    NULL,\n' # accu_data
771                              '    _cclosure_marshal_generic,\n'
772                              '    G_TYPE_NONE,\n'
773                              '    %d'
774                              %(s.name_hyphen, i.camel_name, s.name_lower, len(s.args)))
775                 for a in s.args:
776                     self.c.write (', %s'%(a.gtype))
777                 self.c.write(');\n')
778                 self.c.write('\n')
779
780         if len(i.properties) > 0:
781             self.c.write('  /* GObject properties for D-Bus properties: */\n')
782             for p in i.properties:
783                 self.c.write('  g_object_interface_install_property (iface,\n')
784                 if p.arg.gtype == 'G_TYPE_VARIANT':
785                     s = 'g_param_spec_variant ("%s", NULL, NULL, G_VARIANT_TYPE ("%s"), NULL'%(p.name_hyphen, p.arg.signature)
786                 elif p.arg.signature == 'b':
787                     s = 'g_param_spec_boolean ("%s", NULL, NULL, FALSE'%(p.name_hyphen)
788                 elif p.arg.signature == 'y':
789                     s = 'g_param_spec_uchar ("%s", NULL, NULL, 0, 255, 0'%(p.name_hyphen)
790                 elif p.arg.signature == 'n':
791                     s = 'g_param_spec_int ("%s", NULL, NULL, G_MININT16, G_MAXINT16, 0'%(p.name_hyphen)
792                 elif p.arg.signature == 'q':
793                     s = 'g_param_spec_uint ("%s", NULL, NULL, 0, G_MAXUINT16, 0'%(p.name_hyphen)
794                 elif p.arg.signature == 'i':
795                     s = 'g_param_spec_int ("%s", NULL, NULL, G_MININT32, G_MAXINT32, 0'%(p.name_hyphen)
796                 elif p.arg.signature == 'u':
797                     s = 'g_param_spec_uint ("%s", NULL, NULL, 0, G_MAXUINT32, 0'%(p.name_hyphen)
798                 elif p.arg.signature == 'x':
799                     s = 'g_param_spec_int64 ("%s", NULL, NULL, G_MININT64, G_MAXINT64, 0'%(p.name_hyphen)
800                 elif p.arg.signature == 't':
801                     s = 'g_param_spec_uint64 ("%s", NULL, NULL, 0, G_MAXUINT64, 0'%(p.name_hyphen)
802                 elif p.arg.signature == 'd':
803                     s = 'g_param_spec_double ("%s", NULL, NULL, -G_MAXDOUBLE, G_MAXDOUBLE, 0.0'%(p.name_hyphen)
804                 elif p.arg.signature == 's':
805                     s = 'g_param_spec_string ("%s", NULL, NULL, NULL'%(p.name_hyphen)
806                 elif p.arg.signature == 'o':
807                     s = 'g_param_spec_string ("%s", NULL, NULL, NULL'%(p.name_hyphen)
808                 elif p.arg.signature == 'g':
809                     s = 'g_param_spec_string ("%s", NULL, NULL, NULL'%(p.name_hyphen)
810                 elif p.arg.signature == 'ay':
811                     s = 'g_param_spec_string ("%s", NULL, NULL, NULL'%(p.name_hyphen)
812                 elif p.arg.signature == 'as':
813                     s = 'g_param_spec_boxed ("%s", NULL, NULL, G_TYPE_STRV'%(p.name_hyphen)
814                 elif p.arg.signature == 'aay':
815                     s = 'g_param_spec_boxed ("%s", NULL, NULL, G_TYPE_STRV'%(p.name_hyphen)
816                 else:
817                     raise RuntimeError('Unsupported gtype %s for GParamSpec'%(p.arg.gtype))
818                 self.c.write('    %s, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));'%s);
819                 self.c.write('\n')
820
821         self.c.write('}\n'
822                      '\n')
823
824         self.c.write('typedef %sIface %sInterface;\n'%(i.camel_name, i.camel_name))
825         self.c.write('#define %s_get_type %s_get_gtype\n'%(i.name_lower, i.name_lower))
826         self.c.write('G_DEFINE_INTERFACE (%s, %s, G_TYPE_OBJECT);\n'%(i.camel_name, i.name_lower))
827         self.c.write('#undef %s_get_type\n'%(i.name_lower))
828         self.c.write('\n')
829
830     # ----------------------------------------------------------------------------------------------------
831
832     def generate_property_accessors(self, i):
833         for p in i.properties:
834             # getter
835             self.c.write('%s\n'
836                          '%s_get_%s (%s *object)\n'
837                          '{\n'
838                          '  %svalue;\n'%(p.arg.ctype_in, i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in_g))
839             self.c.write('  g_object_get (G_OBJECT (object), "%s", &value, NULL);\n'%(p.name_hyphen))
840             if p.arg.free_func:
841                 self.c.write('  if (value != NULL)\n'
842                              '    g_object_set_data_full (G_OBJECT (object), "-x-memoizing-%s", (gpointer) value, (GDestroyNotify) %s);\n'
843                              '  else\n'
844                              '    g_object_set_data_full (G_OBJECT (object), "-x-memoizing-%s", (gpointer) value, NULL);\n'
845                              %(p.name_hyphen, p.arg.free_func, p.name_hyphen))
846             self.c.write('  return value;\n')
847             self.c.write('}\n')
848             self.c.write('\n')
849             # setter
850             self.c.write('void\n'
851                          '%s_set_%s (%s *object, %svalue)\n'
852                          '{\n'%(i.name_lower, p.name_lower, i.camel_name, p.arg.ctype_in, ))
853             self.c.write('  g_object_set (G_OBJECT (object), "%s", value, NULL);\n'%(p.name_hyphen))
854             self.c.write('}\n')
855             self.c.write('\n')
856
857     # ---------------------------------------------------------------------------------------------------
858
859     def generate_signal_emitters(self, i):
860         for s in i.signals:
861             self.c.write('void\n'
862                          '%s_emit_%s (\n'
863                          '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
864             for a in s.args:
865                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
866             self.c.write(')\n'
867                          '{\n'
868                          '  g_signal_emit_by_name (object, "%s"'%(s.name_hyphen))
869             for a in s.args:
870                 self.c.write(', %s'%a.name)
871             self.c.write(');\n')
872             self.c.write('}\n'
873                          '\n')
874
875     # ---------------------------------------------------------------------------------------------------
876
877     def generate_method_calls(self, i):
878         for m in i.methods:
879             # async begin
880             self.c.write('void\n'
881                          '%s_call_%s (\n'
882                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
883             for a in m.in_args:
884                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
885             self.c.write(',\n'
886                          '    GCancellable *cancellable,\n'
887                          '    GAsyncReadyCallback callback,\n'
888                          '    gpointer user_data)\n'
889                          '{\n')
890             self.c.write('  g_dbus_proxy_call (G_DBUS_PROXY (proxy),\n'
891                          '    "%s",\n'
892                          '    g_variant_new ("('%(m.name))
893             for a in m.in_args:
894                 self.c.write('%s'%(a.format_in))
895             self.c.write(')"')
896             for a in m.in_args:
897                 self.c.write(',\n                   %s'%(a.name))
898             self.c.write('),\n'
899                          '    G_DBUS_CALL_FLAGS_NONE,\n'
900                          '    -1,\n'
901                          '    cancellable,\n'
902                          '    callback,\n'
903                          '    user_data);\n')
904             self.c.write('}\n'
905                          '\n')
906             # async finish
907             self.c.write('gboolean\n'
908                          '%s_call_%s_finish (\n'
909                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
910             for a in m.out_args:
911                 self.c.write(',\n    %sout_%s'%(a.ctype_out, a.name))
912             self.c.write(',\n'
913                          '    GAsyncResult *res,\n'
914                          '    GError **error)\n'
915                          '{\n'
916                          '  GVariant *_ret;\n'
917                          '  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);\n'
918                          '  if (_ret == NULL)\n'
919                          '    goto _out;\n')
920             self.c.write('  g_variant_get (_ret,\n'
921                          '                 \"(')
922             for a in m.out_args:
923                 self.c.write('%s'%(a.format_out))
924             self.c.write(')"')
925             for a in m.out_args:
926                 self.c.write(',\n                 out_%s'%(a.name))
927             self.c.write(');\n'
928                          '  g_variant_unref (_ret);\n')
929             self.c.write('_out:\n'
930                          '  return _ret != NULL;\n'
931                          '}\n'
932                          '\n')
933
934
935             # sync
936             self.c.write('gboolean\n'
937                          '%s_call_%s_sync (\n'
938                          '    %s *proxy'%(i.name_lower, m.name_lower, i.camel_name))
939             for a in m.in_args:
940                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
941             for a in m.out_args:
942                 self.c.write(',\n    %sout_%s'%(a.ctype_out, a.name))
943             self.c.write(',\n'
944                          '    GCancellable *cancellable,\n'
945                          '    GError **error)\n'
946                          '{\n'
947                          '  GVariant *_ret;\n')
948             self.c.write('  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),\n'
949                          '    "%s",\n'
950                          '    g_variant_new ("('%(m.name))
951             for a in m.in_args:
952                 self.c.write('%s'%(a.format_in))
953             self.c.write(')"')
954             for a in m.in_args:
955                 self.c.write(',\n                   %s'%(a.name))
956             self.c.write('),\n'
957                          '    G_DBUS_CALL_FLAGS_NONE,\n'
958                          '    -1,\n'
959                          '    cancellable,\n'
960                          '    error);\n'
961                          '  if (_ret == NULL)\n'
962                          '    goto _out;\n')
963             self.c.write('  g_variant_get (_ret,\n'
964                          '                 \"(')
965             for a in m.out_args:
966                 self.c.write('%s'%(a.format_out))
967             self.c.write(')"')
968             for a in m.out_args:
969                 self.c.write(',\n                 out_%s'%(a.name))
970             self.c.write(');\n'
971                          '  g_variant_unref (_ret);\n')
972             self.c.write('_out:\n'
973                          '  return _ret != NULL;\n'
974                          '}\n'
975                          '\n')
976
977     # ---------------------------------------------------------------------------------------------------
978
979     def generate_method_completers(self, i):
980         for m in i.methods:
981             self.c.write('void\n'
982                          '%s_complete_%s (\n'
983                          '    %s *object,\n'
984                          '    GDBusMethodInvocation *invocation'%(i.name_lower, m.name_lower, i.camel_name))
985             for a in m.out_args:
986                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
987             self.c.write(')\n'
988                          '{\n')
989
990             self.c.write('  g_dbus_method_invocation_return_value (invocation,\n'
991                          '    g_variant_new ("(')
992             for a in m.out_args:
993                 self.c.write('%s'%(a.format_in))
994             self.c.write(')"')
995             for a in m.out_args:
996                 self.c.write(',\n                   %s'%(a.name))
997             self.c.write('));\n'
998                          '}\n'
999                          '\n')
1000
1001     # ---------------------------------------------------------------------------------------------------
1002
1003     def generate_proxy(self, i):
1004         # class boilerplate
1005         self.c.write('/* ------------------------------------------------------------------------ */\n'
1006                      '\n')
1007         self.c.write('static void\n'
1008                      '%s_proxy_iface_init (%sIface *iface)\n'
1009                      '{\n'
1010                      '}\n'
1011                      '\n'%(i.name_lower, i.camel_name))
1012         self.c.write('#define %s_proxy_get_type %s_proxy_get_gtype\n'%(i.name_lower, i.name_lower))
1013         self.c.write('G_DEFINE_TYPE_WITH_CODE (%sProxy, %s_proxy, G_TYPE_DBUS_PROXY,\n'%(i.camel_name, i.name_lower))
1014         self.c.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_proxy_iface_init));\n'%(i.ns_upper, i.name_upper, i.name_lower))
1015         self.c.write('#undef %s_proxy_get_type\n'
1016                      '\n'%(i.name_lower))
1017
1018         # property accessors
1019         #
1020         # Note that we are guaranteed that prop_id starts at 1 and is
1021         # laid out in the same order as introspection data pointers
1022         #
1023         self.c.write('static void\n'
1024                      '%s_proxy_get_property (GObject      *object,\n'
1025                      '  guint         prop_id,\n'
1026                      '  GValue       *value,\n'
1027                      '  GParamSpec   *pspec)\n'
1028                      '{\n'%(i.name_lower))
1029         if len(i.properties) > 0:
1030             self.c.write('  const _ExtendedGDBusPropertyInfo *info;\n'
1031                          '  GVariant *variant;\n'
1032                          '  g_assert (prop_id - 1 >= 0 && prop_id - 1 < %d);\n'
1033                          '  info = _%s_property_info_pointers[prop_id - 1];\n'
1034                          '  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);\n'
1035                          '  if (info->use_gvariant)\n'
1036                          '    g_value_set_variant (value, variant);\n'
1037                          '  else\n'
1038                          '    g_dbus_gvariant_to_gvalue (variant, value);\n'
1039                          '  if (variant != NULL)\n'
1040                          '    g_variant_unref (variant);\n'
1041                          %(len(i.properties), i.name_lower))
1042         self.c.write('}\n'
1043                      '\n')
1044         if len(i.properties) > 0:
1045             self.c.write('static void\n'
1046                          '%s_proxy_set_property_cb (GDBusProxy *proxy,\n'
1047                          '  GAsyncResult *res,\n'
1048                          '  gpointer      user_data)\n'
1049                          '{\n'%(i.name_lower))
1050             self.c.write('  const _ExtendedGDBusPropertyInfo *info = user_data;\n'
1051                          '  GError *error;\n'
1052                          '  error = NULL;\n'
1053                          '  if (!g_dbus_proxy_call_finish (proxy, res, &error))\n'
1054                          '    {\n'
1055                          '      g_warning ("Error setting property `%%s\' on interface %s: %%s (%%s, %%d)",\n'
1056                          '                 info->parent_struct.name, \n'
1057                          '                 error->message, g_quark_to_string (error->domain), error->code);\n'
1058                          '      g_error_free (error);\n'
1059                          '    }\n'
1060                          %(i.name))
1061             self.c.write('}\n'
1062                          '\n')
1063         self.c.write('static void\n'
1064                      '%s_proxy_set_property (GObject      *object,\n'
1065                      '  guint         prop_id,\n'
1066                      '  const GValue *value,\n'
1067                      '  GParamSpec   *pspec)\n'
1068                      '{\n'%(i.name_lower))
1069         if len(i.properties) > 0:
1070             self.c.write('  const _ExtendedGDBusPropertyInfo *info;\n'
1071                          '  GVariant *variant;\n'
1072                          '  g_assert (prop_id - 1 >= 0 && prop_id - 1 < %d);\n'
1073                          '  info = _%s_property_info_pointers[prop_id - 1];\n'
1074                          '  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));\n'
1075                          '  g_dbus_proxy_call (G_DBUS_PROXY (object),\n'
1076                          '    "org.freedesktop.DBus.Properties.Set",\n'
1077                          '    g_variant_new ("(ssv)", "%s", info->parent_struct.name, variant),\n'
1078                          '    G_DBUS_CALL_FLAGS_NONE,\n'
1079                          '    -1,\n'
1080                          '    NULL, (GAsyncReadyCallback) %s_proxy_set_property_cb, (gpointer) info);\n'
1081                          '  g_variant_unref (variant);\n'
1082                          %(len(i.properties), i.name_lower, i.name, i.name_lower))
1083         self.c.write('}\n'
1084                      '\n')
1085
1086         # signal received
1087         self.c.write('static void\n'
1088                      '%s_proxy_g_signal (GDBusProxy *proxy,\n'
1089                      '  const gchar *sender_name,\n'
1090                      '  const gchar *signal_name,\n'
1091                      '  GVariant *parameters)\n'
1092                      '{\n'%(i.name_lower))
1093         self.c.write('  _ExtendedGDBusSignalInfo *info;\n'
1094                      '  GVariantIter iter;\n'
1095                      '  GVariant *child;\n'
1096                      '  GValue *paramv;\n'
1097                      '  guint num_params;\n'
1098                      '  guint n;\n'
1099                      '  guint signal_id;\n');
1100         # Note: info could be NULL if we are talking to a newer version of the interface
1101         self.c.write('  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_%s_interface_info, signal_name);\n'
1102                      '  if (info == NULL)\n'
1103                      '    return;\n'
1104                      %(i.name_lower))
1105         self.c.write ('  num_params = g_variant_n_children (parameters);\n'
1106                       '  paramv = g_new0 (GValue, num_params + 1);\n'
1107                       '  g_value_init (&paramv[0], %sTYPE_%s);\n'
1108                       '  g_value_set_object (&paramv[0], proxy);\n'
1109                       %(i.ns_upper, i.name_upper))
1110         self.c.write('  g_variant_iter_init (&iter, parameters);\n'
1111                      '  n = 1;\n'
1112                      '  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
1113                      '    {\n'
1114                      '      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];\n'
1115                      '      if (arg_info->use_gvariant)\n'
1116                      '        {\n'
1117                      '          g_value_init (&paramv[n], G_TYPE_VARIANT);\n'
1118                      '          g_value_set_variant (&paramv[n], child);\n'
1119                      '          n++;\n'
1120                      '        }\n'
1121                      '      else\n'
1122                      '        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n'
1123                      '      g_variant_unref (child);\n'
1124                      '    }\n'
1125                      )
1126         self.c.write('  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n'
1127                      %(i.ns_upper, i.name_upper))
1128         self.c.write('  g_signal_emitv (paramv, signal_id, 0, NULL);\n')
1129         self.c.write('  for (n = 0; n < num_params + 1; n++)\n'
1130                      '    g_value_unset (&paramv[n]);\n'
1131                      '  g_free (paramv);\n')
1132         self.c.write('}\n'
1133                      '\n')
1134
1135         # property changed
1136         self.c.write('static void\n'
1137                      '%s_proxy_g_properties_changed (GDBusProxy *proxy,\n'
1138                      '  GVariant *changed_properties,\n'
1139                      '  const gchar *const *invalidated_properties)\n'
1140                      '{\n'%(i.name_lower))
1141         # Note: info could be NULL if we are talking to a newer version of the interface
1142         self.c.write('  guint n;\n'
1143                      '  const gchar *key;\n'
1144                      '  GVariantIter *iter;\n'
1145                      '  _ExtendedGDBusPropertyInfo *info;\n'
1146                      '  g_variant_get (changed_properties, "a{sv}", &iter);\n'
1147                      '  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))\n'
1148                      '    {\n'
1149                      '      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, key);\n'
1150                      '      if (info != NULL)\n'
1151                      '        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n'
1152                      '    }\n'
1153                      '  g_variant_iter_free (iter);\n'
1154                      '  for (n = 0; invalidated_properties[n] != NULL; n++)\n'
1155                      '    {\n'
1156                      '      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, invalidated_properties[n]);\n'
1157                      '      if (info != NULL)\n'
1158                      '        g_object_notify (G_OBJECT (proxy), info->hyphen_name);\n'
1159                      '    }\n'
1160                      '}\n'
1161                      '\n'
1162                      %(i.name_lower, i.name_lower))
1163
1164         # class boilerplate
1165         self.c.write('static void\n'
1166                      '%s_proxy_init (%sProxy *proxy)\n'
1167                      '{\n'
1168                      '  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), %s_interface_info ());\n'
1169                      '}\n'
1170                      '\n'%(i.name_lower, i.camel_name, i.name_lower))
1171         self.c.write('static void\n'
1172                      '%s_proxy_class_init (%sProxyClass *klass)\n'
1173                      '{\n'
1174                      '  GObjectClass *gobject_class;\n'
1175                      '  GDBusProxyClass *proxy_class;\n'
1176                      '\n'
1177                      '  gobject_class = G_OBJECT_CLASS (klass);\n'
1178                      '  gobject_class->get_property = %s_proxy_get_property;\n'
1179                      '  gobject_class->set_property = %s_proxy_set_property;\n'
1180                      '\n'
1181                      '  proxy_class = G_DBUS_PROXY_CLASS (klass);\n'
1182                      '  proxy_class->g_signal = %s_proxy_g_signal;\n'
1183                      '  proxy_class->g_properties_changed = %s_proxy_g_properties_changed;\n'
1184                      '\n'%(i.name_lower, i.camel_name, i.name_lower, i.name_lower, i.name_lower, i.name_lower))
1185         if len(i.properties) > 0:
1186             self.c.write('\n'
1187                          '  %s_override_properties (gobject_class, 1);\n'%(i.name_lower))
1188         self.c.write('}\n')
1189
1190         # constructors
1191         self.c.write('void\n'
1192                      '%s_proxy_new (\n'
1193                      '    GDBusConnection     *connection,\n'
1194                      '    GDBusProxyFlags      flags,\n'
1195                      '    const gchar         *name,\n'
1196                      '    const gchar         *object_path,\n'
1197                      '    GCancellable        *cancellable,\n'
1198                      '    GAsyncReadyCallback  callback,\n'
1199                      '    gpointer             user_data)\n'
1200                      '{\n'
1201                      '  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'
1202                      '}\n'
1203                      '\n'
1204                      %(i.name_lower, i.ns_upper, i.name_upper, i.name))
1205         self.c.write('%s *\n'
1206                      '%s_proxy_new_finish (\n'
1207                      '    GAsyncResult        *res,\n'
1208                      '    GError             **error)\n'
1209                      '{\n'
1210                      '  GObject *ret;\n'
1211                      '  GObject *source_object;\n'
1212                      '  source_object = g_async_result_get_source_object (res);\n'
1213                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
1214                      '  g_object_unref (source_object);\n'
1215                      '  if (ret != NULL)\n'
1216                      '    return %s%s (ret);\n'
1217                      '  else\n'
1218                      '    return NULL;\n'
1219                      '}\n'
1220                      '\n'
1221                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
1222         self.c.write('%s *\n'
1223                      '%s_proxy_new_sync (\n'
1224                      '    GDBusConnection     *connection,\n'
1225                      '    GDBusProxyFlags      flags,\n'
1226                      '    const gchar         *name,\n'
1227                      '    const gchar         *object_path,\n'
1228                      '    GCancellable        *cancellable,\n'
1229                      '    GError             **error)\n'
1230                      '{\n'
1231                      '  GInitable *ret;\n'
1232                      '  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'
1233                      '  if (ret != NULL)\n'
1234                      '    return %s%s (ret);\n'
1235                      '  else\n'
1236                      '    return NULL;\n'
1237                      '}\n'
1238                      '\n'
1239                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
1240         self.c.write('\n')
1241         self.c.write('void\n'
1242                      '%s_proxy_new_for_bus (\n'
1243                      '    GBusType             bus_type,\n'
1244                      '    GDBusProxyFlags      flags,\n'
1245                      '    const gchar         *name,\n'
1246                      '    const gchar         *object_path,\n'
1247                      '    GCancellable        *cancellable,\n'
1248                      '    GAsyncReadyCallback  callback,\n'
1249                      '    gpointer             user_data)\n'
1250                      '{\n'
1251                      '  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'
1252                      '}\n'
1253                      '\n'
1254                      %(i.name_lower, i.ns_upper, i.name_upper, i.name))
1255         self.c.write('%s *\n'
1256                      '%s_proxy_new_for_bus_finish (\n'
1257                      '    GAsyncResult        *res,\n'
1258                      '    GError             **error)\n'
1259                      '{\n'
1260                      '  GObject *ret;\n'
1261                      '  GObject *source_object;\n'
1262                      '  source_object = g_async_result_get_source_object (res);\n'
1263                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
1264                      '  g_object_unref (source_object);\n'
1265                      '  if (ret != NULL)\n'
1266                      '    return %s%s (ret);\n'
1267                      '  else\n'
1268                      '    return NULL;\n'
1269                      '}\n'
1270                      '\n'
1271                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper))
1272         self.c.write('%s *\n'
1273                      '%s_proxy_new_for_bus_sync (\n'
1274                      '    GBusType             bus_type,\n'
1275                      '    GDBusProxyFlags      flags,\n'
1276                      '    const gchar         *name,\n'
1277                      '    const gchar         *object_path,\n'
1278                      '    GCancellable        *cancellable,\n'
1279                      '    GError             **error)\n'
1280                      '{\n'
1281                      '  GInitable *ret;\n'
1282                      '  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'
1283                      '  if (ret != NULL)\n'
1284                      '    return %s%s (ret);\n'
1285                      '  else\n'
1286                      '    return NULL;\n'
1287                      '}\n'
1288                      '\n'
1289                      %(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.name, i.ns_upper, i.name_upper))
1290         self.c.write('\n')
1291
1292     # ---------------------------------------------------------------------------------------------------
1293
1294     def generate_stub(self, i):
1295         # class boilerplate
1296         self.c.write('/* ------------------------------------------------------------------------ */\n'
1297                      '\n')
1298
1299         self.c.write('struct _%sStubPrivate\n'
1300                      '{\n'
1301                      '  GValueArray *properties;\n'
1302                      '  GList *changed_properties;\n'
1303                      '  GSource *changed_properties_idle_source;\n'
1304                      '  GMainContext *context;\n'
1305                      '};\n'
1306                      '\n'%i.camel_name)
1307
1308         self.c.write('static void\n'
1309                      '_%s_stub_handle_method_call (\n'
1310                      '  GDBusConnection *connection,\n'
1311                      '  const gchar *sender,\n'
1312                      '  const gchar *object_path,\n'
1313                      '  const gchar *interface_name,\n'
1314                      '  const gchar *method_name,\n'
1315                      '  GVariant *parameters,\n'
1316                      '  GDBusMethodInvocation *invocation,\n'
1317                      '  gpointer user_data)\n'
1318                      '{\n'
1319                      '  %sStub *stub = %s%s_STUB (user_data);\n'
1320                      '  _ExtendedGDBusMethodInfo *info;\n'
1321                      '  GVariantIter iter;\n'
1322                      '  GVariant *child;\n'
1323                      '  GValue *paramv;\n'
1324                      '  guint num_params;\n'
1325                      '  guint n;\n'
1326                      '  guint signal_id;\n'
1327                      '  GValue return_value = {0};\n'
1328                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1329         self.c.write('  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);\n'
1330                      '  g_assert (info != NULL);\n'
1331                      %())
1332         self.c.write ('  num_params = g_variant_n_children (parameters);\n'
1333                       '  paramv = g_new0 (GValue, num_params + 2);\n'
1334                       '  g_value_init (&paramv[0], %sTYPE_%s);\n'
1335                       '  g_value_set_object (&paramv[0], stub);\n'
1336                       '  g_value_init (&paramv[1], G_TYPE_DBUS_METHOD_INVOCATION);\n'
1337                       '  g_value_set_object (&paramv[1], invocation);\n'
1338                       %(i.ns_upper, i.name_upper))
1339         self.c.write('  g_variant_iter_init (&iter, parameters);\n'
1340                      '  n = 2;\n'
1341                      '  while ((child = g_variant_iter_next_value (&iter)) != NULL)\n'
1342                      '    {\n'
1343                      '      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - 2];\n'
1344                      '      if (arg_info->use_gvariant)\n'
1345                      '        {\n'
1346                      '          g_value_init (&paramv[n], G_TYPE_VARIANT);\n'
1347                      '          g_value_set_variant (&paramv[n], child);\n'
1348                      '          n++;\n'
1349                      '        }\n'
1350                      '      else\n'
1351                      '        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);\n'
1352                      '      g_variant_unref (child);\n'
1353                      '    }\n'
1354                      )
1355         self.c.write('  signal_id = g_signal_lookup (info->signal_name, %sTYPE_%s);\n'
1356                      %(i.ns_upper, i.name_upper))
1357         self.c.write('  g_value_init (&return_value, G_TYPE_BOOLEAN);\n'
1358                      '  g_signal_emitv (paramv, signal_id, 0, &return_value);\n'
1359                      '  if (!g_value_get_boolean (&return_value))\n'
1360                      '    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'
1361                      '  g_value_unset (&return_value);\n'
1362                      )
1363         self.c.write('  for (n = 0; n < num_params + 2; n++)\n'
1364                      '    g_value_unset (&paramv[n]);\n'
1365                      '  g_free (paramv);\n')
1366         self.c.write('}\n'
1367                      '\n')
1368
1369         self.c.write('static GVariant *\n'
1370                      '_%s_stub_handle_get_property (\n'
1371                      '  GDBusConnection *connection,\n'
1372                      '  const gchar *sender,\n'
1373                      '  const gchar *object_path,\n'
1374                      '  const gchar *interface_name,\n'
1375                      '  const gchar *property_name,\n'
1376                      '  GError **error,\n'
1377                      '  gpointer user_data)\n'
1378                      '{\n'
1379                      '  %sStub *stub = %s%s_STUB (user_data);\n'
1380                      '  GValue value = {0};\n'
1381                      '  GParamSpec *pspec;\n'
1382                      '  _ExtendedGDBusPropertyInfo *info;\n'
1383                      '  GVariant *ret;\n'
1384                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1385         self.c.write('  ret = NULL;\n'
1386                      '  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, property_name);\n'
1387                      '  g_assert (info != NULL);\n'
1388                      '  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (stub), info->hyphen_name);\n'
1389                      '  if (pspec == NULL)\n'
1390                      '    {\n'
1391                      '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
1392                      '    }\n'
1393                      '  else\n'
1394                      '    {\n'
1395                      '      g_value_init (&value, pspec->value_type);\n'
1396                      '      g_object_get_property (G_OBJECT (stub), info->hyphen_name, &value);\n'
1397                      '      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));\n'
1398                      '      g_value_unset (&value);\n'
1399                      '    }\n'
1400                      '  return ret;\n'
1401                      '}\n'
1402                      '\n'
1403                      %(i.name_lower))
1404
1405         self.c.write('static gboolean\n'
1406                      '_%s_stub_handle_set_property (\n'
1407                      '  GDBusConnection *connection,\n'
1408                      '  const gchar *sender,\n'
1409                      '  const gchar *object_path,\n'
1410                      '  const gchar *interface_name,\n'
1411                      '  const gchar *property_name,\n'
1412                      '  GVariant *variant,\n'
1413                      '  GError **error,\n'
1414                      '  gpointer user_data)\n'
1415                      '{\n'
1416                      '  %sStub *stub = %s%s_STUB (user_data);\n'
1417                      '  GValue value = {0};\n'
1418                      '  GParamSpec *pspec;\n'
1419                      '  _ExtendedGDBusPropertyInfo *info;\n'
1420                      '  gboolean ret;\n'
1421                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1422         self.c.write('  ret = FALSE;\n'
1423                      '  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_%s_interface_info, property_name);\n'
1424                      '  g_assert (info != NULL);\n'
1425                      '  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (stub), info->hyphen_name);\n'
1426                      '  if (pspec == NULL)\n'
1427                      '    {\n'
1428                      '      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %%s", property_name);\n'
1429                      '    }\n'
1430                      '  else\n'
1431                      '    {\n'
1432                      '      if (info->use_gvariant)\n'
1433                      '        g_value_set_variant (&value, variant);\n'
1434                      '      else\n'
1435                      '        g_dbus_gvariant_to_gvalue (variant, &value);\n'
1436                      '      g_object_set_property (G_OBJECT (stub), info->hyphen_name, &value);\n'
1437                      '      g_value_unset (&value);\n'
1438                      '      ret = TRUE;\n'
1439                      '    }\n'
1440                      '  return ret;\n'
1441                      '}\n'
1442                      '\n'
1443                      %(i.name_lower))
1444
1445
1446         self.c.write('static const GDBusInterfaceVTable _%s_stub_vtable =\n'
1447                      '{\n'
1448                      '  _%s_stub_handle_method_call,\n'
1449                      '  _%s_stub_handle_get_property,\n'
1450                      '  _%s_stub_handle_set_property\n'
1451                      '};\n'
1452                      '\n'%(i.name_lower, i.name_lower, i.name_lower, i.name_lower))
1453
1454         self.c.write('static GDBusInterfaceInfo *\n'
1455                      '%s_stub_dbus_interface_get_info (GDBusInterfaceStub *stub)\n'
1456                      '{\n'
1457                      '  return %s_interface_info ();\n'
1458                      %(i.name_lower, i.name_lower))
1459         self.c.write('}\n'
1460                      '\n')
1461
1462         self.c.write('static GDBusInterfaceVTable *\n'
1463                      '%s_stub_dbus_interface_get_vtable (GDBusInterfaceStub *stub)\n'
1464                      '{\n'
1465                      '  return (GDBusInterfaceVTable *) &_%s_stub_vtable;\n'
1466                      %(i.name_lower, i.name_lower))
1467         self.c.write('}\n'
1468                      '\n')
1469
1470         self.c.write('static GVariant *\n'
1471                      '%s_stub_dbus_interface_get_properties (GDBusInterfaceStub *_stub)\n'
1472                      '{\n'
1473                      '  %sStub *stub = %s%s_STUB (_stub);\n'
1474                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1475         self.c.write('\n'
1476                      '  GVariantBuilder builder;\n'
1477                      '  guint n;\n'
1478                      '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
1479                      '  if (_%s_interface_info.properties == NULL)\n'
1480                      '    goto out;\n'
1481                      '  for (n = 0; _%s_interface_info.properties[n] != NULL; n++)\n'
1482                      '    {\n'
1483                      '      GDBusPropertyInfo *info = _%s_interface_info.properties[n];\n'
1484                      '      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)\n'
1485                      '        {\n'
1486                      '          GVariant *value;\n'
1487                      '          value = _%s_stub_handle_get_property (g_dbus_interface_stub_get_connection (G_DBUS_INTERFACE_STUB (stub)), NULL, g_dbus_interface_stub_get_object_path (G_DBUS_INTERFACE_STUB (stub)), "%s", info->name, NULL, stub);\n'
1488                      '          if (value != NULL)\n'
1489                      '            {\n'
1490                      '              if (g_variant_is_floating (value))\n'
1491                      '                g_variant_ref_sink (value);\n'
1492                      '              g_variant_builder_add (&builder, "{sv}", info->name, value);\n'
1493                      '              g_variant_unref (value);\n'
1494                      '            }\n'
1495                      '        }\n'
1496                      '    }\n'
1497                      'out:\n'
1498                      '  return g_variant_builder_end (&builder);\n'
1499                      '}\n'
1500                      '\n'
1501                      %(i.name_lower, i.name_lower, i.name_lower, i.name_lower, i.name))
1502
1503         if len(i.properties) > 0:
1504             self.c.write('static gboolean _%s_emit_changed (gpointer user_data);\n'
1505                          '\n'
1506                          %(i.name_lower))
1507
1508         self.c.write('static void\n'
1509                      '%s_stub_dbus_interface_flush (GDBusInterfaceStub *_stub)\n'
1510                      '{\n'
1511                      %(i.name_lower))
1512         if len(i.properties) > 0:
1513             self.c.write('  %sStub *stub = %s%s_STUB (_stub);\n'
1514                          '  if (stub->priv->changed_properties_idle_source != NULL)\n'
1515                          '    {\n'
1516                          '      g_source_destroy (stub->priv->changed_properties_idle_source);\n'
1517                          '      stub->priv->changed_properties_idle_source = NULL;\n'
1518                          '      _%s_emit_changed (stub);\n'
1519                          '    }\n'
1520                          %(i.camel_name, i.ns_upper, i.name_upper, i.name_lower))
1521         self.c.write('}\n'
1522                      '\n')
1523
1524         for s in i.signals:
1525             self.c.write('static void\n'
1526                          '_%s_on_signal_%s (\n'
1527                          '    %s *object'%(i.name_lower, s.name_lower, i.camel_name))
1528             for a in s.args:
1529                 self.c.write(',\n    %s%s'%(a.ctype_in, a.name))
1530             self.c.write(')\n'
1531                          '{\n'
1532                          '  %sStub *stub = %s%s_STUB (object);\n'
1533                          '  GDBusConnection *connection = g_dbus_interface_stub_get_connection (G_DBUS_INTERFACE_STUB (stub));\n'
1534                          %(i.camel_name, i.ns_upper, i.name_upper))
1535             self.c.write('  if (connection == NULL)\n'
1536                          '    return;\n'
1537                          '  g_dbus_connection_emit_signal (connection,\n'
1538                          '    NULL, g_dbus_interface_stub_get_object_path (G_DBUS_INTERFACE_STUB (stub)), "%s", "%s",\n'
1539                          '    g_variant_new ("('
1540                          %(i.name, s.name))
1541             for a in s.args:
1542                 self.c.write('%s'%(a.format_in))
1543             self.c.write(')"')
1544             for a in s.args:
1545                 self.c.write(',\n                   %s'%(a.name))
1546             self.c.write('), NULL);\n')
1547             self.c.write('}\n'
1548                          '\n')
1549
1550         self.c.write('static void\n'
1551                      '%s_stub_iface_init (%sIface *iface)\n'
1552                      '{\n'
1553                      %(i.name_lower, i.camel_name))
1554         for s in i.signals:
1555             self.c.write('  iface->%s = _%s_on_signal_%s;\n'
1556                          %(s.name_lower, i.name_lower, s.name_lower))
1557         self.c.write('}\n'
1558                      '\n')
1559         self.c.write('#define %s_stub_get_type %s_stub_get_gtype\n'%(i.name_lower, i.name_lower))
1560         self.c.write('G_DEFINE_TYPE_WITH_CODE (%sStub, %s_stub, G_TYPE_DBUS_INTERFACE_STUB,\n'%(i.camel_name, i.name_lower))
1561         self.c.write('                         G_IMPLEMENT_INTERFACE (%sTYPE_%s, %s_stub_iface_init));\n'%(i.ns_upper, i.name_upper, i.name_lower))
1562         self.c.write('#undef %s_stub_get_type\n'
1563                      '\n'%(i.name_lower))
1564
1565         # finalize
1566         self.c.write('static void\n'
1567                      '%s_stub_finalize (GObject *object)\n'
1568                      '{\n'%(i.name_lower))
1569         self.c.write('  %sStub *stub = %s%s_STUB (object);\n'%(i.camel_name, i.ns_upper, i.name_upper))
1570         if len(i.properties) > 0:
1571             self.c.write('  g_value_array_free (stub->priv->properties);\n')
1572         self.c.write('  g_list_foreach (stub->priv->changed_properties, (GFunc) _changed_property_free, NULL);\n')
1573         self.c.write('  g_list_free (stub->priv->changed_properties);\n')
1574         self.c.write('  if (stub->priv->changed_properties_idle_source != NULL)\n')
1575         self.c.write('    g_source_destroy (stub->priv->changed_properties_idle_source);\n')
1576         self.c.write('  if (stub->priv->context != NULL)\n')
1577         self.c.write('    g_main_context_unref (stub->priv->context);\n')
1578         self.c.write('  G_OBJECT_CLASS (%s_stub_parent_class)->finalize (object);\n'
1579                      '}\n'
1580                      '\n'%(i.name_lower))
1581
1582         # property accessors (TODO: generate PropertiesChanged signals in setter)
1583         self.c.write('static void\n'
1584                      '%s_stub_get_property (GObject      *object,\n'
1585                      '  guint         prop_id,\n'
1586                      '  GValue       *value,\n'
1587                      '  GParamSpec   *pspec)\n'
1588                      '{\n'%(i.name_lower))
1589         self.c.write('  %sStub *stub = %s%s_STUB (object);\n'
1590                      '  g_assert (prop_id - 1 >= 0 && prop_id - 1 < %d);\n'
1591                      '  g_value_copy (&stub->priv->properties->values[prop_id - 1], value);\n'
1592                      %(i.camel_name, i.ns_upper, i.name_upper, len(i.properties)))
1593         self.c.write('}\n'
1594                      '\n')
1595         if len(i.properties) > 0:
1596             self.c.write('static gboolean\n'
1597                          '_%s_emit_changed (gpointer user_data)\n'
1598                          '{\n'
1599                          '  %sStub *stub = %s%s_STUB (user_data);\n'
1600                          %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper))
1601             self.c.write('  GList *l;\n'
1602                          '  GVariantBuilder builder;\n'
1603                          '  GVariantBuilder invalidated_builder;\n'
1604                          '  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));\n'
1605                          '  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));\n'
1606                          '  for (l = stub->priv->changed_properties; l != NULL; l = l->next)\n'
1607                          '    {\n'
1608                          '      ChangedProperty *cp = l->data;\n'
1609                          '      GVariant *variant;\n'
1610                          '      variant = g_dbus_gvalue_to_gvariant (&cp->value, G_VARIANT_TYPE (cp->info->parent_struct.signature));\n'
1611                          '      g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);\n'
1612                          '      g_variant_unref (variant);\n'
1613                          '    }\n'
1614                          '  g_dbus_connection_emit_signal (g_dbus_interface_stub_get_connection (G_DBUS_INTERFACE_STUB (stub)),\n'
1615                          '                                 NULL, g_dbus_interface_stub_get_object_path (G_DBUS_INTERFACE_STUB (stub)),\n'
1616                          '                                 "org.freedesktop.DBus.Properties",\n'
1617                          '                                 "PropertiesChanged",\n'
1618                          '                                 g_variant_new ("(sa{sv}as)",\n'
1619                          '                                                "%s",\n'
1620                          '                                                &builder, &invalidated_builder),\n'
1621                          '                                 NULL);\n'
1622                          %(i.name))
1623             self.c.write('  g_list_foreach (stub->priv->changed_properties, (GFunc) _changed_property_free, NULL);\n')
1624             self.c.write('  g_list_free (stub->priv->changed_properties);\n')
1625             self.c.write('  stub->priv->changed_properties = NULL;\n')
1626             self.c.write('  stub->priv->changed_properties_idle_source = NULL;\n')
1627             self.c.write('  return FALSE;\n'
1628                          '}\n'
1629                          '\n')
1630             # if property is already scheduled then re-use entry
1631             self.c.write('static void\n'
1632                          '_%s_schedule_emit_changed (%sStub *stub, const _ExtendedGDBusPropertyInfo *info, GParamSpec *pspec, const GValue *value)\n'
1633                          '{\n'
1634                          '  ChangedProperty *cp;\n'
1635                          '  GList *l;\n'
1636                          '  cp = NULL;\n'
1637                          '  for (l = stub->priv->changed_properties; l != NULL; l = l->next)\n'
1638                          '    {\n'
1639                          '      ChangedProperty *i_cp = l->data;\n'
1640                          '      if (i_cp->info == info)\n'
1641                          '        {\n'
1642                          '          cp = i_cp;\n'
1643                          '          g_value_unset (&cp->value);\n'
1644                          '          break;\n'
1645                          '        }\n'
1646                          '    }\n'
1647                          '  if (cp == NULL)\n'
1648                          '    {\n'
1649                          '      cp = g_new0 (ChangedProperty, 1);\n'
1650                          '      cp->pspec = pspec;\n'
1651                          '      cp->info = info;\n'
1652                          '      stub->priv->changed_properties = g_list_prepend (stub->priv->changed_properties, cp);\n'
1653                          '    }\n'
1654                          '  g_value_init (&cp->value, G_VALUE_TYPE (value));\n'
1655                          '  g_value_copy (value, &cp->value);\n'
1656                          '  if (stub->priv->changed_properties_idle_source == NULL)\n'
1657                          '    {\n'
1658                          '      stub->priv->changed_properties_idle_source = g_idle_source_new ();\n'
1659                          '      g_source_set_priority (stub->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);\n'
1660                          '      g_source_set_callback (stub->priv->changed_properties_idle_source, _%s_emit_changed, g_object_ref (stub), (GDestroyNotify) g_object_unref);\n'
1661                          '      g_source_attach (stub->priv->changed_properties_idle_source, stub->priv->context);\n'
1662                          '      g_source_unref (stub->priv->changed_properties_idle_source);\n'
1663                          '    }\n'
1664                          '}\n'
1665                          '\n'
1666                          %(i.name_lower, i.camel_name, i.name_lower))
1667         self.c.write('static void\n'
1668                      '%s_stub_set_property (GObject      *object,\n'
1669                      '  guint         prop_id,\n'
1670                      '  const GValue *value,\n'
1671                      '  GParamSpec   *pspec)\n'
1672                      '{\n'%(i.name_lower))
1673         if len(i.properties) > 0:
1674             self.c.write('  %sStub *stub = %s%s_STUB (object);\n'
1675                          '  g_assert (prop_id - 1 >= 0 && prop_id - 1 < %d);\n'
1676                          '  if (!_g_value_equal (value, &stub->priv->properties->values[prop_id - 1]))\n'
1677                          '    {\n'
1678                          '      g_value_copy (value, &stub->priv->properties->values[prop_id - 1]);\n'
1679                          '      g_object_notify_by_pspec (object, pspec);\n'
1680                          '      if (g_dbus_interface_stub_get_connection (G_DBUS_INTERFACE_STUB (stub)) != NULL)\n'
1681                          '        _%s_schedule_emit_changed (stub, _%s_property_info_pointers[prop_id - 1], pspec, value);\n'
1682                          '    }\n'
1683                          %(i.camel_name, i.ns_upper, i.name_upper, len(i.properties), i.name_lower, i.name_lower))
1684         self.c.write('}\n'
1685                      '\n')
1686
1687         self.c.write('static void\n'
1688                      '%s_stub_init (%sStub *stub)\n'
1689                      '{\n'
1690                      '  stub->priv = G_TYPE_INSTANCE_GET_PRIVATE (stub, %sTYPE_%s_STUB, %sStubPrivate);\n'
1691                      %(i.name_lower, i.camel_name, i.ns_upper, i.name_upper, i.camel_name))
1692         self.c.write('  stub->priv->context = g_main_context_get_thread_default ();\n')
1693         self.c.write('  if (stub->priv->context != NULL)\n')
1694         self.c.write('    g_main_context_ref (stub->priv->context);\n')
1695         if len(i.properties) > 0:
1696             self.c.write('  stub->priv->properties = g_value_array_new (%d);\n'%(len(i.properties)))
1697             n = 0
1698             for p in i.properties:
1699                 self.c.write('  g_value_array_append (stub->priv->properties, NULL);\n')
1700                 self.c.write('  g_value_init (&stub->priv->properties->values[%d], %s);\n'%(n, p.arg.gtype))
1701                 n += 1
1702         self.c.write('}\n'
1703                      '\n')
1704         self.c.write('static void\n'
1705                      '%s_stub_class_init (%sStubClass *klass)\n'
1706                      '{\n'
1707                      '  GObjectClass *gobject_class;\n'
1708                      '  GDBusInterfaceStubClass *stub_class;\n'
1709                      '\n'
1710                      '  g_type_class_add_private (klass, sizeof (%sStubPrivate));\n'
1711                      '\n'
1712                      '  gobject_class = G_OBJECT_CLASS (klass);\n'
1713                      '  gobject_class->finalize = %s_stub_finalize;\n'
1714                      '  gobject_class->get_property = %s_stub_get_property;\n'
1715                      '  gobject_class->set_property = %s_stub_set_property;\n'
1716                      '\n'%(i.name_lower, i.camel_name, i.camel_name, i.name_lower, i.name_lower, i.name_lower))
1717         if len(i.properties) > 0:
1718             self.c.write('\n'
1719                          '  %s_override_properties (gobject_class, 1);\n'%(i.name_lower))
1720         self.c.write('\n'
1721                      '  stub_class = G_DBUS_INTERFACE_STUB_CLASS (klass);\n');
1722         self.c.write('  stub_class->get_info = %s_stub_dbus_interface_get_info;\n'%(i.name_lower))
1723         self.c.write('  stub_class->get_properties = %s_stub_dbus_interface_get_properties;\n'%(i.name_lower))
1724         self.c.write('  stub_class->flush = %s_stub_dbus_interface_flush;\n'%(i.name_lower))
1725         self.c.write('  stub_class->get_vtable = %s_stub_dbus_interface_get_vtable;\n'%(i.name_lower))
1726         self.c.write('}\n'
1727                      '\n')
1728
1729         # constructors
1730         self.c.write('%s *\n'
1731                      '%s_stub_new (void)\n'
1732                      '{\n'
1733                      '  return %s%s (g_object_new (%sTYPE_%s_STUB, NULL));\n'
1734                      '}\n'
1735                      '\n'%(i.camel_name, i.name_lower, i.ns_upper, i.name_upper, i.ns_upper, i.name_upper))
1736
1737     # ---------------------------------------------------------------------------------------------------
1738
1739     # From https://bugzilla.gnome.org/show_bug.cgi?id=567087
1740     #
1741     # See https://bugzilla.gnome.org/show_bug.cgi?id=401080 for the request
1742     # to include this in libgobject
1743     #
1744     def generate_generic_marshaller(self):
1745         self.c.write('#include <ffi.h>\n'
1746                      ''
1747                      'static ffi_type *\n'
1748                      'value_to_ffi_type (const GValue *gvalue, gpointer *value)\n'
1749                      '{\n'
1750                      '  ffi_type *rettype = NULL;\n'
1751                      '  GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));\n'
1752                      '  g_assert (type != G_TYPE_INVALID);\n'
1753                      '\n'
1754                      '  switch (type)\n'
1755                      '    {\n'
1756                      '    case G_TYPE_BOOLEAN:\n'
1757                      '    case G_TYPE_CHAR:\n'
1758                      '    case G_TYPE_INT:\n'
1759                      '      rettype = &ffi_type_sint;\n'
1760                      '      *value = (gpointer)&(gvalue->data[0].v_int);\n'
1761                      '      break;\n'
1762                      '    case G_TYPE_UCHAR:\n'
1763                      '    case G_TYPE_UINT:\n'
1764                      '      rettype = &ffi_type_uint;\n'
1765                      '      *value = (gpointer)&(gvalue->data[0].v_uint);\n'
1766                      '      break;\n'
1767                      '    case G_TYPE_STRING:\n'
1768                      '    case G_TYPE_OBJECT:\n'
1769                      '    case G_TYPE_BOXED:\n'
1770                      '    case G_TYPE_POINTER:\n'
1771                      '    case G_TYPE_INTERFACE:\n'
1772                      '    case G_TYPE_VARIANT:\n'
1773                      '      rettype = &ffi_type_pointer;\n'
1774                      '      *value = (gpointer)&(gvalue->data[0].v_pointer);\n'
1775                      '      break;\n'
1776                      '    case G_TYPE_FLOAT:\n'
1777                      '      rettype = &ffi_type_float;\n'
1778                      '      *value = (gpointer)&(gvalue->data[0].v_float);\n'
1779                      '      break;\n'
1780                      '    case G_TYPE_DOUBLE:\n'
1781                      '      rettype = &ffi_type_double;\n'
1782                      '      *value = (gpointer)&(gvalue->data[0].v_double);\n'
1783                      '      break;\n'
1784                      '    case G_TYPE_LONG:\n'
1785                      '      rettype = &ffi_type_slong;\n'
1786                      '      *value = (gpointer)&(gvalue->data[0].v_long);\n'
1787                      '      break;\n'
1788                      '    case G_TYPE_ULONG:\n'
1789                      '      rettype = &ffi_type_ulong;\n'
1790                      '      *value = (gpointer)&(gvalue->data[0].v_ulong);\n'
1791                      '      break;\n'
1792                      '    case G_TYPE_INT64:\n'
1793                      '      rettype = &ffi_type_sint64;\n'
1794                      '      *value = (gpointer)&(gvalue->data[0].v_int64);\n'
1795                      '      break;\n'
1796                      '    case G_TYPE_UINT64:\n'
1797                      '      rettype = &ffi_type_uint64;\n'
1798                      '      *value = (gpointer)&(gvalue->data[0].v_uint64);\n'
1799                      '      break;\n'
1800                      '    default:\n'
1801                      '      rettype = &ffi_type_pointer;\n'
1802                      '      *value = NULL;\n'
1803                      '      g_warning ("value_to_ffi_type: Unsupported fundamental type: %s", g_type_name (type));\n'
1804                      '      break;\n'
1805                      '    }\n'
1806                      '  return rettype;\n'
1807                      '}\n'
1808                      '\n'
1809                      'static void\n'
1810                      'value_from_ffi_type (GValue *gvalue, gpointer *value)\n'
1811                      '{\n'
1812                      '  switch (g_type_fundamental (G_VALUE_TYPE (gvalue)))\n'
1813                      '    {\n'
1814                      '    case G_TYPE_INT:\n'
1815                      '      g_value_set_int (gvalue, *(gint*)value);\n'
1816                      '      break;\n'
1817                      '    case G_TYPE_FLOAT:\n'
1818                      '      g_value_set_float (gvalue, *(gfloat*)value);\n'
1819                      '      break;\n'
1820                      '    case G_TYPE_DOUBLE:\n'
1821                      '      g_value_set_double (gvalue, *(gdouble*)value);\n'
1822                      '      break;\n'
1823                      '    case G_TYPE_BOOLEAN:\n'
1824                      '      g_value_set_boolean (gvalue, *(gboolean*)value);\n'
1825                      '      break;\n'
1826                      '    case G_TYPE_STRING:\n'
1827                      '      g_value_set_string (gvalue, *(gchar**)value);\n'
1828                      '      break;\n'
1829                      '    case G_TYPE_CHAR:\n'
1830                      '      g_value_set_char (gvalue, *(gchar*)value);\n'
1831                      '      break;\n'
1832                      '    case G_TYPE_UCHAR:\n'
1833                      '      g_value_set_uchar (gvalue, *(guchar*)value);\n'
1834                      '      break;\n'
1835                      '    case G_TYPE_UINT:\n'
1836                      '      g_value_set_uint (gvalue, *(guint*)value);\n'
1837                      '      break;\n'
1838                      '    case G_TYPE_POINTER:\n'
1839                      '      g_value_set_pointer (gvalue, *(gpointer*)value);\n'
1840                      '      break;\n'
1841                      '    case G_TYPE_LONG:\n'
1842                      '      g_value_set_long (gvalue, *(glong*)value);\n'
1843                      '      break;\n'
1844                      '    case G_TYPE_ULONG:\n'
1845                      '      g_value_set_ulong (gvalue, *(gulong*)value);\n'
1846                      '      break;\n'
1847                      '    case G_TYPE_INT64:\n'
1848                      '      g_value_set_int64 (gvalue, *(gint64*)value);\n'
1849                      '      break;\n'
1850                      '    case G_TYPE_UINT64:\n'
1851                      '      g_value_set_uint64 (gvalue, *(guint64*)value);\n'
1852                      '      break;\n'
1853                      '    case G_TYPE_BOXED:\n'
1854                      '      g_value_set_boxed (gvalue, *(gpointer*)value);\n'
1855                      '      break;\n'
1856                      '    default:\n'
1857                      '      g_warning ("value_from_ffi_type: Unsupported fundamental type: %s",\n'
1858                      '                g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue))));\n'
1859                      '    }\n'
1860                      '}\n'
1861                      '\n'
1862                      'static void\n'
1863                      '_cclosure_marshal_generic (GClosure *closure,\n'
1864                      '                             GValue *return_gvalue,\n'
1865                      '                             guint n_param_values,\n'
1866                      '                             const GValue *param_values,\n'
1867                      '                             gpointer invocation_hint,\n'
1868                      '                             gpointer marshal_data)\n'
1869                      '{\n'
1870                      '  ffi_type *rtype;\n'
1871                      '  void *rvalue;\n'
1872                      '  int n_args;\n'
1873                      '  ffi_type **atypes;\n'
1874                      '  void **args;\n'
1875                      '  int i;\n'
1876                      '  ffi_cif cif;\n'
1877                      '  GCClosure *cc = (GCClosure*) closure;\n'
1878                      '\n'
1879                      '  if (return_gvalue && G_VALUE_TYPE (return_gvalue)) \n'
1880                      '    {\n'
1881                      '      rtype = value_to_ffi_type (return_gvalue, &rvalue);\n'
1882                      '    }\n'
1883                      '  else \n'
1884                      '    {\n'
1885                      '      rtype = &ffi_type_void;\n'
1886                      '    }\n'
1887                      '\n'
1888                      '  rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg)));\n'
1889                      '  \n'
1890                      '  n_args = n_param_values + 1;\n'
1891                      '  atypes = g_alloca (sizeof (ffi_type *) * n_args);\n'
1892                      '  args =  g_alloca (sizeof (gpointer) * n_args);\n'
1893                      '\n'
1894                      '  if (G_CCLOSURE_SWAP_DATA (closure))\n'
1895                      '    {\n'
1896                      '      atypes[n_args-1] = value_to_ffi_type (param_values + 0,  \n'
1897                      '                                            &args[n_args-1]);\n'
1898                      '      atypes[0] = &ffi_type_pointer;\n'
1899                      '      args[0] = &closure->data;\n'
1900                      '    }\n'
1901                      '  else\n'
1902                      '    {\n'
1903                      '      atypes[0] = value_to_ffi_type (param_values + 0, &args[0]);\n'
1904                      '      atypes[n_args-1] = &ffi_type_pointer;\n'
1905                      '      args[n_args-1] = &closure->data;\n'
1906                      '    }\n'
1907                      '\n'
1908                      '  for (i = 1; i < n_args - 1; i++)\n'
1909                      '    atypes[i] = value_to_ffi_type (param_values + i, &args[i]);\n'
1910                      '\n'
1911                      '  if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)\n'
1912                      '    return;\n'
1913                      '\n'
1914                      '  ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args);\n'
1915                      '\n'
1916                      '  if (return_gvalue && G_VALUE_TYPE (return_gvalue))\n'
1917                      '    value_from_ffi_type (return_gvalue, rvalue);\n'
1918                      '}\n'
1919                      '\n')
1920
1921     # ---------------------------------------------------------------------------------------------------
1922
1923     def generate_object_manager_client(self):
1924         self.c.write('/* ------------------------------------------------------------------------\n'
1925                      ' * Code for proxy manager\n'
1926                      ' * ------------------------------------------------------------------------\n'
1927                      ' */\n'
1928                      '\n')
1929
1930         # class boilerplate
1931         self.c.write('/* ------------------------------------------------------------------------ */\n'
1932                      '\n')
1933         self.c.write('#define %sobject_manager_client_get_type %sobject_manager_client_get_gtype\n'%(self.ns_lower, self.ns_lower))
1934         self.c.write('G_DEFINE_TYPE (%sObjectManagerClient, %sobject_manager_client, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT);\n'%(self.namespace, self.ns_lower))
1935         self.c.write('#undef %sobject_manager_client_get_type\n'
1936                      '\n'%(self.ns_lower))
1937
1938         # class boilerplate
1939         self.c.write('static void\n'
1940                      '%sobject_manager_client_init (%sObjectManagerClient *manager)\n'
1941                      '{\n'
1942                      '}\n'
1943                      '\n'%(self.ns_lower, self.namespace))
1944         self.c.write('static void\n'
1945                      '%sobject_manager_client_class_init (%sObjectManagerClientClass *klass)\n'
1946                      '{\n'
1947                      '}\n'
1948                      '\n'%(self.ns_lower, self.namespace))
1949
1950         self.c.write('static GType\n'
1951                      '_%sobject_manager_client_get_proxy_type_func (GDBusObjectManagerClient *manager, const gchar *object_path, const gchar *interface_name, gpointer user_data)\n'
1952                      '{\n'
1953                      %(self.ns_lower))
1954         self.c.write('  static gsize once_init_value = 0;\n'
1955                      '  static GHashTable *lookup_hash;\n'
1956                      '  GType ret;\n'
1957                      '\n'
1958                      '  if (g_once_init_enter (&once_init_value))\n'
1959                      '    {\n'
1960                      '      lookup_hash = g_hash_table_new (g_str_hash, g_str_equal);\n')
1961         for i in self.ifaces:
1962             self.c.write('      g_hash_table_insert (lookup_hash, "%s", GSIZE_TO_POINTER (%sTYPE_%s_PROXY));\n'
1963                          %(i.name, i.ns_upper, i.name_upper))
1964         self.c.write('      g_once_init_leave (&once_init_value, 1);\n'
1965                      '    }\n')
1966         self.c.write('  ret = (GType) GPOINTER_TO_SIZE (g_hash_table_lookup (lookup_hash, interface_name));\n'
1967                      '  if (ret == (GType) 0)\n'
1968                      '    ret = G_TYPE_DBUS_PROXY;\n')
1969         self.c.write('  return ret;\n'
1970                      '}\n'
1971                      '\n')
1972
1973         self.c.write('GDBusProxyTypeFunc\n'
1974                      '%sobject_manager_client_get_proxy_type_func (void)\n'
1975                      '{\n'
1976                      '  return _%sobject_manager_client_get_proxy_type_func;\n'
1977                      '}\n'
1978                      '\n'
1979                      %(self.ns_lower, self.ns_lower))
1980
1981         # constructors
1982         self.c.write('void\n'
1983                      '%sobject_manager_client_new (\n'
1984                      '    GDBusConnection        *connection,\n'
1985                      '    GDBusObjectManagerClientFlags  flags,\n'
1986                      '    const gchar            *name,\n'
1987                      '    const gchar            *object_path,\n'
1988                      '    GCancellable           *cancellable,\n'
1989                      '    GAsyncReadyCallback     callback,\n'
1990                      '    gpointer                user_data)\n'
1991                      '{\n'
1992                      '  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_func, NULL);\n'
1993                      '}\n'
1994                      '\n'
1995                      %(self.ns_lower, self.ns_upper, self.ns_lower))
1996         self.c.write('GDBusObjectManager *\n'
1997                      '%sobject_manager_client_new_finish (\n'
1998                      '    GAsyncResult        *res,\n'
1999                      '    GError             **error)\n'
2000                      '{\n'
2001                      '  GObject *ret;\n'
2002                      '  GObject *source_object;\n'
2003                      '  source_object = g_async_result_get_source_object (res);\n'
2004                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
2005                      '  g_object_unref (source_object);\n'
2006                      '  if (ret != NULL)\n'
2007                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
2008                      '  else\n'
2009                      '    return NULL;\n'
2010                      '}\n'
2011                      '\n'
2012                      %(self.ns_lower))
2013         self.c.write('GDBusObjectManager *\n'
2014                      '%sobject_manager_client_new_sync (\n'
2015                      '    GDBusConnection        *connection,\n'
2016                      '    GDBusObjectManagerClientFlags  flags,\n'
2017                      '    const gchar            *name,\n'
2018                      '    const gchar            *object_path,\n'
2019                      '    GCancellable           *cancellable,\n'
2020                      '    GError                **error)\n'
2021                      '{\n'
2022                      '  GInitable *ret;\n'
2023                      '  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_func, NULL);\n'
2024                      '  if (ret != NULL)\n'
2025                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
2026                      '  else\n'
2027                      '    return NULL;\n'
2028                      '}\n'
2029                      '\n'
2030                      %(self.ns_lower, self.ns_upper, self.ns_lower))
2031         self.c.write('\n')
2032         self.c.write('void\n'
2033                      '%sobject_manager_client_new_for_bus (\n'
2034                      '    GBusType                bus_type,\n'
2035                      '    GDBusObjectManagerClientFlags  flags,\n'
2036                      '    const gchar            *name,\n'
2037                      '    const gchar            *object_path,\n'
2038                      '    GCancellable           *cancellable,\n'
2039                      '    GAsyncReadyCallback     callback,\n'
2040                      '    gpointer                user_data)\n'
2041                      '{\n'
2042                      '  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_func, NULL);\n'
2043                      '}\n'
2044                      '\n'
2045                      %(self.ns_lower, self.ns_upper, self.ns_lower))
2046         self.c.write('GDBusObjectManager *\n'
2047                      '%sobject_manager_client_new_for_bus_finish (\n'
2048                      '    GAsyncResult        *res,\n'
2049                      '    GError             **error)\n'
2050                      '{\n'
2051                      '  GObject *ret;\n'
2052                      '  GObject *source_object;\n'
2053                      '  source_object = g_async_result_get_source_object (res);\n'
2054                      '  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);\n'
2055                      '  g_object_unref (source_object);\n'
2056                      '  if (ret != NULL)\n'
2057                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
2058                      '  else\n'
2059                      '    return NULL;\n'
2060                      '}\n'
2061                      '\n'
2062                      %(self.ns_lower))
2063         self.c.write('GDBusObjectManager *\n'
2064                      '%sobject_manager_client_new_for_bus_sync (\n'
2065                      '    GBusType                bus_type,\n'
2066                      '    GDBusObjectManagerClientFlags  flags,\n'
2067                      '    const gchar            *name,\n'
2068                      '    const gchar            *object_path,\n'
2069                      '    GCancellable           *cancellable,\n'
2070                      '    GError                **error)\n'
2071                      '{\n'
2072                      '  GInitable *ret;\n'
2073                      '  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_func, NULL);\n'
2074                      '  if (ret != NULL)\n'
2075                      '    return G_DBUS_OBJECT_MANAGER (ret);\n'
2076                      '  else\n'
2077                      '    return NULL;\n'
2078                      '}\n'
2079                      '\n'
2080                      %(self.ns_lower, self.ns_upper, self.ns_lower))
2081         self.c.write('\n')
2082
2083     # ---------------------------------------------------------------------------------------------------
2084
2085     def generate(self):
2086         self.generate_intro()
2087         self.generate_generic_marshaller()
2088         self.declare_types()
2089         for i in self.ifaces:
2090             self.c.write('/* ------------------------------------------------------------------------\n'
2091                          ' * Code for interface %s\n'
2092                          ' * ------------------------------------------------------------------------\n'
2093                          ' */\n'
2094                          '\n'%(i.name))
2095             self.generate_introspection_for_interface(i)
2096             self.generate_interface(i)
2097             self.generate_property_accessors(i)
2098             self.generate_signal_emitters(i)
2099             self.generate_method_calls(i)
2100             self.generate_method_completers(i)
2101             self.generate_proxy(i)
2102             self.generate_stub(i)
2103         self.generate_object_manager_client()
2104         self.generate_outro()