add rules to build it.
[platform/upstream/glib.git] / tests / gobject / override.c
1 /* -*- mode: C; c-basic-offset: 4 -*- */
2 #include <glib.h>
3 #include <glib-object.h>
4
5 static guint foo_signal_id = 0;
6 static guint bar_signal_id = 0;
7
8
9 static GType test_i_get_type (void);
10 static GType test_a_get_type (void);
11 static GType test_b_get_type (void);
12 static GType test_c_get_type (void);
13
14 #define TEST_TYPE_I (test_i_get_type ())
15 #define TEST_I(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_I, TestI))
16 #define TEST_I_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), TEST_TYPE_I, TestIClass))
17 #define TEST_IS_I(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_I))
18 #define TEST_IS_I_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), TEST_TYPE_I))
19 #define TEST_I_GET_CLASS(object) (G_TYPE_INSTANCE_GET_INTERFACE((object), TEST_TYPE_I, TestIClass))
20
21 typedef struct _TestI TestI;
22 typedef struct _TestIClass TestIClass;
23
24 struct _TestIClass {
25     GTypeInterface base_iface;
26 };
27
28 static void
29 test_i_foo (TestI *self)
30 {
31     g_print("TestI::foo called.\n");
32 }
33
34
35 static void
36 test_i_base_init (gpointer g_class)
37 {
38     static gboolean initialised = FALSE;
39
40     if (!initialised) {
41         foo_signal_id = g_signal_newv("foo",
42                                       TEST_TYPE_I,
43                                       G_SIGNAL_RUN_LAST,
44                                       g_cclosure_new(G_CALLBACK(test_i_foo),
45                                                      NULL, NULL),
46                                       NULL, NULL,
47                                       g_cclosure_marshal_VOID__VOID,
48                                       G_TYPE_NONE, 0, NULL);
49     }
50     initialised = TRUE;
51 }
52
53 static GType
54 test_i_get_type (void)
55 {
56     static GType type = 0;
57   
58     if (!type) {
59         static const GTypeInfo type_info = {
60             sizeof (TestIClass),
61             (GBaseInitFunc) test_i_base_init, /* base_init */
62             NULL,             /* base_finalize */
63         };
64       
65         type = g_type_register_static (G_TYPE_INTERFACE, "TestI",
66                                        &type_info, 0);
67     }
68   
69     return type;
70 }
71
72
73
74 #define TEST_TYPE_A (test_a_get_type())
75 #define TEST_A(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_A, TestA))
76 #define TEST_A_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_A, TestAClass))
77 #define TEST_IS_A(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_A))
78 #define TEST_IS_A_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_A))
79 #define TEST_A_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_A, TestAClass))
80
81 typedef struct _TestA TestA;
82 typedef struct _TestAClass TestAClass;
83
84 struct _TestA {
85     GObject parent;
86 };
87 struct _TestAClass {
88     GObjectClass parent_class;
89
90     void (* bar) (TestA *self);
91 };
92
93 static void
94 test_a_foo (TestI *self)
95 {
96     GValue args[1] = { { 0, } };
97
98     g_print("TestA::foo called.  Chaining up.\n");
99
100     g_value_init (&args[0], TEST_TYPE_A);
101     g_value_set_object (&args[0], self);
102
103     g_signal_chain_from_overridden (args, foo_signal_id, NULL);
104
105     g_value_unset (&args[0]);
106 }
107
108 static void
109 test_a_bar (TestA *self)
110 {
111     g_print("TestA::bar called.\n");
112 }
113
114 static void
115 test_a_class_init (TestAClass *class)
116 {
117     class->bar = test_a_bar;
118
119     bar_signal_id = g_signal_new("bar",
120                                  TEST_TYPE_A,
121                                  G_SIGNAL_RUN_LAST,
122                                  G_STRUCT_OFFSET (TestAClass, bar),
123                                  NULL, NULL,
124                                  g_cclosure_marshal_VOID__VOID,
125                                  G_TYPE_NONE, 0);
126 }
127
128 static void
129 test_a_interface_init (TestIClass *iface)
130 {
131     g_signal_override_class_closure (foo_signal_id,
132                                      TEST_TYPE_A,
133                                      g_cclosure_new (G_CALLBACK (test_a_foo),
134                                                      NULL, NULL));
135 }
136
137 static GType
138 test_a_get_type (void)
139 {
140     static GType type = 0;
141   
142     if (!type) {
143         static const GTypeInfo type_info = {
144             sizeof(TestAClass),
145             (GBaseInitFunc) NULL,
146             (GBaseFinalizeFunc) NULL,
147             (GClassInitFunc) test_a_class_init,
148             NULL, /* class_finalize */
149             NULL, /* class_data */
150             sizeof(TestAClass),
151             0, /* n_preallocs */
152             (GInstanceInitFunc) NULL,
153         };
154         static const GInterfaceInfo interface_info = {
155             (GInterfaceInitFunc) test_a_interface_init,
156             NULL,
157             NULL
158         };
159
160         type = g_type_register_static (G_TYPE_OBJECT, "TestA",
161                                        &type_info, 0);
162         g_type_add_interface_static (type, TEST_TYPE_I, &interface_info);
163     }
164   
165   return type;
166 }
167
168
169 #define TEST_TYPE_B (test_b_get_type())
170 #define TEST_B(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_B, TestB))
171 #define TEST_B_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_B, TestBClass))
172 #define TEST_IS_B(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_B))
173 #define TEST_IS_B_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_B))
174 #define TEST_B_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_B, TestBClass))
175
176 typedef struct _TestB TestB;
177 typedef struct _TestBClass TestBClass;
178
179 struct _TestB {
180     TestA parent;
181 };
182 struct _TestBClass {
183     TestAClass parent_class;
184 };
185
186 static void
187 test_b_foo (TestA *self)
188 {
189     GValue args[1] = { { 0, } };
190
191     g_print("TestB::foo called.  Chaining up.\n");
192
193     g_value_init (&args[0], TEST_TYPE_A);
194     g_value_set_object (&args[0], self);
195
196     g_signal_chain_from_overridden (args, foo_signal_id, NULL);
197
198     g_value_unset (&args[0]);
199 }
200
201 static void
202 test_b_bar (TestI *self)
203 {
204     GValue args[1] = { { 0, } };
205
206     g_print("TestB::bar called.  Chaining up.\n");
207
208     g_value_init (&args[0], TEST_TYPE_A);
209     g_value_set_object (&args[0], self);
210
211     g_signal_chain_from_overridden (args, bar_signal_id, NULL);
212
213     g_value_unset (&args[0]);
214 }
215
216 static void
217 test_b_class_init (TestBClass *class)
218 {
219     g_signal_override_class_closure (foo_signal_id,
220                                      TEST_TYPE_B,
221                                      g_cclosure_new (G_CALLBACK (test_b_foo),
222                                                      NULL, NULL));
223     g_signal_override_class_closure (bar_signal_id,
224                                      TEST_TYPE_B,
225                                      g_cclosure_new (G_CALLBACK (test_b_bar),
226                                                      NULL, NULL));
227 }
228
229 static GType
230 test_b_get_type (void)
231 {
232     static GType type = 0;
233   
234     if (!type) {
235         static const GTypeInfo type_info = {
236             sizeof(TestBClass),
237             (GBaseInitFunc) NULL,
238             (GBaseFinalizeFunc) NULL,
239             (GClassInitFunc) test_b_class_init,
240             NULL, /* class_finalize */
241             NULL, /* class_data */
242             sizeof(TestBClass),
243             0, /* n_preallocs */
244             (GInstanceInitFunc) NULL,
245         };
246
247         type = g_type_register_static (TEST_TYPE_A, "TestB",
248                                        &type_info, 0);
249     }
250   
251   return type;
252 }
253
254
255 #define TEST_TYPE_C (test_c_get_type())
256 #define TEST_C(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_C, TestC))
257 #define TEST_C_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_C, TestCClass))
258 #define TEST_IS_C(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_C))
259 #define TEST_IS_C_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_C))
260 #define TEST_C_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_C, TestCClass))
261
262 typedef struct _TestC TestC;
263 typedef struct _TestCClass TestCClass;
264
265 struct _TestC {
266     TestB parent;
267 };
268 struct _TestCClass {
269     TestBClass parent_class;
270 };
271
272 static void
273 test_c_foo (TestA *self)
274 {
275     GValue args[1] = { { 0, } };
276
277     g_print("TestC::foo called.  Chaining up.\n");
278
279     g_value_init (&args[0], TEST_TYPE_A);
280     g_value_set_object (&args[0], self);
281
282     g_signal_chain_from_overridden (args, foo_signal_id, NULL);
283
284     g_value_unset (&args[0]);
285 }
286
287 static void
288 test_c_bar (TestI *self)
289 {
290     GValue args[1] = { { 0, } };
291
292     g_print("TestC::bar called.  Chaining up.\n");
293
294     g_value_init (&args[0], TEST_TYPE_A);
295     g_value_set_object (&args[0], self);
296
297     g_signal_chain_from_overridden (args, bar_signal_id, NULL);
298
299     g_value_unset (&args[0]);
300 }
301
302 static void
303 test_c_class_init (TestBClass *class)
304 {
305     g_signal_override_class_closure (foo_signal_id,
306                                      TEST_TYPE_C,
307                                      g_cclosure_new (G_CALLBACK (test_c_foo),
308                                                      NULL, NULL));
309     g_signal_override_class_closure (bar_signal_id,
310                                      TEST_TYPE_C,
311                                      g_cclosure_new (G_CALLBACK (test_c_bar),
312                                                      NULL, NULL));
313 }
314
315 static GType
316 test_c_get_type (void)
317 {
318     static GType type = 0;
319   
320     if (!type) {
321         static const GTypeInfo type_info = {
322             sizeof(TestCClass),
323             (GBaseInitFunc) NULL,
324             (GBaseFinalizeFunc) NULL,
325             (GClassInitFunc) test_c_class_init,
326             NULL, /* class_finalize */
327             NULL, /* class_data */
328             sizeof(TestCClass),
329             0, /* n_preallocs */
330             (GInstanceInitFunc) NULL,
331         };
332
333         type = g_type_register_static (TEST_TYPE_B, "TestC",
334                                        &type_info, 0);
335     }
336   
337   return type;
338 }
339
340
341 int
342 main (int argc, char **argv)
343 {
344     GObject *self;
345
346     g_type_init();
347
348     self = g_object_new(TEST_TYPE_A, NULL);
349     g_print("*** emiting foo on a TestA instance (expect chain A->I)\n");
350     g_signal_emit(self, foo_signal_id, 0);
351     g_print("*** emiting bar on a TestA instance\n");
352     g_signal_emit(self, bar_signal_id, 0);
353     g_object_unref(self);
354
355     g_print("\n");
356
357     self = g_object_new(TEST_TYPE_B, NULL);
358     g_print("*** emiting foo on a TestB instance (expect chain B->A->I)\n");
359     g_signal_emit(self, foo_signal_id, 0);
360     g_print("*** emiting bar on a TestB instance (expect chain B->A)\n");
361     g_signal_emit(self, bar_signal_id, 0);
362     g_object_unref(self);
363
364     g_print("\n");
365
366     self = g_object_new(TEST_TYPE_C, NULL);
367     g_print("*** emiting foo on a TestC instance (expect chain C->B->A->I)\n");
368     g_signal_emit(self, foo_signal_id, 0);
369     g_print("*** emiting bar on a TestC instance (expect chain C->B->A)\n");
370     g_signal_emit(self, bar_signal_id, 0);
371     g_object_unref(self);
372
373     return 0;
374 }