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;
40 static guint baz_signal_id = 0;
42 static GType test_i_get_type (void);
43 static GType test_a_get_type (void);
44 static GType test_b_get_type (void);
45 static GType test_c_get_type (void);
47 static void record (const gchar *str);
49 #define TEST_TYPE_I (test_i_get_type ())
51 typedef struct _TestI TestI;
52 typedef struct _TestIClass TestIClass;
56 GTypeInterface base_iface;
60 test_i_foo (TestI *self)
62 record ("TestI::foo");
66 test_i_default_init (gpointer g_class)
68 foo_signal_id = g_signal_newv ("foo",
71 g_cclosure_new(G_CALLBACK(test_i_foo),
74 g_cclosure_marshal_VOID__VOID,
75 G_TYPE_NONE, 0, NULL);
78 static DEFINE_IFACE (TestI, test_i, NULL, test_i_default_init)
80 #define TEST_TYPE_A (test_a_get_type())
82 typedef struct _TestA TestA;
83 typedef struct _TestAClass TestAClass;
89 GObjectClass parent_class;
91 void (* bar) (TestA *self);
95 test_a_foo (TestI *self)
97 GValue args[1] = { G_VALUE_INIT };
99 record ("TestA::foo");
101 g_value_init (&args[0], TEST_TYPE_A);
102 g_value_set_object (&args[0], self);
104 g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
105 g_signal_chain_from_overridden (args, NULL);
107 g_value_unset (&args[0]);
111 test_a_bar (TestA *self)
113 record ("TestA::bar");
117 test_a_baz (TestA *self,
121 record ("TestA::baz");
123 g_assert (object == G_OBJECT (self));
124 g_assert (GPOINTER_TO_INT (pointer) == 23);
126 return g_strdup ("TestA::baz");
130 test_a_class_init (TestAClass *class)
132 class->bar = test_a_bar;
134 bar_signal_id = g_signal_new ("bar",
137 G_STRUCT_OFFSET (TestAClass, bar),
139 g_cclosure_marshal_VOID__VOID,
140 G_TYPE_NONE, 0, NULL);
142 baz_signal_id = g_signal_new_class_handler ("baz",
145 G_CALLBACK (test_a_baz),
147 g_cclosure_marshal_STRING__OBJECT_POINTER,
154 test_a_interface_init (TestIClass *iface)
156 g_signal_override_class_closure (foo_signal_id,
158 g_cclosure_new (G_CALLBACK (test_a_foo),
162 static DEFINE_TYPE_FULL (TestA, test_a,
163 test_a_class_init, NULL, NULL,
165 INTERFACE (test_a_interface_init, TEST_TYPE_I))
167 #define TEST_TYPE_B (test_b_get_type())
169 typedef struct _TestB TestB;
170 typedef struct _TestBClass TestBClass;
176 TestAClass parent_class;
180 test_b_foo (TestI *self)
182 GValue args[1] = { G_VALUE_INIT };
184 record ("TestB::foo");
186 g_value_init (&args[0], TEST_TYPE_A);
187 g_value_set_object (&args[0], self);
189 g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
190 g_signal_chain_from_overridden (args, NULL);
192 g_value_unset (&args[0]);
196 test_b_bar (TestA *self)
198 GValue args[1] = { G_VALUE_INIT };
200 record ("TestB::bar");
202 g_value_init (&args[0], TEST_TYPE_A);
203 g_value_set_object (&args[0], self);
205 g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
206 g_signal_chain_from_overridden (args, NULL);
208 g_value_unset (&args[0]);
212 test_b_baz (TestA *self,
216 gchar *retval = NULL;
218 record ("TestB::baz");
220 g_assert (object == G_OBJECT (self));
221 g_assert (GPOINTER_TO_INT (pointer) == 23);
223 g_signal_chain_from_overridden_handler (self, object, pointer, &retval);
227 gchar *tmp = g_strconcat (retval , ",TestB::baz", NULL);
236 test_b_class_init (TestBClass *class)
238 g_signal_override_class_closure (foo_signal_id,
240 g_cclosure_new (G_CALLBACK (test_b_foo),
242 g_signal_override_class_closure (bar_signal_id,
244 g_cclosure_new (G_CALLBACK (test_b_bar),
246 g_signal_override_class_handler ("baz",
248 G_CALLBACK (test_b_baz));
251 static DEFINE_TYPE (TestB, test_b,
252 test_b_class_init, NULL, NULL,
255 #define TEST_TYPE_C (test_c_get_type())
257 typedef struct _TestC TestC;
258 typedef struct _TestCClass TestCClass;
264 TestBClass parent_class;
268 test_c_foo (TestI *self)
270 GValue args[1] = { G_VALUE_INIT };
272 record ("TestC::foo");
274 g_value_init (&args[0], TEST_TYPE_A);
275 g_value_set_object (&args[0], self);
277 g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id);
278 g_signal_chain_from_overridden (args, NULL);
280 g_value_unset (&args[0]);
284 test_c_bar (TestA *self)
286 GValue args[1] = { G_VALUE_INIT };
288 record ("TestC::bar");
290 g_value_init (&args[0], TEST_TYPE_A);
291 g_value_set_object (&args[0], self);
293 g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id);
294 g_signal_chain_from_overridden (args, NULL);
296 g_value_unset (&args[0]);
300 test_c_baz (TestA *self,
304 gchar *retval = NULL;
306 record ("TestC::baz");
308 g_assert (object == G_OBJECT (self));
309 g_assert (GPOINTER_TO_INT (pointer) == 23);
311 g_signal_chain_from_overridden_handler (self, object, pointer, &retval);
315 gchar *tmp = g_strconcat (retval , ",TestC::baz", NULL);
324 test_c_class_init (TestBClass *class)
326 g_signal_override_class_closure (foo_signal_id,
328 g_cclosure_new (G_CALLBACK (test_c_foo),
330 g_signal_override_class_closure (bar_signal_id,
332 g_cclosure_new (G_CALLBACK (test_c_bar),
334 g_signal_override_class_handler ("baz",
336 G_CALLBACK (test_c_baz));
340 static DEFINE_TYPE (TestC, test_c,
341 test_c_class_init, NULL, NULL,
344 static GString *test_string = NULL;
345 gboolean failed = FALSE;
348 record (const gchar *str)
350 if (test_string->len)
351 g_string_append_c (test_string, ',');
352 g_string_append (test_string, str);
358 const gchar *expected,
359 const gchar *expected_retval)
361 GObject *self = g_object_new (type, NULL);
363 test_string = g_string_new (NULL);
365 if (strcmp (signal, "baz"))
367 g_signal_emit_by_name (self, signal);
373 g_signal_emit_by_name (self, signal, self, GINT_TO_POINTER (23), &ret);
375 if (strcmp (ret, expected_retval) != 0)
382 if (strcmp (test_string->str, expected) != 0)
385 g_printerr ("*** emitting %s on a %s instance\n"
388 signal, g_type_name (type),
392 if (strcmp (test_string->str, expected) != 0)
396 g_string_free (test_string, TRUE);
397 g_object_unref (self);
401 main (int argc, char **argv)
403 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
404 G_LOG_LEVEL_WARNING |
405 G_LOG_LEVEL_CRITICAL);
407 test (TEST_TYPE_A, "foo", "TestA::foo,TestI::foo", NULL);
408 test (TEST_TYPE_A, "bar", "TestA::bar", NULL);
409 test (TEST_TYPE_A, "baz", "TestA::baz", "TestA::baz");
411 test (TEST_TYPE_B, "foo", "TestB::foo,TestA::foo,TestI::foo", NULL);
412 test (TEST_TYPE_B, "bar", "TestB::bar,TestA::bar", NULL);
413 test (TEST_TYPE_B, "baz", "TestB::baz,TestA::baz", "TestA::baz,TestB::baz");
415 test (TEST_TYPE_C, "foo", "TestC::foo,TestB::foo,TestA::foo,TestI::foo", NULL);
416 test (TEST_TYPE_C, "bar", "TestC::bar,TestB::bar,TestA::bar", NULL);
417 test (TEST_TYPE_C, "baz", "TestC::baz,TestB::baz,TestA::baz", "TestA::baz,TestB::baz,TestC::baz");
419 return failed ? 1 : 0;