source: trunk/third/glib2/gobject/testoverride.c @ 18159

Revision 18159, 9.5 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18158, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- mode: C; c-basic-offset: 4 -*- */
2#include <glib.h>
3#include <glib-object.h>
4
5static guint foo_signal_id = 0;
6static guint bar_signal_id = 0;
7
8
9static GType test_i_get_type (void);
10static GType test_a_get_type (void);
11static GType test_b_get_type (void);
12static 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
21typedef struct _TestI TestI;
22typedef struct _TestIClass TestIClass;
23
24struct _TestIClass {
25    GTypeInterface base_iface;
26};
27
28static void
29test_i_foo (TestI *self)
30{
31    g_print("TestI::foo called.\n");
32}
33
34
35static void
36test_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
53static GType
54test_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
81typedef struct _TestA TestA;
82typedef struct _TestAClass TestAClass;
83
84struct _TestA {
85    GObject parent;
86};
87struct _TestAClass {
88    GObjectClass parent_class;
89
90    void (* bar) (TestA *self);
91};
92
93static void
94test_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_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
104    g_signal_chain_from_overridden (args, NULL);
105
106    g_value_unset (&args[0]);
107}
108
109static void
110test_a_bar (TestA *self)
111{
112    g_print("TestA::bar called.\n");
113}
114
115static void
116test_a_class_init (TestAClass *class)
117{
118    class->bar = test_a_bar;
119
120    bar_signal_id = g_signal_new("bar",
121                                 TEST_TYPE_A,
122                                 G_SIGNAL_RUN_LAST,
123                                 G_STRUCT_OFFSET (TestAClass, bar),
124                                 NULL, NULL,
125                                 g_cclosure_marshal_VOID__VOID,
126                                 G_TYPE_NONE, 0);
127}
128
129static void
130test_a_interface_init (TestIClass *iface)
131{
132    g_signal_override_class_closure (foo_signal_id,
133                                     TEST_TYPE_A,
134                                     g_cclosure_new (G_CALLBACK (test_a_foo),
135                                                     NULL, NULL));
136}
137
138static GType
139test_a_get_type (void)
140{
141    static GType type = 0;
142 
143    if (!type) {
144        static const GTypeInfo type_info = {
145            sizeof(TestAClass),
146            (GBaseInitFunc) NULL,
147            (GBaseFinalizeFunc) NULL,
148            (GClassInitFunc) test_a_class_init,
149            NULL, /* class_finalize */
150            NULL, /* class_data */
151            sizeof(TestAClass),
152            0, /* n_preallocs */
153            (GInstanceInitFunc) NULL,
154        };
155        static const GInterfaceInfo interface_info = {
156            (GInterfaceInitFunc) test_a_interface_init,
157            NULL,
158            NULL
159        };
160
161        type = g_type_register_static (G_TYPE_OBJECT, "TestA",
162                                       &type_info, 0);
163        g_type_add_interface_static (type, TEST_TYPE_I, &interface_info);
164    }
165 
166  return type;
167}
168
169
170#define TEST_TYPE_B (test_b_get_type())
171#define TEST_B(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_B, TestB))
172#define TEST_B_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_B, TestBClass))
173#define TEST_IS_B(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_B))
174#define TEST_IS_B_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_B))
175#define TEST_B_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_B, TestBClass))
176
177typedef struct _TestB TestB;
178typedef struct _TestBClass TestBClass;
179
180struct _TestB {
181    TestA parent;
182};
183struct _TestBClass {
184    TestAClass parent_class;
185};
186
187static void
188test_b_foo (TestA *self)
189{
190    GValue args[1] = { { 0, } };
191
192    g_print("TestB::foo called.  Chaining up.\n");
193
194    g_value_init (&args[0], TEST_TYPE_A);
195    g_value_set_object (&args[0], self);
196
197    g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
198    g_signal_chain_from_overridden (args, NULL);
199
200    g_value_unset (&args[0]);
201}
202
203static void
204test_b_bar (TestI *self)
205{
206    GValue args[1] = { { 0, } };
207
208    g_print("TestB::bar called.  Chaining up.\n");
209
210    g_value_init (&args[0], TEST_TYPE_A);
211    g_value_set_object (&args[0], self);
212
213    g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
214    g_signal_chain_from_overridden (args, NULL);
215
216    g_value_unset (&args[0]);
217}
218
219static void
220test_b_class_init (TestBClass *class)
221{
222    g_signal_override_class_closure (foo_signal_id,
223                                     TEST_TYPE_B,
224                                     g_cclosure_new (G_CALLBACK (test_b_foo),
225                                                     NULL, NULL));
226    g_signal_override_class_closure (bar_signal_id,
227                                     TEST_TYPE_B,
228                                     g_cclosure_new (G_CALLBACK (test_b_bar),
229                                                     NULL, NULL));
230}
231
232static GType
233test_b_get_type (void)
234{
235    static GType type = 0;
236 
237    if (!type) {
238        static const GTypeInfo type_info = {
239            sizeof(TestBClass),
240            (GBaseInitFunc) NULL,
241            (GBaseFinalizeFunc) NULL,
242            (GClassInitFunc) test_b_class_init,
243            NULL, /* class_finalize */
244            NULL, /* class_data */
245            sizeof(TestBClass),
246            0, /* n_preallocs */
247            (GInstanceInitFunc) NULL,
248        };
249
250        type = g_type_register_static (TEST_TYPE_A, "TestB",
251                                       &type_info, 0);
252    }
253 
254  return type;
255}
256
257
258#define TEST_TYPE_C (test_c_get_type())
259#define TEST_C(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_C, TestC))
260#define TEST_C_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_C, TestCClass))
261#define TEST_IS_C(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_C))
262#define TEST_IS_C_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_C))
263#define TEST_C_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_C, TestCClass))
264
265typedef struct _TestC TestC;
266typedef struct _TestCClass TestCClass;
267
268struct _TestC {
269    TestB parent;
270};
271struct _TestCClass {
272    TestBClass parent_class;
273};
274
275static void
276test_c_foo (TestA *self)
277{
278    GValue args[1] = { { 0, } };
279
280    g_print("TestC::foo called.  Chaining up.\n");
281
282    g_value_init (&args[0], TEST_TYPE_A);
283    g_value_set_object (&args[0], self);
284
285    g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
286    g_signal_chain_from_overridden (args, NULL);
287
288    g_value_unset (&args[0]);
289}
290
291static void
292test_c_bar (TestI *self)
293{
294    GValue args[1] = { { 0, } };
295
296    g_print("TestC::bar called.  Chaining up.\n");
297
298    g_value_init (&args[0], TEST_TYPE_A);
299    g_value_set_object (&args[0], self);
300
301    g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
302    g_signal_chain_from_overridden (args, NULL);
303
304    g_value_unset (&args[0]);
305}
306
307static void
308test_c_class_init (TestBClass *class)
309{
310    g_signal_override_class_closure (foo_signal_id,
311                                     TEST_TYPE_C,
312                                     g_cclosure_new (G_CALLBACK (test_c_foo),
313                                                     NULL, NULL));
314    g_signal_override_class_closure (bar_signal_id,
315                                     TEST_TYPE_C,
316                                     g_cclosure_new (G_CALLBACK (test_c_bar),
317                                                     NULL, NULL));
318}
319
320static GType
321test_c_get_type (void)
322{
323    static GType type = 0;
324 
325    if (!type) {
326        static const GTypeInfo type_info = {
327            sizeof(TestCClass),
328            (GBaseInitFunc) NULL,
329            (GBaseFinalizeFunc) NULL,
330            (GClassInitFunc) test_c_class_init,
331            NULL, /* class_finalize */
332            NULL, /* class_data */
333            sizeof(TestCClass),
334            0, /* n_preallocs */
335            (GInstanceInitFunc) NULL,
336        };
337
338        type = g_type_register_static (TEST_TYPE_B, "TestC",
339                                       &type_info, 0);
340    }
341 
342  return type;
343}
344
345
346int
347main (int argc, char **argv)
348{
349    GObject *self;
350
351    g_type_init();
352
353    self = g_object_new(TEST_TYPE_A, NULL);
354    g_print("*** emiting foo on a TestA instance (expect chain A->I)\n");
355    g_signal_emit(self, foo_signal_id, 0);
356    g_print("*** emiting bar on a TestA instance\n");
357    g_signal_emit(self, bar_signal_id, 0);
358    g_object_unref(self);
359
360    g_print("\n");
361
362    self = g_object_new(TEST_TYPE_B, NULL);
363    g_print("*** emiting foo on a TestB instance (expect chain B->A->I)\n");
364    g_signal_emit(self, foo_signal_id, 0);
365    g_print("*** emiting bar on a TestB instance (expect chain B->A)\n");
366    g_signal_emit(self, bar_signal_id, 0);
367    g_object_unref(self);
368
369    g_print("\n");
370
371    self = g_object_new(TEST_TYPE_C, NULL);
372    g_print("*** emiting foo on a TestC instance (expect chain C->B->A->I)\n");
373    g_signal_emit(self, foo_signal_id, 0);
374    g_print("*** emiting bar on a TestC instance (expect chain C->B->A)\n");
375    g_signal_emit(self, bar_signal_id, 0);
376    g_object_unref(self);
377
378    return 0;
379}
Note: See TracBrowser for help on using the repository browser.