1 /* SPDX-License-Identifier: AFL-2.1 OR GPL-2.0-or-later */
2
3 #include <config.h>
4 #undef G_DISABLE_ASSERT
5
6 #include <string.h>
7 #include <glib/gi18n.h>
8 #include <glib-object.h>
9 #include "my-object.h"
10
11 #include "test-service-glib-glue.h"
12
13 /* Properties */
14 enum
15 {
16 PROP_0,
17 PROP_THIS_IS_A_STRING,
18 PROP_NO_TOUCHING,
19 PROP_SUPER_STUDLY,
20 PROP_SHOULD_BE_HIDDEN
21 };
22
23 enum
24 {
25 FROBNICATE,
26 OBJECTIFIED,
27 SIG0,
28 SIG1,
29 SIG2,
30 LAST_SIGNAL
31 };
32
33 static guint signals[LAST_SIGNAL] = { 0 };
34
G_DEFINE_TYPE(MyObject,my_object,G_TYPE_OBJECT)35 G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT)
36
37 static void
38 my_object_finalize (GObject *object)
39 {
40 MyObject *mobject = MY_OBJECT (object);
41
42 g_free (mobject->this_is_a_string);
43 g_clear_error (&mobject->saved_error);
44
45 (G_OBJECT_CLASS (my_object_parent_class)->finalize) (object);
46 }
47
48 static void
my_object_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)49 my_object_set_property (GObject *object,
50 guint prop_id,
51 const GValue *value,
52 GParamSpec *pspec)
53 {
54 MyObject *mobject;
55
56 mobject = MY_OBJECT (object);
57
58 switch (prop_id)
59 {
60 case PROP_THIS_IS_A_STRING:
61 g_free (mobject->this_is_a_string);
62 mobject->this_is_a_string = g_value_dup_string (value);
63 break;
64
65 case PROP_NO_TOUCHING:
66 mobject->notouching = g_value_get_uint (value);
67 break;
68
69 case PROP_SUPER_STUDLY:
70 mobject->super_studly = g_value_get_double (value);
71 break;
72
73 case PROP_SHOULD_BE_HIDDEN:
74 mobject->should_be_hidden = g_value_get_boolean (value);
75 break;
76
77 default:
78 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
79 break;
80 }
81 }
82
83 static void
my_object_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)84 my_object_get_property (GObject *object,
85 guint prop_id,
86 GValue *value,
87 GParamSpec *pspec)
88 {
89 MyObject *mobject;
90
91 mobject = MY_OBJECT (object);
92
93 switch (prop_id)
94 {
95 case PROP_THIS_IS_A_STRING:
96 g_value_set_string (value, mobject->this_is_a_string);
97 break;
98
99 case PROP_NO_TOUCHING:
100 g_value_set_uint (value, mobject->notouching);
101 break;
102
103 case PROP_SUPER_STUDLY:
104 g_value_set_double (value, mobject->super_studly);
105 break;
106
107 case PROP_SHOULD_BE_HIDDEN:
108 g_value_set_boolean (value, mobject->should_be_hidden);
109 break;
110
111 default:
112 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
113 break;
114 }
115 }
116
117 static void
my_object_init(MyObject * obj)118 my_object_init (MyObject *obj)
119 {
120 obj->val = 0;
121 obj->notouching = 42;
122 obj->saved_error = g_error_new_literal (MY_OBJECT_ERROR,
123 MY_OBJECT_ERROR_FOO, "this method always loses");
124 }
125
126 static void
my_object_class_init(MyObjectClass * mobject_class)127 my_object_class_init (MyObjectClass *mobject_class)
128 {
129 GObjectClass *gobject_class = G_OBJECT_CLASS (mobject_class);
130
131 dbus_g_object_type_install_info (MY_TYPE_OBJECT,
132 &dbus_glib_my_object_object_info);
133
134 gobject_class->finalize = my_object_finalize;
135 gobject_class->set_property = my_object_set_property;
136 gobject_class->get_property = my_object_get_property;
137
138 g_object_class_install_property (gobject_class,
139 PROP_THIS_IS_A_STRING,
140 g_param_spec_string ("this_is_a_string",
141 _("Sample string"),
142 _("Example of a string property"),
143 "default value",
144 G_PARAM_READWRITE));
145 g_object_class_install_property (gobject_class,
146 PROP_NO_TOUCHING,
147 g_param_spec_uint ("no_touching",
148 _("Don't touch"),
149 _("Example of a readonly property (for export)"),
150 0, 100, 42,
151 G_PARAM_READWRITE));
152
153 g_object_class_install_property (gobject_class,
154 PROP_SUPER_STUDLY,
155 g_param_spec_double ("super-studly",
156 _("In Studly Caps"),
157 _("Example of a StudlyCaps property"),
158 0, 256, 128,
159 G_PARAM_READWRITE));
160
161 g_object_class_install_property (gobject_class,
162 PROP_SHOULD_BE_HIDDEN,
163 g_param_spec_boolean ("should-be-hidden",
164 _("A non-exported property"),
165 _("Example of a property we don't want exported"),
166 FALSE,
167 G_PARAM_READWRITE));
168
169 signals[FROBNICATE] =
170 g_signal_new ("frobnicate",
171 G_OBJECT_CLASS_TYPE (mobject_class),
172 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
173 0,
174 NULL, NULL,
175 g_cclosure_marshal_VOID__INT,
176 G_TYPE_NONE, 1, G_TYPE_INT);
177
178 signals[OBJECTIFIED] =
179 g_signal_new ("objectified",
180 G_OBJECT_CLASS_TYPE (mobject_class),
181 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
182 0,
183 NULL, NULL,
184 g_cclosure_marshal_VOID__OBJECT,
185 G_TYPE_NONE, 1, G_TYPE_OBJECT);
186
187 signals[SIG0] =
188 g_signal_new ("sig0",
189 G_OBJECT_CLASS_TYPE (mobject_class),
190 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
191 0,
192 NULL, NULL, NULL,
193 G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
194
195 signals[SIG1] =
196 g_signal_new ("sig1",
197 G_OBJECT_CLASS_TYPE (mobject_class),
198 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
199 0,
200 NULL, NULL, NULL,
201 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_VALUE);
202
203 signals[SIG2] =
204 g_signal_new ("sig2",
205 G_OBJECT_CLASS_TYPE (mobject_class),
206 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
207 0,
208 NULL, NULL,
209 g_cclosure_marshal_VOID__BOXED,
210 G_TYPE_NONE, 1, DBUS_TYPE_G_STRING_STRING_HASHTABLE);
211 }
212
213 GQuark
my_object_error_quark(void)214 my_object_error_quark (void)
215 {
216 static GQuark quark = 0;
217 if (!quark)
218 quark = g_quark_from_static_string ("my_object_error");
219
220 return quark;
221 }
222
223 /* This should really be standard. */
224 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
225
226 GType
my_object_error_get_type(void)227 my_object_error_get_type (void)
228 {
229 static GType etype = 0;
230
231 if (etype == 0)
232 {
233 static const GEnumValue values[] =
234 {
235
236 ENUM_ENTRY (MY_OBJECT_ERROR_FOO, "Foo"),
237 ENUM_ENTRY (MY_OBJECT_ERROR_BAR, "Bar"),
238 ENUM_ENTRY (MY_OBJECT_ERROR_MULTI_WORD, "Multi-word"),
239 ENUM_ENTRY (MY_OBJECT_ERROR_UNDER_SCORE, "Under_score"),
240 { 0, 0, 0 }
241 };
242
243 etype = g_enum_register_static ("MyObjectError", values);
244 }
245
246 return etype;
247 }
248
249 gboolean
my_object_do_nothing(MyObject * obj,GError ** error)250 my_object_do_nothing (MyObject *obj, GError **error)
251 {
252 return TRUE;
253 }
254
255 gboolean
my_object_increment(MyObject * obj,gint32 x,gint32 * ret,GError ** error)256 my_object_increment (MyObject *obj, gint32 x, gint32 *ret, GError **error)
257 {
258 *ret = x +1;
259 return TRUE;
260 }
261
262 gint32
my_object_increment_retval(MyObject * obj,gint32 x)263 my_object_increment_retval (MyObject *obj, gint32 x)
264 {
265 return x + 1;
266 }
267
268 gint32
my_object_increment_retval_error(MyObject * obj,gint32 x,GError ** error)269 my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error)
270 {
271 if (x + 1 > 10)
272 {
273 g_set_error (error,
274 MY_OBJECT_ERROR,
275 MY_OBJECT_ERROR_FOO,
276 "%s",
277 "x is bigger than 9");
278 return FALSE;
279 }
280 return x + 1;
281 }
282
283 void
my_object_save_error(MyObject * obj,GQuark domain,gint code,const gchar * message)284 my_object_save_error (MyObject *obj,
285 GQuark domain,
286 gint code,
287 const gchar *message)
288 {
289 g_clear_error (&obj->saved_error);
290 g_set_error_literal (&obj->saved_error, domain, code, message);
291 }
292
293 gboolean
my_object_throw_error(MyObject * obj,GError ** error)294 my_object_throw_error (MyObject *obj, GError **error)
295 {
296 g_set_error_literal (error, obj->saved_error->domain,
297 obj->saved_error->code, obj->saved_error->message);
298 return FALSE;
299 }
300
301 gboolean
my_object_throw_unregistered_error(MyObject * obj,GError ** error)302 my_object_throw_unregistered_error (MyObject *obj, GError **error)
303 {
304 /* Unregistered errors shouldn't cause a dbus abort. See
305 * https://bugzilla.redhat.com/show_bug.cgi?id=581794
306 *
307 * This is arguably invalid usage - a domain of 0 (which stringifies
308 * to NULL) is meaningless. (See GNOME#660731.)
309 *
310 * We can't just use my_object_save_error() and ThrowError() for
311 * this, because g_error_new() is stricter about the domain than
312 * g_error_new_valist(). Perhaps this method should be removed entirely,
313 * though.
314 */
315 g_set_error (error, 0, 0,
316 "%s",
317 "this method always loses more");
318 return FALSE;
319 }
320
321
322 gboolean
my_object_uppercase(MyObject * obj,const char * str,char ** ret,GError ** error)323 my_object_uppercase (MyObject *obj, const char *str, char **ret, GError **error)
324 {
325 *ret = g_ascii_strup (str, -1);
326 return TRUE;
327 }
328
329 gboolean
my_object_many_args(MyObject * obj,guint32 x,const char * str,double trouble,double * d_ret,char ** str_ret,GError ** error)330 my_object_many_args (MyObject *obj, guint32 x, const char *str, double trouble, double *d_ret, char **str_ret, GError **error)
331 {
332 *d_ret = trouble + (x * 2);
333 *str_ret = g_ascii_strup (str, -1);
334 return TRUE;
335 }
336
337 gboolean
my_object_many_return(MyObject * obj,guint32 * arg0,char ** arg1,gint32 * arg2,guint32 * arg3,guint32 * arg4,const char ** arg5,GError ** error)338 my_object_many_return (MyObject *obj, guint32 *arg0, char **arg1, gint32 *arg2, guint32 *arg3, guint32 *arg4, const char **arg5, GError **error)
339 {
340 *arg0 = 42;
341 *arg1 = g_strdup ("42");
342 *arg2 = -67;
343 *arg3 = 2;
344 *arg4 = 26;
345 *arg5 = "hello world"; /* Annotation specifies as const */
346 return TRUE;
347 }
348
349 gboolean
my_object_stringify(MyObject * obj,GValue * value,char ** ret,GError ** error)350 my_object_stringify (MyObject *obj, GValue *value, char **ret, GError **error)
351 {
352 GValue valstr = {0, };
353
354 g_value_init (&valstr, G_TYPE_STRING);
355 if (!g_value_transform (value, &valstr))
356 {
357 g_set_error (error,
358 MY_OBJECT_ERROR,
359 MY_OBJECT_ERROR_FOO,
360 "couldn't transform value");
361 return FALSE;
362 }
363 *ret = g_value_dup_string (&valstr);
364 g_value_unset (&valstr);
365 return TRUE;
366 }
367
368 gboolean
my_object_unstringify(MyObject * obj,const char * str,GValue * value,GError ** error)369 my_object_unstringify (MyObject *obj, const char *str, GValue *value, GError **error)
370 {
371 if (str[0] == '\0' || !g_ascii_isdigit (str[0])) {
372 g_value_init (value, G_TYPE_STRING);
373 g_value_set_string (value, str);
374 } else {
375 g_value_init (value, G_TYPE_INT);
376 g_value_set_int (value, (int) g_ascii_strtoull (str, NULL, 10));
377 }
378 return TRUE;
379 }
380
381 gboolean
my_object_recursive1(MyObject * obj,GArray * array,guint32 * len_ret,GError ** error)382 my_object_recursive1 (MyObject *obj, GArray *array, guint32 *len_ret, GError **error)
383 {
384 *len_ret = array->len;
385 return TRUE;
386 }
387
388 gboolean
my_object_recursive2(MyObject * obj,guint32 reqlen,GArray ** ret,GError ** error)389 my_object_recursive2 (MyObject *obj, guint32 reqlen, GArray **ret, GError **error)
390 {
391 guint32 val;
392 GArray *array;
393
394 array = g_array_new (FALSE, TRUE, sizeof (guint32));
395
396 while (reqlen > 0) {
397 val = 42;
398 g_array_append_val (array, val);
399 val = 26;
400 g_array_append_val (array, val);
401 reqlen--;
402 }
403 val = 2;
404 g_array_append_val (array, val);
405 *ret = array;
406 return TRUE;
407 }
408
409 gboolean
my_object_many_uppercase(MyObject * obj,const char * const * in,char *** out,GError ** error)410 my_object_many_uppercase (MyObject *obj, const char * const *in, char ***out, GError **error)
411 {
412 int len;
413 int i;
414
415 len = g_strv_length ((char**) in);
416
417 *out = g_new0 (char *, len + 1);
418 for (i = 0; i < len; i++)
419 {
420 (*out)[i] = g_ascii_strup (in[i], -1);
421 }
422 (*out)[i] = NULL;
423
424 return TRUE;
425 }
426
427 static void
hash_foreach_stringify(gpointer key,gpointer val,gpointer user_data)428 hash_foreach_stringify (gpointer key, gpointer val, gpointer user_data)
429 {
430 const char *keystr = key;
431 const GValue *value = val;
432 GValue *sval;
433 GHashTable *ret = user_data;
434
435 sval = g_new0 (GValue, 1);
436 g_value_init (sval, G_TYPE_STRING);
437 if (!g_value_transform (value, sval))
438 g_assert_not_reached ();
439
440 g_hash_table_insert (ret, g_strdup (keystr), sval);
441 }
442
443 static void
unset_and_free_gvalue(gpointer val)444 unset_and_free_gvalue (gpointer val)
445 {
446 g_value_unset (val);
447 g_free (val);
448 }
449
450 gboolean
my_object_many_stringify(MyObject * obj,GHashTable * vals,GHashTable ** ret,GError ** error)451 my_object_many_stringify (MyObject *obj, GHashTable /* char * -> GValue * */ *vals, GHashTable /* char * -> GValue * */ **ret, GError **error)
452 {
453 *ret = g_hash_table_new_full (g_str_hash, g_str_equal,
454 g_free, unset_and_free_gvalue);
455 g_hash_table_foreach (vals, hash_foreach_stringify, *ret);
456 return TRUE;
457 }
458
459 gboolean
my_object_rec_arrays(MyObject * obj,GPtrArray * in,GPtrArray ** ret,GError ** error)460 my_object_rec_arrays (MyObject *obj, GPtrArray *in, GPtrArray **ret, GError **error)
461 {
462 char **strs;
463 GArray *ints;
464 guint v_UINT;
465
466 if (in->len != 2)
467 {
468 g_set_error (error,
469 MY_OBJECT_ERROR,
470 MY_OBJECT_ERROR_FOO,
471 "invalid array len");
472 return FALSE;
473 }
474
475 strs = g_ptr_array_index (in, 0);
476 if (!*strs || strcmp (*strs, "foo"))
477 {
478 g_set_error (error,
479 MY_OBJECT_ERROR,
480 MY_OBJECT_ERROR_FOO,
481 "invalid string 0");
482 return FALSE;
483 }
484 strs++;
485 if (!*strs || strcmp (*strs, "bar"))
486 {
487 g_set_error (error,
488 MY_OBJECT_ERROR,
489 MY_OBJECT_ERROR_FOO,
490 "invalid string 1");
491 return FALSE;
492 }
493 strs++;
494 if (*strs)
495 {
496 g_set_error (error,
497 MY_OBJECT_ERROR,
498 MY_OBJECT_ERROR_FOO,
499 "invalid string array len in pos 0");
500 return FALSE;
501 }
502 strs = g_ptr_array_index (in, 1);
503 if (!*strs || strcmp (*strs, "baz"))
504 {
505 g_set_error (error,
506 MY_OBJECT_ERROR,
507 MY_OBJECT_ERROR_FOO,
508 "invalid string 0");
509 return FALSE;
510 }
511 strs++;
512 if (!*strs || strcmp (*strs, "whee"))
513 {
514 g_set_error (error,
515 MY_OBJECT_ERROR,
516 MY_OBJECT_ERROR_FOO,
517 "invalid string 1");
518 return FALSE;
519 }
520 strs++;
521 if (!*strs || strcmp (*strs, "moo"))
522 {
523 g_set_error (error,
524 MY_OBJECT_ERROR,
525 MY_OBJECT_ERROR_FOO,
526 "invalid string 2");
527 return FALSE;
528 }
529 strs++;
530 if (*strs)
531 {
532 g_set_error (error,
533 MY_OBJECT_ERROR,
534 MY_OBJECT_ERROR_FOO,
535 "invalid string array len in pos 1");
536 return FALSE;
537 }
538
539 *ret = g_ptr_array_new ();
540
541 ints = g_array_new (TRUE, TRUE, sizeof (guint));
542 v_UINT = 10;
543 g_array_append_val (ints, v_UINT);
544 v_UINT = 42;
545 g_array_append_val (ints, v_UINT);
546 v_UINT = 27;
547 g_array_append_val (ints, v_UINT);
548 g_ptr_array_add (*ret, ints);
549
550 ints = g_array_new (TRUE, TRUE, sizeof (guint));
551 v_UINT = 30;
552 g_array_append_val (ints, v_UINT);
553 g_ptr_array_add (*ret, ints);
554 return TRUE;
555 }
556
557 gboolean
my_object_objpath(MyObject * obj,const char * incoming,const char ** outgoing,GError ** error)558 my_object_objpath (MyObject *obj, const char *incoming, const char **outgoing, GError **error)
559 {
560 if (strcmp (incoming, "/org/freedesktop/DBus/GLib/Tests/MyTestObject"))
561 {
562 g_set_error (error,
563 MY_OBJECT_ERROR,
564 MY_OBJECT_ERROR_FOO,
565 "invalid incoming object");
566 return FALSE;
567 }
568 *outgoing = "/org/freedesktop/DBus/GLib/Tests/MyTestObject2";
569 return TRUE;
570 }
571
572 gboolean
my_object_get_objs(MyObject * obj,GPtrArray ** objs,GError ** error)573 my_object_get_objs (MyObject *obj, GPtrArray **objs, GError **error)
574 {
575 *objs = g_ptr_array_new ();
576
577 g_ptr_array_add (*objs, g_strdup ("/org/freedesktop/DBus/GLib/Tests/MyTestObject"));
578 g_ptr_array_add (*objs, g_strdup ("/org/freedesktop/DBus/GLib/Tests/MyTestObject2"));
579
580 return TRUE;
581 }
582
583 static void
hash_foreach(gpointer key,gpointer val,gpointer user_data)584 hash_foreach (gpointer key, gpointer val, gpointer user_data)
585 {
586 const char *keystr = key;
587 const char *valstr = val;
588 guint *count = user_data;
589
590 *count += (strlen (keystr) + strlen (valstr));
591 g_print ("%s -> %s\n", keystr, valstr);
592 }
593
594 gboolean
my_object_str_hash_len(MyObject * obj,GHashTable * table,guint * len,GError ** error)595 my_object_str_hash_len (MyObject *obj, GHashTable *table, guint *len, GError **error)
596 {
597 *len = 0;
598 g_hash_table_foreach (table, hash_foreach, len);
599 return TRUE;
600 }
601
602 gboolean
my_object_send_car(MyObject * obj,GValueArray * invals,GValueArray ** outvals,GError ** error)603 my_object_send_car (MyObject *obj, GValueArray *invals, GValueArray **outvals, GError **error)
604 {
605 if (invals->n_values != 3
606 || G_VALUE_TYPE (g_value_array_get_nth (invals, 0)) != G_TYPE_STRING
607 || G_VALUE_TYPE (g_value_array_get_nth (invals, 1)) != G_TYPE_UINT
608 || G_VALUE_TYPE (g_value_array_get_nth (invals, 2)) != G_TYPE_VALUE)
609 {
610 g_set_error (error,
611 MY_OBJECT_ERROR,
612 MY_OBJECT_ERROR_FOO,
613 "invalid incoming values");
614 return FALSE;
615 }
616 *outvals = g_value_array_new (2);
617 g_value_array_append (*outvals, NULL);
618 g_value_init (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1), G_TYPE_UINT);
619 g_value_set_uint (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1),
620 g_value_get_uint (g_value_array_get_nth (invals, 1)) + 1);
621 g_value_array_append (*outvals, NULL);
622 g_value_init (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1), DBUS_TYPE_G_OBJECT_PATH);
623 g_value_set_boxed (g_value_array_get_nth (*outvals, (*outvals)->n_values - 1),
624 g_strdup ("/org/freedesktop/DBus/GLib/Tests/MyTestObject2"));
625 return TRUE;
626 }
627
628 gboolean
my_object_get_hash(MyObject * obj,GHashTable ** ret,GError ** error)629 my_object_get_hash (MyObject *obj, GHashTable **ret, GError **error)
630 {
631 GHashTable *table;
632
633 table = g_hash_table_new (g_str_hash, g_str_equal);
634 g_hash_table_insert (table, "foo", "bar");
635 g_hash_table_insert (table, "baz", "whee");
636 g_hash_table_insert (table, "cow", "crack");
637 *ret = table;
638 return TRUE;
639 }
640
641 gboolean
my_object_increment_val(MyObject * obj,GError ** error)642 my_object_increment_val (MyObject *obj, GError **error)
643 {
644 obj->val++;
645 return TRUE;
646 }
647
648 gboolean
my_object_get_val(MyObject * obj,guint * ret,GError ** error)649 my_object_get_val (MyObject *obj, guint *ret, GError **error)
650 {
651 *ret = obj->val;
652 return TRUE;
653 }
654
655 gboolean
my_object_get_value(MyObject * obj,guint * ret,GError ** error)656 my_object_get_value (MyObject *obj, guint *ret, GError **error)
657 {
658 *ret = obj->val;
659 return TRUE;
660 }
661
662 gboolean
my_object_echo_variant(MyObject * obj,GValue * variant,GValue * ret,GError ** error)663 my_object_echo_variant (MyObject *obj, GValue *variant, GValue *ret, GError **error)
664 {
665 GType t;
666
667 obj->echo_variant_called++;
668
669 t = G_VALUE_TYPE(variant);
670 g_value_init (ret, t);
671 g_value_copy (variant, ret);
672
673 return TRUE;
674 }
675
676 gboolean
my_object_echo_signature(MyObject * obj,const gchar * in,gchar ** out,GError ** error)677 my_object_echo_signature (MyObject *obj, const gchar *in, gchar **out, GError **error)
678 {
679 *out = g_strdup (in);
680 return TRUE;
681 }
682
683 gboolean
my_object_process_variant_of_array_of_ints123(MyObject * obj,GValue * variant,GError ** error)684 my_object_process_variant_of_array_of_ints123 (MyObject *obj, GValue *variant, GError **error)
685 {
686 GArray *array;
687 int i;
688 int j;
689
690 j = 0;
691
692 array = (GArray *)g_value_get_boxed (variant);
693
694 for (i = 0; i <= 2; i++)
695 {
696 j = g_array_index (array, int, i);
697 if (j != i + 1)
698 goto error;
699 }
700
701 return TRUE;
702
703 error:
704 *error = g_error_new (MY_OBJECT_ERROR,
705 MY_OBJECT_ERROR_FOO,
706 "Error decoding a variant of type ai (i + 1 = %i, j = %i)",
707 i, j + 1);
708 return FALSE;
709 }
710
711
712 typedef struct _HashAndString HashAndString;
713
714 struct _HashAndString
715 {
716 GHashTable *hash;
717 gchar* string;
718 };
719
720 static void
hash_foreach_prepend_string(gpointer key,gpointer val,gpointer user_data)721 hash_foreach_prepend_string (gpointer key, gpointer val, gpointer user_data)
722 {
723 HashAndString *data = (HashAndString*) user_data;
724 gchar *in = (gchar*) val;
725 g_hash_table_insert (data->hash, g_strdup ((gchar*) key),
726 g_strjoin (" ", data->string, in, NULL));
727 }
728
729
730 static void
hash_foreach_mangle_dict_of_strings(gpointer key,gpointer val,gpointer user_data)731 hash_foreach_mangle_dict_of_strings (gpointer key, gpointer val, gpointer user_data)
732 {
733 GHashTable *out = (GHashTable*) user_data;
734 GHashTable *in_dict = (GHashTable *) val;
735 HashAndString *data = g_new0 (HashAndString, 1);
736
737 data->string = (gchar*) key;
738 data->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
739 g_free, g_free);
740 g_hash_table_foreach (in_dict, hash_foreach_prepend_string, data);
741
742 g_hash_table_insert(out, g_strdup ((gchar*) key), data->hash);
743 }
744
745 gboolean
my_object_dict_of_dicts(MyObject * obj,GHashTable * in,GHashTable ** out,GError ** error)746 my_object_dict_of_dicts (MyObject *obj, GHashTable *in,
747 GHashTable **out, GError **error)
748 {
749 *out = g_hash_table_new_full (g_str_hash, g_str_equal,
750 (GDestroyNotify) g_free,
751 (GDestroyNotify) g_hash_table_destroy);
752 g_hash_table_foreach (in, hash_foreach_mangle_dict_of_strings, *out);
753 return TRUE;
754 }
755
756 void
my_object_dict_of_sigs(MyObject * obj,GHashTable * dict,DBusGMethodInvocation * context)757 my_object_dict_of_sigs (MyObject *obj,
758 GHashTable *dict,
759 DBusGMethodInvocation *context)
760 {
761 dbus_g_method_return (context, dict);
762 }
763
764 void
my_object_dict_of_objs(MyObject * obj,GHashTable * dict,DBusGMethodInvocation * context)765 my_object_dict_of_objs (MyObject *obj,
766 GHashTable *dict,
767 DBusGMethodInvocation *context)
768 {
769 dbus_g_method_return (context, dict);
770 }
771
772 gboolean
my_object_emit_frobnicate(MyObject * obj,GError ** error)773 my_object_emit_frobnicate (MyObject *obj, GError **error)
774 {
775 g_signal_emit (obj, signals[FROBNICATE], 0, 42);
776 return TRUE;
777 }
778
779 gboolean
my_object_emit_signals(MyObject * obj,GError ** error)780 my_object_emit_signals (MyObject *obj, GError **error)
781 {
782 GValue val = {0, };
783
784 g_signal_emit (obj, signals[SIG0], 0, "foo", 22, "moo");
785
786 g_value_init (&val, G_TYPE_STRING);
787 g_value_set_string (&val, "bar");
788 g_signal_emit (obj, signals[SIG1], 0, "baz", &val);
789 g_value_unset (&val);
790
791 return TRUE;
792 }
793
794 gboolean
my_object_emit_signal2(MyObject * obj,GError ** error)795 my_object_emit_signal2 (MyObject *obj, GError **error)
796 {
797 GHashTable *table;
798
799 table = g_hash_table_new (g_str_hash, g_str_equal);
800 g_hash_table_insert (table, "baz", "cow");
801 g_hash_table_insert (table, "bar", "foo");
802 g_signal_emit (obj, signals[SIG2], 0, table);
803 g_hash_table_destroy (table);
804 return TRUE;
805 }
806
807 typedef struct {
808 gint32 x;
809 DBusGMethodInvocation *context;
810 } IncrementData;
811
812 static gboolean
do_async_increment(IncrementData * data)813 do_async_increment (IncrementData *data)
814 {
815 gint32 newx = data->x + 1;
816 dbus_g_method_return (data->context, newx);
817 g_free (data);
818 return FALSE;
819 }
820
821 void
my_object_async_increment(MyObject * obj,gint32 x,DBusGMethodInvocation * context)822 my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *context)
823 {
824 IncrementData *data = g_new0 (IncrementData, 1);
825 data->x = x;
826 data->context = context;
827 g_idle_add ((GSourceFunc)do_async_increment, data);
828 }
829
830 typedef struct {
831 GError *error;
832 DBusGMethodInvocation *context;
833 } ErrorData;
834
835 static gboolean
do_async_error(ErrorData * data)836 do_async_error (ErrorData *data)
837 {
838 dbus_g_method_return_error (data->context, data->error);
839 g_error_free (data->error);
840 g_free (data);
841 return FALSE;
842 }
843
844 void
my_object_async_throw_error(MyObject * obj,DBusGMethodInvocation * context)845 my_object_async_throw_error (MyObject *obj, DBusGMethodInvocation *context)
846 {
847 ErrorData *data = g_new0 (ErrorData, 1);
848
849 data->error = g_error_copy (obj->saved_error);
850 data->context = context;
851 g_idle_add ((GSourceFunc) do_async_error, data);
852 }
853
854 gboolean
my_object_unsafe_disable_legacy_property_access(MyObject * obj,GError ** error)855 my_object_unsafe_disable_legacy_property_access (MyObject *obj,
856 GError **error)
857 {
858 dbus_glib_global_set_disable_legacy_property_access ();
859 return TRUE;
860 }
861
862 extern GMainLoop *loop;
863
864 gboolean
my_object_terminate(MyObject * obj,GError ** error)865 my_object_terminate (MyObject *obj, GError **error)
866 {
867 g_main_loop_quit (loop);
868 return TRUE;
869 }
870
871 void
my_object_emit_objectified(MyObject * obj,GObject * other)872 my_object_emit_objectified (MyObject *obj,
873 GObject *other)
874 {
875 g_signal_emit (obj, signals[OBJECTIFIED], 0, other);
876 }
877