1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * override.c: Closure override test program
3 * Copyright (C) 2001, James Henstridge
4 * Copyright (C) 2003, Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #define G_LOG_DOMAIN "TestOverride"
25 #undef G_DISABLE_ASSERT
26 #undef G_DISABLE_CHECKS
27 #undef G_DISABLE_CAST_CHECKS
34 #include <glib-object.h>
36 #include "testcommon.h"
38 static guint foo_signal_id = 0;
39 static guint bar_signal_id = 0;
41 static GType test_i_get_type (void);
42 static GType test_a_get_type (void);
43 static GType test_b_get_type (void);
44 static GType test_c_get_type (void);
46 static void record (const gchar *str);
48 #define TEST_TYPE_I (test_i_get_type ())
50 typedef struct _TestI TestI;
51 typedef struct _TestIClass TestIClass;
55 GTypeInterface base_iface;
59 test_i_foo (TestI *self)
61 record ("TestI::foo");
65 test_i_default_init (gpointer g_class)
67 foo_signal_id = g_signal_newv ("foo",
70 g_cclosure_new(G_CALLBACK(test_i_foo),
73 g_cclosure_marshal_VOID__VOID,
74 G_TYPE_NONE, 0, NULL);
77 static DEFINE_IFACE (TestI, test_i, NULL, test_i_default_init)
79 #define TEST_TYPE_A (test_a_get_type())
81 typedef struct _TestA TestA;
82 typedef struct _TestAClass TestAClass;
88 GObjectClass parent_class;
90 void (* bar) (TestA *self);
94 test_a_foo (TestI *self)
96 GValue args[1] = { { 0, } };
98 record ("TestA::foo");
100 g_value_init (&args[0], TEST_TYPE_A);
101 g_value_set_object (&args[0], self);
103 g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
104 g_signal_chain_from_overridden (args, NULL);
106 g_value_unset (&args[0]);
110 test_a_bar (TestA *self)
112 record ("TestA::bar");
116 test_a_class_init (TestAClass *class)
118 class->bar = test_a_bar;
120 bar_signal_id = g_signal_new ("bar",
123 G_STRUCT_OFFSET (TestAClass, bar),
125 g_cclosure_marshal_VOID__VOID,
126 G_TYPE_NONE, 0, NULL);
130 test_a_interface_init (TestIClass *iface)
132 g_signal_override_class_closure (foo_signal_id,
134 g_cclosure_new (G_CALLBACK (test_a_foo),
138 static DEFINE_TYPE_FULL (TestA, test_a,
139 test_a_class_init, NULL, NULL,
141 INTERFACE (test_a_interface_init, TEST_TYPE_I))
143 #define TEST_TYPE_B (test_b_get_type())
145 typedef struct _TestB TestB;
146 typedef struct _TestBClass TestBClass;
152 TestAClass parent_class;
156 test_b_foo (TestA *self)
158 GValue args[1] = { { 0, } };
160 record ("TestB::foo");
162 g_value_init (&args[0], TEST_TYPE_A);
163 g_value_set_object (&args[0], self);
165 g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
166 g_signal_chain_from_overridden (args, NULL);
168 g_value_unset (&args[0]);
172 test_b_bar (TestI *self)
174 GValue args[1] = { { 0, } };
176 record ("TestB::bar");
178 g_value_init (&args[0], TEST_TYPE_A);
179 g_value_set_object (&args[0], self);
181 g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
182 g_signal_chain_from_overridden (args, NULL);
184 g_value_unset (&args[0]);
188 test_b_class_init (TestBClass *class)
190 g_signal_override_class_closure (foo_signal_id,
192 g_cclosure_new (G_CALLBACK (test_b_foo),
194 g_signal_override_class_closure (bar_signal_id,
196 g_cclosure_new (G_CALLBACK (test_b_bar),
200 static DEFINE_TYPE (TestB, test_b,
201 test_b_class_init, NULL, NULL,
204 #define TEST_TYPE_C (test_c_get_type())
206 typedef struct _TestC TestC;
207 typedef struct _TestCClass TestCClass;
213 TestBClass parent_class;
217 test_c_foo (TestA *self)
219 GValue args[1] = { { 0, } };
221 record ("TestC::foo");
223 g_value_init (&args[0], TEST_TYPE_A);
224 g_value_set_object (&args[0], self);
226 g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
227 g_signal_chain_from_overridden (args, NULL);
229 g_value_unset (&args[0]);
233 test_c_bar (TestI *self)
235 GValue args[1] = { { 0, } };
237 record ("TestC::bar");
239 g_value_init (&args[0], TEST_TYPE_A);
240 g_value_set_object (&args[0], self);
242 g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
243 g_signal_chain_from_overridden (args, NULL);
245 g_value_unset (&args[0]);
249 test_c_class_init (TestBClass *class)
251 g_signal_override_class_closure (foo_signal_id,
253 g_cclosure_new (G_CALLBACK (test_c_foo),
255 g_signal_override_class_closure (bar_signal_id,
257 g_cclosure_new (G_CALLBACK (test_c_bar),
262 static DEFINE_TYPE (TestC, test_c,
263 test_c_class_init, NULL, NULL,
266 static GString *test_string = NULL;
267 gboolean failed = FALSE;
270 record (const gchar *str)
272 if (test_string->len)
273 g_string_append_c (test_string, ',');
274 g_string_append (test_string, str);
280 const gchar *expected)
282 GObject *self = g_object_new (type, NULL);
284 test_string = g_string_new (NULL);
286 g_signal_emit_by_name (self, signal, 0);
289 if (strcmp (test_string->str, expected) != 0)
292 g_printerr ("*** emitting %s on a %s instance\n"
295 signal, g_type_name (type),
299 if (strcmp (test_string->str, expected) != 0)
303 g_string_free (test_string, TRUE);
307 main (int argc, char **argv)
309 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
310 G_LOG_LEVEL_WARNING |
311 G_LOG_LEVEL_CRITICAL);
314 test (TEST_TYPE_A, "foo", "TestA::foo,TestI::foo");
315 test (TEST_TYPE_A, "bar", "TestA::bar");
317 test (TEST_TYPE_B, "foo", "TestB::foo,TestA::foo,TestI::foo");
318 test (TEST_TYPE_B, "bar", "TestB::bar,TestA::bar");
320 test (TEST_TYPE_C, "foo", "TestC::foo,TestB::foo,TestA::foo,TestI::foo");
321 test (TEST_TYPE_C, "bar", "TestC::bar,TestB::bar,TestA::bar");
323 return failed ? 1 : 0;