tests: fix generic closure marshalling tests
[platform/upstream/glib.git] / gobject / tests / signals.c
1 #include <glib-object.h>
2
3 typedef enum {
4   TEST_ENUM_NEGATIVE = -30,
5   TEST_ENUM_NONE = 0,
6   TEST_ENUM_FOO = 1,
7   TEST_ENUM_BAR = 2
8 } TestEnum;
9
10 typedef enum {
11   TEST_UNSIGNED_ENUM_FOO = 1,
12   TEST_UNSIGNED_ENUM_BAR = 0x80000000
13 } TestUnsignedEnum;
14
15 GType
16 test_enum_get_type (void)
17 {
18   static volatile gsize g_define_type_id__volatile = 0;
19
20   if (g_once_init_enter (&g_define_type_id__volatile))
21     {
22       static const GEnumValue values[] = {
23         { TEST_ENUM_NEGATIVE, "TEST_ENUM_NEGATIVE", "negative" },
24         { TEST_ENUM_NONE, "TEST_ENUM_NONE", "none" },
25         { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" },
26         { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" },
27         { 0, NULL, NULL }
28       };
29       GType g_define_type_id =
30         g_enum_register_static (g_intern_static_string ("TestEnum"), values);
31       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
32     }
33
34   return g_define_type_id__volatile;
35 }
36
37 GType
38 test_unsigned_enum_get_type (void)
39 {
40   static volatile gsize g_define_type_id__volatile = 0;
41
42   if (g_once_init_enter (&g_define_type_id__volatile))
43     {
44       static const GEnumValue values[] = {
45         { TEST_UNSIGNED_ENUM_FOO, "TEST_UNSIGNED_ENUM_FOO", "foo" },
46         { TEST_UNSIGNED_ENUM_BAR, "TEST_UNSIGNED_ENUM_BAR", "bar" },
47         { 0, NULL, NULL }
48       };
49       GType g_define_type_id =
50         g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values);
51       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
52     }
53
54   return g_define_type_id__volatile;
55 }
56
57
58 typedef struct _Test Test;
59 typedef struct _TestClass TestClass;
60
61 struct _Test
62 {
63   GObject parent_instance;
64 };
65
66 struct _TestClass
67 {
68   GObjectClass parent_class;
69
70   void (* variant_changed) (Test *, GVariant *);
71 };
72
73 static GType test_get_type (void);
74 G_DEFINE_TYPE (Test, test, G_TYPE_OBJECT)
75
76 static void
77 test_init (Test *test)
78 {
79 }
80
81 static void
82 test_class_init (TestClass *klass)
83 {
84   g_signal_new ("generic-marshaller-1",
85                 G_TYPE_FROM_CLASS (klass),
86                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
87                 0,
88                 NULL, NULL,
89                 NULL,
90                 G_TYPE_NONE,
91                 7,
92                 G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_INT, G_TYPE_LONG, G_TYPE_POINTER, G_TYPE_DOUBLE, G_TYPE_FLOAT);
93   g_signal_new ("generic-marshaller-2",
94                 G_TYPE_FROM_CLASS (klass),
95                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
96                 0,
97                 NULL, NULL,
98                 NULL,
99                 G_TYPE_NONE,
100                 5,
101                 G_TYPE_INT, test_enum_get_type(), G_TYPE_INT, test_unsigned_enum_get_type (), G_TYPE_INT);
102   g_signal_new ("generic-marshaller-enum-return-signed",
103                 G_TYPE_FROM_CLASS (klass),
104                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
105                 0,
106                 NULL, NULL,
107                 NULL,
108                 test_enum_get_type(),
109                 0);
110   g_signal_new ("generic-marshaller-enum-return-unsigned",
111                 G_TYPE_FROM_CLASS (klass),
112                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
113                 0,
114                 NULL, NULL,
115                 NULL,
116                 test_unsigned_enum_get_type(),
117                 0);
118   g_signal_new ("variant-changed-no-slot",
119                 G_TYPE_FROM_CLASS (klass),
120                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
121                 0,
122                 NULL, NULL,
123                 g_cclosure_marshal_VOID__VARIANT,
124                 G_TYPE_NONE,
125                 1,
126                 G_TYPE_VARIANT);
127   g_signal_new ("variant-changed",
128                 G_TYPE_FROM_CLASS (klass),
129                 G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
130                 G_STRUCT_OFFSET (TestClass, variant_changed),
131                 NULL, NULL,
132                 g_cclosure_marshal_VOID__VARIANT,
133                 G_TYPE_NONE,
134                 1,
135                 G_TYPE_VARIANT);
136 }
137
138 static void
139 test_variant_signal (void)
140 {
141   Test *test;
142   GVariant *v;
143
144   /* Tests that the signal emission consumes the variant,
145    * even if there are no handlers connected.
146    */
147
148   test = g_object_new (test_get_type (), NULL);
149
150   v = g_variant_new_boolean (TRUE);
151   g_variant_ref (v);
152   g_assert (g_variant_is_floating (v));
153   g_signal_emit_by_name (test, "variant-changed-no-slot", v);
154   g_assert (!g_variant_is_floating (v));
155   g_variant_unref (v);
156
157   v = g_variant_new_boolean (TRUE);
158   g_variant_ref (v);
159   g_assert (g_variant_is_floating (v));
160   g_signal_emit_by_name (test, "variant-changed", v);
161   g_assert (!g_variant_is_floating (v));
162   g_variant_unref (v);
163
164   g_object_unref (test);
165 }
166
167 static void
168 on_generic_marshaller_1 (Test *obj,
169                          gint8 v_schar,
170                          guint8 v_uchar,
171                          gint v_int,
172                          glong v_long,
173                          gpointer v_pointer,
174                          gdouble v_double,
175                          gfloat v_float,
176                          gpointer user_data)
177 {
178   g_assert_cmpint (v_schar, ==, 42);
179   g_assert_cmpint (v_uchar, ==, 43);
180   g_assert_cmpint (v_int, ==, 4096);
181   g_assert_cmpint (v_long, ==, 8192);
182   g_assert (v_pointer == NULL);
183   g_assert_cmpfloat (v_double, >, 0.0);
184   g_assert_cmpfloat (v_double, <, 1.0);
185   g_assert_cmpfloat (v_float, >, 5.0);
186   g_assert_cmpfloat (v_float, <, 6.0);
187 }
188                          
189 static void
190 test_generic_marshaller_signal_1 (void)
191 {
192   Test *test;
193   test = g_object_new (test_get_type (), NULL);
194
195   g_signal_connect (test, "generic-marshaller-1", G_CALLBACK (on_generic_marshaller_1), NULL);
196
197   g_signal_emit_by_name (test, "generic-marshaller-1", 42, 43, 4096, 8192, NULL, 0.5, 5.5);
198
199   g_object_unref (test);
200 }
201
202 static void
203 on_generic_marshaller_2 (Test *obj,
204                          gint        v_int1,
205                          TestEnum    v_enum,
206                          gint        v_int2,
207                          TestUnsignedEnum v_uenum,
208                          gint        v_int3)
209 {
210   g_assert_cmpint (v_int1, ==, 42);
211   g_assert_cmpint (v_enum, ==, TEST_ENUM_BAR);
212   g_assert_cmpint (v_int2, ==, 43);
213   g_assert_cmpint (v_uenum, ==, TEST_UNSIGNED_ENUM_BAR);
214   g_assert_cmpint (v_int3, ==, 44);
215 }
216
217 static void
218 test_generic_marshaller_signal_2 (void)
219 {
220   Test *test;
221   test = g_object_new (test_get_type (), NULL);
222
223   g_signal_connect (test, "generic-marshaller-2", G_CALLBACK (on_generic_marshaller_2), NULL);
224
225   g_signal_emit_by_name (test, "generic-marshaller-2", 42, TEST_ENUM_BAR, 43, TEST_UNSIGNED_ENUM_BAR, 44);
226
227   g_object_unref (test);
228 }
229
230 static TestEnum
231 on_generic_marshaller_enum_return_signed_1 (Test *obj)
232 {
233   return TEST_ENUM_NEGATIVE;
234 }
235
236 static TestEnum
237 on_generic_marshaller_enum_return_signed_2 (Test *obj)
238 {
239   return TEST_ENUM_BAR;
240 }
241
242 static void
243 test_generic_marshaller_signal_enum_return_signed (void)
244 {
245   Test *test;
246   guint id;
247   TestEnum retval = 0;
248
249   test = g_object_new (test_get_type (), NULL);
250
251   /* Test return value NEGATIVE */
252   id = g_signal_connect (test,
253                          "generic-marshaller-enum-return-signed",
254                          G_CALLBACK (on_generic_marshaller_enum_return_signed_1),
255                          NULL);
256   g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval);
257   g_assert_cmpint (retval, ==, TEST_ENUM_NEGATIVE);
258   g_signal_handler_disconnect (test, id);
259
260   /* Test return value BAR */
261   retval = 0;
262   id = g_signal_connect (test,
263                          "generic-marshaller-enum-return-signed",
264                          G_CALLBACK (on_generic_marshaller_enum_return_signed_2),
265                          NULL);
266   g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval);
267   g_assert_cmpint (retval, ==, TEST_ENUM_BAR);
268   g_signal_handler_disconnect (test, id);
269
270   g_object_unref (test);
271 }
272
273 static TestUnsignedEnum
274 on_generic_marshaller_enum_return_unsigned_1 (Test *obj)
275 {
276   return TEST_UNSIGNED_ENUM_FOO;
277 }
278
279 static TestUnsignedEnum
280 on_generic_marshaller_enum_return_unsigned_2 (Test *obj)
281 {
282   return TEST_UNSIGNED_ENUM_BAR;
283 }
284
285 static void
286 test_generic_marshaller_signal_enum_return_unsigned (void)
287 {
288   Test *test;
289   guint id;
290   TestUnsignedEnum retval = 0;
291
292   test = g_object_new (test_get_type (), NULL);
293
294   /* Test return value FOO */
295   id = g_signal_connect (test,
296                          "generic-marshaller-enum-return-unsigned",
297                          G_CALLBACK (on_generic_marshaller_enum_return_unsigned_1),
298                          NULL);
299   g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval);
300   g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_FOO);
301   g_signal_handler_disconnect (test, id);
302
303   /* Test return value BAR */
304   retval = 0;
305   id = g_signal_connect (test,
306                          "generic-marshaller-enum-return-unsigned",
307                          G_CALLBACK (on_generic_marshaller_enum_return_unsigned_2),
308                          NULL);
309   g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval);
310   g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_BAR);
311   g_signal_handler_disconnect (test, id);
312
313   g_object_unref (test);
314 }
315
316 /* --- */
317
318 int
319 main (int argc,
320      char *argv[])
321 {
322   g_type_init ();
323
324   g_test_init (&argc, &argv, NULL);
325
326   g_test_add_func ("/gobject/signals/variant", test_variant_signal);
327   g_test_add_func ("/gobject/signals/generic-marshaller-1", test_generic_marshaller_signal_1);
328   g_test_add_func ("/gobject/signals/generic-marshaller-2", test_generic_marshaller_signal_2);
329   g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-signed", test_generic_marshaller_signal_enum_return_signed);
330   g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-unsigned", test_generic_marshaller_signal_enum_return_unsigned);
331
332   return g_test_run ();
333 }