1#include <gio/gio.h>
2#include <stdlib.h>
3
4static GDBusNodeInfo *introspection_data = NULL;
5static GMainLoop *loop = NULL;
6static GHashTable *properties = NULL;
7
8static const gchar introspection_xml[] =
9 "<node>"
10 " <interface name='com.example.Frob'>"
11 " <method name='Quit'>"
12 " </method>"
13 " <method name='TestArrayOfStringTypes'>"
14 " <arg direction='in' type='as' name='val_string' />"
15 " <arg direction='in' type='ao' name='val_objpath' />"
16 " <arg direction='in' type='ag' name='val_signature' />"
17 " <arg direction='out' type='as' />"
18 " <arg direction='out' type='ao' />"
19 " <arg direction='out' type='ag' />"
20 " </method>"
21 " <method name='TestPrimitiveTypes'>"
22 " <arg direction='in' type='y' name='val_byte' />"
23 " <arg direction='in' type='b' name='val_boolean' />"
24 " <arg direction='in' type='n' name='val_int16' />"
25 " <arg direction='in' type='q' name='val_uint16' />"
26 " <arg direction='in' type='i' name='val_int32' />"
27 " <arg direction='in' type='u' name='val_uint32' />"
28 " <arg direction='in' type='x' name='val_int64' />"
29 " <arg direction='in' type='t' name='val_uint64' />"
30 " <arg direction='in' type='d' name='val_double' />"
31 " <arg direction='in' type='s' name='val_string' />"
32 " <arg direction='in' type='o' name='val_objpath' />"
33 " <arg direction='in' type='g' name='val_signature' />"
34 " <arg direction='out' type='y' />"
35 " <arg direction='out' type='b' />"
36 " <arg direction='out' type='n' />"
37 " <arg direction='out' type='q' />"
38 " <arg direction='out' type='i' />"
39 " <arg direction='out' type='u' />"
40 " <arg direction='out' type='x' />"
41 " <arg direction='out' type='t' />"
42 " <arg direction='out' type='d' />"
43 " <arg direction='out' type='s' />"
44 " <arg direction='out' type='o' />"
45 " <arg direction='out' type='g' />"
46 " </method>"
47 " <method name='EmitSignal'>"
48 " <arg direction='in' type='s' name='str1' />"
49 " <arg direction='in' type='o' name='objpath1' />"
50 " </method>"
51 " <method name='TestArrayOfPrimitiveTypes'>"
52 " <arg direction='in' type='ay' name='val_byte' />"
53 " <arg direction='in' type='ab' name='val_boolean' />"
54 " <arg direction='in' type='an' name='val_int16' />"
55 " <arg direction='in' type='aq' name='val_uint16' />"
56 " <arg direction='in' type='ai' name='val_int32' />"
57 " <arg direction='in' type='au' name='val_uint32' />"
58 " <arg direction='in' type='ax' name='val_int64' />"
59 " <arg direction='in' type='at' name='val_uint64' />"
60 " <arg direction='in' type='ad' name='val_double' />"
61 " <arg direction='out' type='ay' />"
62 " <arg direction='out' type='ab' />"
63 " <arg direction='out' type='an' />"
64 " <arg direction='out' type='aq' />"
65 " <arg direction='out' type='ai' />"
66 " <arg direction='out' type='au' />"
67 " <arg direction='out' type='ax' />"
68 " <arg direction='out' type='at' />"
69 " <arg direction='out' type='ad' />"
70 " </method>"
71 " <method name='FrobSetProperty'>"
72 " <arg direction='in' type='s' name='prop_name' />"
73 " <arg direction='in' type='v' name='prop_value' />"
74 " </method>"
75 " <signal name='TestSignal'>"
76 " <arg type='s' name='str1' />"
77 " <arg type='o' name='objpath1' />"
78 " <arg type='v' name='variant1' />"
79 " </signal>"
80 " <method name='TestComplexArrays'>"
81 " <arg direction='in' type='a(ii)' name='aii' />"
82 " <arg direction='in' type='aa(ii)' name='aaii' />"
83 " <arg direction='in' type='aas' name='aas' />"
84 " <arg direction='in' type='aa{ss}' name='ahashes' />"
85 " <arg direction='in' type='aay' name='aay' />"
86 " <arg direction='in' type='av' name='av' />"
87 " <arg direction='in' type='aav' name='aav' />"
88 " <arg direction='out' type='a(ii)' />"
89 " <arg direction='out' type='aa(ii)' />"
90 " <arg direction='out' type='aas' />"
91 " <arg direction='out' type='aa{ss}' />"
92 " <arg direction='out' type='aay' />"
93 " <arg direction='out' type='av' />"
94 " <arg direction='out' type='aav' />"
95 " </method>"
96 " <method name='TestVariant'>"
97 " <arg direction='in' type='v' name='v' />"
98 " <arg direction='in' type='b' name='modify' />"
99 " <arg direction='out' type='v' />"
100 " </method>"
101 " <method name='FrobInvalidateProperty'>"
102 " <arg direction='in' type='s' name='new_value' />"
103 " </method>"
104 " <method name='HelloWorld'>"
105 " <arg direction='in' type='s' name='hello_message' />"
106 " <arg direction='out' type='s' />"
107 " </method>"
108 " <method name='PairReturn'>"
109 " <arg direction='out' type='s' />"
110 " <arg direction='out' type='u' />"
111 " </method>"
112 " <method name='TestStructureTypes'>"
113 " <arg direction='in' type='(ii)' name='s1' />"
114 " <arg direction='in' type='(s(ii)aya{ss})' name='s2' />"
115 " <arg direction='out' type='(ii)' />"
116 " <arg direction='out' type='(s(ii)aya{ss})' />"
117 " </method>"
118 " <method name='EmitSignal2'>"
119 " </method>"
120 " <method name='DoubleHelloWorld'>"
121 " <arg direction='in' type='s' name='hello1' />"
122 " <arg direction='in' type='s' name='hello2' />"
123 " <arg direction='out' type='s' />"
124 " <arg direction='out' type='s' />"
125 " </method>"
126 " <method name='Sleep'>"
127 " <arg direction='in' type='i' name='msec' />"
128 " </method>"
129 " <method name='TestHashTables'>"
130 " <arg direction='in' type='a{yy}' name='hyy' />"
131 " <arg direction='in' type='a{bb}' name='hbb' />"
132 " <arg direction='in' type='a{nn}' name='hnn' />"
133 " <arg direction='in' type='a{qq}' name='hqq' />"
134 " <arg direction='in' type='a{ii}' name='hii' />"
135 " <arg direction='in' type='a{uu}' name='huu' />"
136 " <arg direction='in' type='a{xx}' name='hxx' />"
137 " <arg direction='in' type='a{tt}' name='htt' />"
138 " <arg direction='in' type='a{dd}' name='hdd' />"
139 " <arg direction='in' type='a{ss}' name='hss' />"
140 " <arg direction='in' type='a{oo}' name='hoo' />"
141 " <arg direction='in' type='a{gg}' name='hgg' />"
142 " <arg direction='out' type='a{yy}' />"
143 " <arg direction='out' type='a{bb}' />"
144 " <arg direction='out' type='a{nn}' />"
145 " <arg direction='out' type='a{qq}' />"
146 " <arg direction='out' type='a{ii}' />"
147 " <arg direction='out' type='a{uu}' />"
148 " <arg direction='out' type='a{xx}' />"
149 " <arg direction='out' type='a{tt}' />"
150 " <arg direction='out' type='a{dd}' />"
151 " <arg direction='out' type='a{ss}' />"
152 " <arg direction='out' type='a{oo}' />"
153 " <arg direction='out' type='a{gg}' />"
154 " </method>"
155 " <signal name='TestSignal2'>"
156 " <arg type='i' name='int1' />"
157 " </signal>"
158 " <method name='TestComplexHashTables'>"
159 " <arg direction='in' type='a{s(ii)}' name='h_str_to_pair' />"
160 " <arg direction='in' type='a{sv}' name='h_str_to_variant' />"
161 " <arg direction='in' type='a{sav}' name='h_str_to_av' />"
162 " <arg direction='in' type='a{saav}' name='h_str_to_aav' />"
163 " <arg direction='in' type='a{sa(ii)}' name='h_str_to_array_of_pairs' />"
164 " <arg direction='in' type='a{sa{ss}}' name='hash_of_hashes' />"
165 " <arg direction='out' type='a{s(ii)}' />"
166 " <arg direction='out' type='a{sv}' />"
167 " <arg direction='out' type='a{sav}' />"
168 " <arg direction='out' type='a{saav}' />"
169 " <arg direction='out' type='a{sa(ii)}' />"
170 " <arg direction='out' type='a{sa{ss}}' />"
171 " </method>"
172 " <property type='y' name='y' access='readwrite' />"
173 " <property type='b' name='b' access='readwrite' />"
174 " <property type='n' name='n' access='readwrite' />"
175 " <property type='q' name='q' access='readwrite' />"
176 " <property type='i' name='i' access='readwrite' />"
177 " <property type='u' name='u' access='readwrite' />"
178 " <property type='x' name='x' access='readwrite' />"
179 " <property type='t' name='t' access='readwrite' />"
180 " <property type='d' name='d' access='readwrite' />"
181 " <property type='s' name='s' access='readwrite' />"
182 " <property type='o' name='o' access='readwrite' />"
183 " <property type='ay' name='ay' access='readwrite' />"
184 " <property type='ab' name='ab' access='readwrite' />"
185 " <property type='an' name='an' access='readwrite' />"
186 " <property type='aq' name='aq' access='readwrite' />"
187 " <property type='ai' name='ai' access='readwrite' />"
188 " <property type='au' name='au' access='readwrite' />"
189 " <property type='ax' name='ax' access='readwrite' />"
190 " <property type='at' name='at' access='readwrite' />"
191 " <property type='ad' name='ad' access='readwrite' />"
192 " <property type='as' name='as' access='readwrite' />"
193 " <property type='ao' name='ao' access='readwrite' />"
194 " <property type='s' name='foo' access='readwrite' />"
195 " <property type='s' name='PropertyThatWillBeInvalidated' access='readwrite' />"
196 " </interface>"
197 "</node>";
198
199static gboolean
200end_sleep (gpointer data)
201{
202 GDBusMethodInvocation *invocation = data;
203
204 g_dbus_method_invocation_return_value (invocation, NULL);
205 g_object_unref (object: invocation);
206
207 return G_SOURCE_REMOVE;
208}
209
210static void
211handle_method_call (GDBusConnection *connection,
212 const gchar *sender,
213 const gchar *object_path,
214 const gchar *interface_name,
215 const gchar *method_name,
216 GVariant *parameters,
217 GDBusMethodInvocation *invocation,
218 gpointer user_data)
219{
220 if (g_strcmp0 (str1: method_name, str2: "HelloWorld") == 0)
221 {
222 const gchar *greeting;
223
224 g_variant_get (value: parameters, format_string: "(&s)", &greeting);
225 if (g_strcmp0 (str1: greeting, str2: "Yo") == 0)
226 {
227 g_dbus_method_invocation_return_dbus_error (invocation,
228 error_name: "com.example.TestException",
229 error_message: "Yo is not a proper greeting");
230 }
231 else
232 {
233 gchar *response;
234 response = g_strdup_printf (format: "You greeted me with '%s'. Thanks!", greeting);
235 g_dbus_method_invocation_return_value (invocation,
236 parameters: g_variant_new (format_string: "(s)", response));
237 g_free ( mem: response);
238 }
239 }
240 else if (g_strcmp0 (str1: method_name, str2: "DoubleHelloWorld") == 0)
241 {
242 const gchar *hello1, *hello2;
243 gchar *reply1, *reply2;
244
245 g_variant_get (value: parameters, format_string: "(&s&s)", &hello1, &hello2);
246 reply1 = g_strdup_printf (format: "You greeted me with '%s'. Thanks!", hello1);
247 reply2 = g_strdup_printf (format: "Yo dawg, you uttered '%s'. Thanks!", hello2);
248 g_dbus_method_invocation_return_value (invocation,
249 parameters: g_variant_new (format_string: "(ss)", reply1, reply2));
250 g_free (mem: reply1);
251 g_free (mem: reply2);
252 }
253 else if (g_strcmp0 (str1: method_name, str2: "PairReturn") == 0)
254 {
255 g_dbus_method_invocation_return_value (invocation,
256 parameters: g_variant_new (format_string: "(su)", "foo", 42));
257 }
258 else if (g_strcmp0 (str1: method_name, str2: "TestPrimitiveTypes") == 0)
259 {
260 guchar val_byte;
261 gboolean val_boolean;
262 gint16 val_int16;
263 guint16 val_uint16;
264 gint32 val_int32;
265 guint32 val_uint32;
266 gint64 val_int64;
267 guint64 val_uint64;
268 gdouble val_double;
269 const gchar *val_string;
270 const gchar *val_objpath;
271 const gchar *val_signature;
272 gchar *ret_string;
273 gchar *ret_objpath;
274 gchar *ret_signature;
275
276 g_variant_get (value: parameters, format_string: "(ybnqiuxtd&s&o&g)",
277 &val_byte,
278 &val_boolean,
279 &val_int16,
280 &val_uint16,
281 &val_int32,
282 &val_uint32,
283 &val_int64,
284 &val_uint64,
285 &val_double,
286 &val_string,
287 &val_objpath,
288 &val_signature);
289
290 ret_string = g_strconcat (string1: val_string, val_string, NULL);
291 ret_objpath = g_strconcat (string1: val_objpath, "/modified", NULL);
292 ret_signature = g_strconcat (string1: val_signature, val_signature, NULL);
293
294 g_dbus_method_invocation_return_value (invocation,
295 parameters: g_variant_new (format_string: "(ybnqiuxtdsog)",
296 val_byte + 1,
297 !val_boolean,
298 val_int16 + 1,
299 val_uint16 + 1,
300 val_int32 + 1,
301 val_uint32 + 1,
302 val_int64 + 1,
303 val_uint64 + 1,
304 - val_double + 0.123,
305 ret_string,
306 ret_objpath,
307 ret_signature));
308
309 g_free (mem: ret_string);
310 g_free (mem: ret_objpath);
311 g_free (mem: ret_signature);
312 }
313 else if (g_strcmp0 (str1: method_name, str2: "TestArrayOfPrimitiveTypes") == 0)
314 {
315 GVariant *v;
316 const guchar *bytes;
317 const gint16 *int16s;
318 const guint16 *uint16s;
319 const gint32 *int32s;
320 const guint32 *uint32s;
321 const gint64 *int64s;
322 const guint64 *uint64s;
323 const gdouble *doubles;
324 gsize n_elts;
325 gint i, j;
326 GVariantBuilder ret;
327
328 g_variant_builder_init (builder: &ret, G_VARIANT_TYPE ("(ayabanaqaiauaxatad)"));
329
330 v = g_variant_get_child_value (value: parameters, index_: 0);
331 bytes = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 1);
332 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ay"));
333 for (j = 0; j < 2; j++)
334 for (i = 0; i < n_elts; i++)
335 g_variant_builder_add (builder: &ret, format_string: "y", bytes[i]);
336 g_variant_builder_close (builder: &ret);
337 g_variant_unref (value: v);
338
339 v = g_variant_get_child_value (value: parameters, index_: 1);
340 bytes = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 1);
341 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ab"));
342 for (j = 0; j < 2; j++)
343 for (i = 0; i < n_elts; i++)
344 g_variant_builder_add (builder: &ret, format_string: "b", (gboolean)bytes[i]);
345 g_variant_builder_close (builder: &ret);
346 g_variant_unref (value: v);
347
348 v = g_variant_get_child_value (value: parameters, index_: 2);
349 int16s = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 2);
350 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("an"));
351 for (j = 0; j < 2; j++)
352 for (i = 0; i < n_elts; i++)
353 g_variant_builder_add (builder: &ret, format_string: "n", int16s[i]);
354 g_variant_builder_close (builder: &ret);
355 g_variant_unref (value: v);
356
357 v = g_variant_get_child_value (value: parameters, index_: 3);
358 uint16s = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 2);
359 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("aq"));
360 for (j = 0; j < 2; j++)
361 for (i = 0; i < n_elts; i++)
362 g_variant_builder_add (builder: &ret, format_string: "q", uint16s[i]);
363 g_variant_builder_close (builder: &ret);
364 g_variant_unref (value: v);
365
366 v = g_variant_get_child_value (value: parameters, index_: 4);
367 int32s = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 4);
368 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ai"));
369 for (j = 0; j < 2; j++)
370 for (i = 0; i < n_elts; i++)
371 g_variant_builder_add (builder: &ret, format_string: "i", int32s[i]);
372 g_variant_builder_close (builder: &ret);
373 g_variant_unref (value: v);
374
375 v = g_variant_get_child_value (value: parameters, index_: 5);
376 uint32s = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 4);
377 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("au"));
378 for (j = 0; j < 2; j++)
379 for (i = 0; i < n_elts; i++)
380 g_variant_builder_add (builder: &ret, format_string: "u", uint32s[i]);
381 g_variant_builder_close (builder: &ret);
382 g_variant_unref (value: v);
383
384 v = g_variant_get_child_value (value: parameters, index_: 6);
385 int64s = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 8);
386 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ax"));
387 for (j = 0; j < 2; j++)
388 for (i = 0; i < n_elts; i++)
389 g_variant_builder_add (builder: &ret, format_string: "x", int64s[i]);
390 g_variant_builder_close (builder: &ret);
391 g_variant_unref (value: v);
392
393 v = g_variant_get_child_value (value: parameters, index_: 7);
394 uint64s = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: 8);
395 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("at"));
396 for (j = 0; j < 2; j++)
397 for (i = 0; i < n_elts; i++)
398 g_variant_builder_add (builder: &ret, format_string: "t", uint64s[i]);
399 g_variant_builder_close (builder: &ret);
400 g_variant_unref (value: v);
401
402 v = g_variant_get_child_value (value: parameters, index_: 8);
403 doubles = g_variant_get_fixed_array (value: v, n_elements: &n_elts, element_size: sizeof (gdouble));
404 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ad"));
405 for (j = 0; j < 2; j++)
406 for (i = 0; i < n_elts; i++)
407 g_variant_builder_add (builder: &ret, format_string: "d", doubles[i]);
408 g_variant_builder_close (builder: &ret);
409 g_variant_unref (value: v);
410
411 g_dbus_method_invocation_return_value (invocation,
412 parameters: g_variant_builder_end (builder: &ret));
413 }
414 else if (g_strcmp0 (str1: method_name, str2: "TestArrayOfStringTypes") == 0)
415 {
416 GVariantIter *iter1;
417 GVariantIter *iter2;
418 GVariantIter *iter3;
419 GVariantIter *iter;
420 GVariantBuilder ret;
421 const gchar *s;
422 gint i;
423
424 g_variant_builder_init (builder: &ret, G_VARIANT_TYPE ("(asaoag)"));
425 g_variant_get (value: parameters, format_string: "(asaoag)", &iter1, &iter2, &iter3);
426
427 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("as"));
428 for (i = 0; i < 2; i++)
429 {
430 iter = g_variant_iter_copy (iter: iter1);
431 while (g_variant_iter_loop (iter, format_string: "s", &s))
432 g_variant_builder_add (builder: &ret, format_string: "s", s);
433 g_variant_iter_free (iter);
434 }
435 g_variant_builder_close (builder: &ret);
436
437 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ao"));
438 for (i = 0; i < 2; i++)
439 {
440 iter = g_variant_iter_copy (iter: iter1);
441 while (g_variant_iter_loop (iter, format_string: "o", &s))
442 g_variant_builder_add (builder: &ret, format_string: "o", s);
443 g_variant_iter_free (iter);
444 }
445 g_variant_builder_close (builder: &ret);
446
447 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("ag"));
448 for (i = 0; i < 2; i++)
449 {
450 iter = g_variant_iter_copy (iter: iter1);
451 while (g_variant_iter_loop (iter, format_string: "g", &s))
452 g_variant_builder_add (builder: &ret, format_string: "g", s);
453 g_variant_iter_free (iter);
454 }
455 g_variant_builder_close (builder: &ret);
456
457 g_variant_iter_free (iter: iter1);
458 g_variant_iter_free (iter: iter2);
459 g_variant_iter_free (iter: iter3);
460
461 g_dbus_method_invocation_return_value (invocation,
462 parameters: g_variant_builder_end (builder: &ret));
463 }
464 else if (g_strcmp0 (str1: method_name, str2: "TestHashTables") == 0)
465 {
466 GVariant *v;
467 GVariantIter iter;
468 GVariantBuilder ret;
469 guint8 y1, y2;
470 gboolean b1, b2;
471 gint16 n1, n2;
472 guint16 q1, q2;
473 gint i1, i2;
474 guint u1, u2;
475 gint64 x1, x2;
476 guint64 t1, t2;
477 gdouble d1, d2;
478 gchar *s1, *s2;
479
480 g_variant_builder_init (builder: &ret, G_VARIANT_TYPE ("(a{yy}a{bb}a{nn}a{qq}a{ii}a{uu}a{xx}a{tt}a{dd}a{ss}a{oo}a{gg})"));
481
482 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{yy}"));
483 v = g_variant_get_child_value (value: parameters, index_: 0);
484 g_variant_iter_init (iter: &iter, value: v);
485 while (g_variant_iter_loop (iter: &iter, format_string: "yy", &y1, &y2))
486 g_variant_builder_add (builder: &ret, format_string: "{yy}", y1 * 2, (y2 * 3) & 255);
487 g_variant_unref (value: v);
488 g_variant_builder_close (builder: &ret);
489
490 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{bb}"));
491 v = g_variant_get_child_value (value: parameters, index_: 1);
492 g_variant_iter_init (iter: &iter, value: v);
493 while (g_variant_iter_loop (iter: &iter, format_string: "bb", &b1, &b2))
494 g_variant_builder_add (builder: &ret, format_string: "{bb}", b1, TRUE);
495 g_variant_unref (value: v);
496 g_variant_builder_close (builder: &ret);
497
498 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{nn}"));
499 v = g_variant_get_child_value (value: parameters, index_: 2);
500 g_variant_iter_init (iter: &iter, value: v);
501 while (g_variant_iter_loop (iter: &iter, format_string: "nn", &n1, &n2))
502 g_variant_builder_add (builder: &ret, format_string: "{nn}", n1 * 2, n2 * 3);
503 g_variant_unref (value: v);
504 g_variant_builder_close (builder: &ret);
505
506 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{qq}"));
507 v = g_variant_get_child_value (value: parameters, index_: 3);
508 g_variant_iter_init (iter: &iter, value: v);
509 while (g_variant_iter_loop (iter: &iter, format_string: "qq", &q1, &q2))
510 g_variant_builder_add (builder: &ret, format_string: "{qq}", q1 * 2, q2 * 3);
511 g_variant_unref (value: v);
512 g_variant_builder_close (builder: &ret);
513
514 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{ii}"));
515 v = g_variant_get_child_value (value: parameters, index_: 4);
516 g_variant_iter_init (iter: &iter, value: v);
517 while (g_variant_iter_loop (iter: &iter, format_string: "ii", &i1, &i2))
518 g_variant_builder_add (builder: &ret, format_string: "{ii}", i1 * 2, i2 * 3);
519 g_variant_unref (value: v);
520 g_variant_builder_close (builder: &ret);
521
522 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{uu}"));
523 v = g_variant_get_child_value (value: parameters, index_: 5);
524 g_variant_iter_init (iter: &iter, value: v);
525 while (g_variant_iter_loop (iter: &iter, format_string: "uu", &u1, &u2))
526 g_variant_builder_add (builder: &ret, format_string: "{uu}", u1 * 2, u2 * 3);
527 g_variant_unref (value: v);
528 g_variant_builder_close (builder: &ret);
529
530 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{xx}"));
531 v = g_variant_get_child_value (value: parameters, index_: 6);
532 g_variant_iter_init (iter: &iter, value: v);
533 while (g_variant_iter_loop (iter: &iter, format_string: "xx", &x1, &x2))
534 g_variant_builder_add (builder: &ret, format_string: "{xx}", x1 + 2, x2 + 1);
535 g_variant_unref (value: v);
536 g_variant_builder_close (builder: &ret);
537
538 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{tt}"));
539 v = g_variant_get_child_value (value: parameters, index_: 7);
540 g_variant_iter_init (iter: &iter, value: v);
541 while (g_variant_iter_loop (iter: &iter, format_string: "tt", &t1, &t2))
542 g_variant_builder_add (builder: &ret, format_string: "{tt}", t1 + 2, t2 + 1);
543 g_variant_unref (value: v);
544 g_variant_builder_close (builder: &ret);
545
546 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{dd}"));
547 v = g_variant_get_child_value (value: parameters, index_: 8);
548 g_variant_iter_init (iter: &iter, value: v);
549 while (g_variant_iter_loop (iter: &iter, format_string: "dd", &d1, &d2))
550 g_variant_builder_add (builder: &ret, format_string: "{dd}", d1 + 2.5, d2 + 5.0);
551 g_variant_unref (value: v);
552 g_variant_builder_close (builder: &ret);
553
554 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{ss}"));
555 v = g_variant_get_child_value (value: parameters, index_: 9);
556 g_variant_iter_init (iter: &iter, value: v);
557 while (g_variant_iter_loop (iter: &iter, format_string: "ss", &s1, &s2))
558 {
559 gchar *tmp1, *tmp2;
560 tmp1 = g_strconcat (string1: s1, "mod", NULL);
561 tmp2 = g_strconcat (string1: s2, s2, NULL);
562 g_variant_builder_add (builder: &ret, format_string: "{ss}", tmp1, tmp2);
563 g_free (mem: tmp1);
564 g_free (mem: tmp2);
565 }
566 g_variant_unref (value: v);
567 g_variant_builder_close (builder: &ret);
568
569 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{oo}"));
570 v = g_variant_get_child_value (value: parameters, index_: 10);
571 g_variant_iter_init (iter: &iter, value: v);
572 while (g_variant_iter_loop (iter: &iter, format_string: "oo", &s1, &s2))
573 {
574 gchar *tmp1, *tmp2;
575 tmp1 = g_strconcat (string1: s1, "/mod", NULL);
576 tmp2 = g_strconcat (string1: s2, "/mod2", NULL);
577 g_variant_builder_add (builder: &ret, format_string: "{oo}", tmp1, tmp2);
578 g_free (mem: tmp1);
579 g_free (mem: tmp2);
580 }
581 g_variant_unref (value: v);
582 g_variant_builder_close (builder: &ret);
583
584 g_variant_builder_open (builder: &ret, G_VARIANT_TYPE ("a{gg}"));
585 v = g_variant_get_child_value (value: parameters, index_: 11);
586 g_variant_iter_init (iter: &iter, value: v);
587 while (g_variant_iter_loop (iter: &iter, format_string: "gg", &s1, &s2))
588 {
589 gchar *tmp1, *tmp2;
590 tmp1 = g_strconcat (string1: s1, "assgit", NULL);
591 tmp2 = g_strconcat (string1: s2, s2, NULL);
592 g_variant_builder_add (builder: &ret, format_string: "{gg}", tmp1, tmp2);
593 g_free (mem: tmp1);
594 g_free (mem: tmp2);
595 }
596 g_variant_unref (value: v);
597 g_variant_builder_close (builder: &ret);
598
599 g_dbus_method_invocation_return_value (invocation,
600 parameters: g_variant_builder_end (builder: &ret));
601 }
602 else if (g_strcmp0 (str1: method_name, str2: "TestStructureTypes") == 0)
603 {
604 gint x, y, x1, y1;
605 const gchar *desc;
606 GVariantIter *iter1, *iter2;
607 gchar *desc_ret;
608 GVariantBuilder ret1, ret2;
609 GVariantIter *iter;
610 GVariant *v;
611 gchar *s1, *s2;
612
613 g_variant_get (value: parameters, format_string: "((ii)(&s(ii)aya{ss}))",
614 &x, &y, &desc, &x1, &y1, &iter1, &iter2);
615
616 desc_ret = g_strconcat (string1: desc, "... in bed!", NULL);
617
618 g_variant_builder_init (builder: &ret1, G_VARIANT_TYPE ("ay"));
619 iter = g_variant_iter_copy (iter: iter1);
620 while (g_variant_iter_loop (iter: iter1, format_string: "y", &v))
621 g_variant_builder_add (builder: &ret1, format_string: "y", v);
622 while (g_variant_iter_loop (iter, format_string: "y", &v))
623 g_variant_builder_add (builder: &ret1, format_string: "y", v);
624 g_variant_iter_free (iter);
625 g_variant_iter_free (iter: iter1);
626
627 g_variant_builder_init (builder: &ret2, G_VARIANT_TYPE ("a{ss}"));
628 while (g_variant_iter_loop (iter: iter1, format_string: "ss", &s1, &s2))
629 {
630 gchar *tmp;
631 tmp = g_strconcat (string1: s2, " ... in bed!", NULL);
632 g_variant_builder_add (builder: &ret1, format_string: "{ss}", s1, tmp);
633 g_free (mem: tmp);
634 }
635 g_variant_iter_free (iter: iter2);
636
637 g_dbus_method_invocation_return_value (invocation,
638 parameters: g_variant_new (format_string: "((ii)(&s(ii)aya{ss}))",
639 x + 1, y + 1, desc_ret, x1 + 2, y1 + 2,
640 &ret1, &ret2));
641
642 g_free (mem: desc_ret);
643 }
644 else if (g_strcmp0 (str1: method_name, str2: "TestVariant") == 0)
645 {
646 GVariant *v;
647 gboolean modify;
648 GVariant *ret;
649
650 g_variant_get (value: parameters, format_string: "(vb)", &v, &modify);
651
652 /* FIXME handle more cases */
653 if (modify)
654 {
655 if (g_variant_is_of_type (value: v, G_VARIANT_TYPE_BOOLEAN))
656 {
657 ret = g_variant_new_boolean (FALSE);
658 }
659 else if (g_variant_is_of_type (value: v, G_VARIANT_TYPE_TUPLE))
660 {
661 ret = g_variant_new (format_string: "(si)", "other struct", 100);
662 }
663 else
664 g_assert_not_reached ();
665 }
666 else
667 ret = v;
668
669 g_dbus_method_invocation_return_value (invocation, parameters: ret);
670 g_variant_unref (value: v);
671 }
672 else if (g_strcmp0 (str1: method_name, str2: "TestComplexArrays") == 0)
673 {
674 /* FIXME */
675 g_dbus_method_invocation_return_value (invocation, parameters);
676 }
677 else if (g_strcmp0 (str1: method_name, str2: "TestComplexHashTables") == 0)
678 {
679 /* FIXME */
680 g_dbus_method_invocation_return_value (invocation, parameters);
681 }
682 else if (g_strcmp0 (str1: method_name, str2: "FrobSetProperty") == 0)
683 {
684 gchar *name;
685 GVariant *value;
686 g_variant_get (value: parameters, format_string: "(sv)", &name, &value);
687 g_hash_table_replace (hash_table: properties, key: name, value);
688 g_dbus_connection_emit_signal (connection,
689 NULL,
690 object_path: "/com/example/TestObject",
691 interface_name: "org.freedesktop.DBus.Properties",
692 signal_name: "PropertiesChanged",
693 parameters: g_variant_new_parsed (format: "('com.example.Frob', [{%s, %v}], @as [])", name, value),
694 NULL);
695 g_dbus_method_invocation_return_value (invocation, NULL);
696 }
697 else if (g_strcmp0 (str1: method_name, str2: "FrobInvalidateProperty") == 0)
698 {
699 const gchar *value;
700 g_variant_get (value: parameters, format_string: "(&s)", &value);
701 g_hash_table_replace (hash_table: properties, key: g_strdup (str: "PropertyThatWillBeInvalidated"), value: g_variant_ref_sink (value: g_variant_new_string (string: value)));
702
703 g_dbus_connection_emit_signal (connection,
704 NULL,
705 object_path: "/com/example/TestObject",
706 interface_name: "org.freedesktop.DBus.Properties",
707 signal_name: "PropertiesChanged",
708 parameters: g_variant_new_parsed (format: "('com.example.Frob', @a{sv} [], ['PropertyThatWillBeInvalidated'])"),
709 NULL);
710 g_dbus_method_invocation_return_value (invocation, NULL);
711 }
712 else if (g_strcmp0 (str1: method_name, str2: "EmitSignal") == 0)
713 {
714 const gchar *str;
715 const gchar *path;
716 gchar *str_ret;
717 gchar *path_ret;
718 g_variant_get (value: parameters, format_string: "(&s&o)", &str, &path);
719 str_ret = g_strconcat (string1: str, " .. in bed!", NULL);
720 path_ret = g_strconcat (string1: path, "/in/bed", NULL);
721 g_dbus_connection_emit_signal (connection,
722 NULL,
723 object_path: "/com/example/TestObject",
724 interface_name: "com.example.Frob",
725 signal_name: "TestSignal",
726 parameters: g_variant_new_parsed (format: "(%s, %o, <'a variant'>)", str_ret, path_ret),
727 NULL);
728 g_free (mem: str_ret);
729 g_free (mem: path_ret);
730 g_dbus_method_invocation_return_value (invocation, NULL);
731 }
732 else if (g_strcmp0 (str1: method_name, str2: "EmitSignal2") == 0)
733 {
734 g_dbus_connection_emit_signal (connection,
735 NULL,
736 object_path: "/com/example/TestObject",
737 interface_name: "com.example.Frob",
738 signal_name: "TestSignal2",
739 parameters: g_variant_new_parsed (format: "(42, )"),
740 NULL);
741 g_dbus_method_invocation_return_value (invocation, NULL);
742 }
743 else if (g_strcmp0 (str1: method_name, str2: "Sleep") == 0)
744 {
745 gint msec;
746
747 g_variant_get (value: parameters, format_string: "(i)", &msec);
748
749 g_timeout_add (interval: (guint)msec, function: end_sleep, g_object_ref (invocation));
750 }
751 else if (g_strcmp0 (str1: method_name, str2: "Quit") == 0)
752 {
753 g_dbus_method_invocation_return_value (invocation, NULL);
754 g_main_loop_quit (loop);
755 }
756}
757
758static GVariant *
759handle_get_property (GDBusConnection *connection,
760 const gchar *sender,
761 const gchar *object_path,
762 const gchar *interface_name,
763 const gchar *property_name,
764 GError **error,
765 gpointer user_data)
766{
767 GVariant *ret;
768
769 ret = g_hash_table_lookup (hash_table: properties, key: property_name);
770 if (ret)
771 {
772 g_assert (!g_variant_is_floating (ret));
773 g_variant_ref (value: ret);
774 }
775 else
776 {
777 g_set_error (err: error,
778 G_DBUS_ERROR, code: G_DBUS_ERROR_FAILED,
779 format: "no such property: %s", property_name);
780 }
781
782 return ret;
783}
784
785static gboolean
786handle_set_property (GDBusConnection *connection,
787 const gchar *sender,
788 const gchar *object_path,
789 const gchar *interface_name,
790 const gchar *property_name,
791 GVariant *value,
792 GError **error,
793 gpointer user_data)
794{
795 g_set_error (err: error,
796 G_DBUS_ERROR, code: G_DBUS_ERROR_FAILED,
797 format: "SetProperty not implemented");
798 return FALSE;
799}
800
801static const GDBusInterfaceVTable interface_vtable =
802{
803 handle_method_call,
804 handle_get_property,
805 handle_set_property
806};
807
808static void
809on_bus_acquired (GDBusConnection *connection,
810 const gchar *name,
811 gpointer user_data)
812{
813 guint id;
814
815 id = g_dbus_connection_register_object (connection,
816 object_path: "/com/example/TestObject",
817 interface_info: introspection_data->interfaces[0],
818 vtable: &interface_vtable,
819 NULL,
820 NULL,
821 NULL);
822 g_assert (id > 0);
823}
824
825static void
826on_name_acquired (GDBusConnection *connection,
827 const gchar *name,
828 gpointer user_data)
829{
830}
831
832static void
833on_name_lost (GDBusConnection *connection,
834 const gchar *name,
835 gpointer user_data)
836{
837 exit (status: 1);
838}
839
840int
841main (int argc, char *argv[])
842{
843 guint owner_id;
844
845 introspection_data = g_dbus_node_info_new_for_xml (xml_data: introspection_xml, NULL);
846 properties = g_hash_table_new_full (hash_func: g_str_hash, key_equal_func: g_str_equal, key_destroy_func: g_free, value_destroy_func: (GDestroyNotify)g_variant_unref);
847 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "y"), value: g_variant_ref_sink (value: g_variant_new_byte (value: 1)));
848 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "b"), value: g_variant_ref_sink (value: g_variant_new_boolean (TRUE)));
849 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "n"), value: g_variant_ref_sink (value: g_variant_new_int16 (value: 2)));
850 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "q"), value: g_variant_ref_sink (value: g_variant_new_uint16 (value: 3)));
851 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "i"), value: g_variant_ref_sink (value: g_variant_new_int32 (value: 4)));
852 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "u"), value: g_variant_ref_sink (value: g_variant_new_uint32 (value: 5)));
853 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "x"), value: g_variant_ref_sink (value: g_variant_new_int64 (value: 6)));
854 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "t"), value: g_variant_ref_sink (value: g_variant_new_uint64 (value: 7)));
855 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "d"), value: g_variant_ref_sink (value: g_variant_new_double (value: 7.5)));
856 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "s"), value: g_variant_ref_sink (value: g_variant_new_string (string: "a string")));
857 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "o"), value: g_variant_ref_sink (value: g_variant_new_object_path (object_path: "/some/path")));
858 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "ay"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@y 1, @y 11]")));
859 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "ab"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[true, false]")));
860 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "an"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@n 2, @n 12]")));
861 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "aq"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@q 3, @q 13]")));
862 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "ai"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@i 4, @i 14]")));
863 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "au"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@u 5, @u 15]")));
864 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "ax"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@x 6, @x 16]")));
865 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "at"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@t 7, @t 17]")));
866 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "ad"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[7.5, 17.5]")));
867 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "as"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "['a string', 'another string']")));
868 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "ao"), value: g_variant_ref_sink (value: g_variant_new_parsed (format: "[@o '/some/path', @o '/another/path']")));
869 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "foo"), value: g_variant_ref_sink (value: g_variant_new_string (string: "a frobbed string")));
870 g_hash_table_insert (hash_table: properties, key: g_strdup (str: "PropertyThatWillBeInvalidated"), value: g_variant_ref_sink (value: g_variant_new_string (string: "InitialValue")));
871
872 owner_id = g_bus_own_name (bus_type: G_BUS_TYPE_SESSION,
873 name: "com.example.TestService",
874 flags: G_BUS_NAME_OWNER_FLAGS_NONE,
875 bus_acquired_handler: on_bus_acquired,
876 name_acquired_handler: on_name_acquired,
877 name_lost_handler: on_name_lost,
878 NULL,
879 NULL);
880
881 loop = g_main_loop_new (NULL, FALSE);
882 g_main_loop_run (loop);
883
884 g_bus_unown_name (owner_id);
885
886 g_dbus_node_info_unref (info: introspection_data);
887 g_hash_table_unref (hash_table: properties);
888
889 return 0;
890}
891

source code of gtk/subprojects/glib/gio/tests/gdbus-testserver.c