From 32bc3c419726f26bd771ccd03c60cd03243037f6 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Fri, 12 Sep 2003 20:33:31 +0000 Subject: [PATCH] Add g_signal_accumulator_true_handled(), to do TRUE-stops-emit signals. Fri Sep 12 16:31:40 2003 Owen Taylor * gsignal.[ch]: Add g_signal_accumulator_true_handled(), to do TRUE-stops-emit signals. * Makefile.am: Move testoverride.c and testifaceinit.c to tests/gobject. --- gobject/.cvsignore | 2 - gobject/ChangeLog | 8 + gobject/Makefile.am | 6 +- gobject/gmarshal.list | 2 +- gobject/gsignal.c | 16 ++ gobject/gsignal.h | 5 + gobject/testifaceinit.c | 474 ---------------------------------------- gobject/testoverride.c | 379 -------------------------------- 8 files changed, 31 insertions(+), 861 deletions(-) delete mode 100644 gobject/testifaceinit.c delete mode 100644 gobject/testoverride.c diff --git a/gobject/.cvsignore b/gobject/.cvsignore index 9bc966b4e..f8d6d1d19 100644 --- a/gobject/.cvsignore +++ b/gobject/.cvsignore @@ -26,6 +26,4 @@ gmarshal.strings oldest-source-stamp stamp-gmarshal.h testgobject -testoverride -testifaceinit .saved diff --git a/gobject/ChangeLog b/gobject/ChangeLog index c4192d99e..fb179d973 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,11 @@ +Fri Sep 12 16:31:40 2003 Owen Taylor + + * gsignal.[ch]: Add g_signal_accumulator_true_handled(), to + do TRUE-stops-emit signals. + + * Makefile.am: Move testoverride.c and testifaceinit.c to + tests/gobject. + 2003-09-12 Matthias Clasen Make the g_value_set_x_take_ownership() functions "official" diff --git a/gobject/Makefile.am b/gobject/Makefile.am index 200ad0f2d..909fc2e3d 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -177,20 +177,16 @@ libgobject_2_0_la_SOURCES = $(gobject_target_sources) # bin_PROGRAMS = gobject-query glib-genmarshal bin_SCRIPTS = glib-mkenums -noinst_PROGRAMS = testgobject testifaceinit testoverride +noinst_PROGRAMS = testgobject # source files gobject_query_SOURCES = gobject-query.c glib_genmarshal_SOURCES = glib-genmarshal.c testgobject_SOURCES = testgobject.c -testifaceinit_SOURCES = testifaceinit.c -testoverride_SOURCES = testoverride.c # link programs against libgobject progs_LDADD = ./libgobject-2.0.la $(libglib) glib_genmarshal_LDADD = $(libglib) gobject_query_LDADD = $(progs_LDADD) testgobject_LDADD = $(progs_LDADD) -testifaceinit_LDADD = $(progs_LDADD) -testoverride_LDADD = $(progs_LDADD) # # auxillary files diff --git a/gobject/gmarshal.list b/gobject/gmarshal.list index 83af2cd4f..f3844a1e3 100644 --- a/gobject/gmarshal.list +++ b/gobject/gmarshal.list @@ -40,8 +40,8 @@ VOID:PARAM VOID:BOXED VOID:POINTER VOID:OBJECT -STRING:OBJECT,POINTER # GRuntime specific marshallers VOID:UINT,POINTER BOOL:FLAGS +STRING:OBJECT,POINTER diff --git a/gobject/gsignal.c b/gobject/gsignal.c index c5fae2112..70c666eac 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -2586,6 +2586,22 @@ type_debug_name (GType type) return ""; } +gboolean +g_signal_accumulator_true_handled (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + gboolean signal_handled; + + signal_handled = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_handled); + continue_emission = !signal_handled; + + return continue_emission; +} + /* --- compile standard marshallers --- */ #include "gobject.h" #include "genums.h" diff --git a/gobject/gsignal.h b/gobject/gsignal.h index c5295e62f..61345dcba 100644 --- a/gobject/gsignal.h +++ b/gobject/gsignal.h @@ -256,6 +256,11 @@ void g_signal_chain_from_overridden (const GValue *instance_and_param 0, 0, NULL, (func), (data)) +gboolean g_signal_accumulator_true_handled (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy); + /*< private >*/ void g_signal_handlers_destroy (gpointer instance); void _g_signals_destroy (GType itype); diff --git a/gobject/testifaceinit.c b/gobject/testifaceinit.c deleted file mode 100644 index c25bb2968..000000000 --- a/gobject/testifaceinit.c +++ /dev/null @@ -1,474 +0,0 @@ -/* GObject - GLib Type, Object, Parameter and Signal Library - * Copyright (C) 2001, 2003 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN "TestIfaceInit" -#include - -/* What this test tests is the ability to add interfaces dynamically; in - * particular adding interfaces to a class while that class is being - * initialized. - * - * The test defines 5 interfaces: - * - * - TestIface1 is added before the class is initialized - * - TestIface2 is added in base_object_base_init() - * - TestIface3 is added in test_iface1_base_init() - * - TestIface4 is added in test_object_class_init() - * - TestIface5 is added in test_object_test_iface1_init() - * - TestIface6 is added after the class is initialized - */ - -#define DEFINE_TYPE(name, prefix, \ - class_init, base_init, instance_init, \ - parent_type) \ -GType \ -prefix ## _get_type (void) \ -{ \ - static GType object_type = 0; \ - \ - if (!object_type) \ - { \ - static const GTypeInfo object_info = \ - { \ - sizeof (name ## Class), \ - (GBaseInitFunc) base_init, \ - (GBaseFinalizeFunc) NULL, \ - (GClassInitFunc) class_init, \ - (GClassFinalizeFunc) NULL, \ - NULL, /* class_data */ \ - sizeof (name), \ - 0, /* n_prelocs */ \ - (GInstanceInitFunc) instance_init \ - }; \ - \ - object_type = g_type_register_static (parent_type, \ - # name, \ - &object_info, 0); \ - } \ - \ - return object_type; \ -} - -#define DEFINE_IFACE(name, prefix, base_init, dflt_init) \ -GType \ -prefix ## _get_type (void) \ -{ \ - static GType iface_type = 0; \ - \ - if (!iface_type) \ - { \ - static const GTypeInfo iface_info = \ - { \ - sizeof (name ## Class), \ - (GBaseInitFunc) base_init, \ - (GBaseFinalizeFunc) NULL, \ - (GClassInitFunc) dflt_init, \ - }; \ - \ - iface_type = g_type_register_static (G_TYPE_INTERFACE, \ - # name, \ - &iface_info, 0); \ - } \ - return iface_type; \ -} - -/* All 6 interfaces actually share the same class structure, though - * we use separate typedefs - */ -typedef struct _TestIfaceClass TestIfaceClass; - -struct _TestIfaceClass -{ - GTypeInterface base_iface; - guint val; - guint base_val; - guint default_val; -}; - -#define TEST_TYPE_IFACE1 (test_iface1_get_type ()) -#define TEST_IFACE1_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE1, TestIface1Class)) -typedef struct _TestIface1 TestIface1; -typedef struct _TestIfaceClass TestIface1Class; - -static void test_iface1_base_init (TestIface1Class *iface); -static void test_iface1_default_init (TestIface1Class *iface, gpointer class_data); - -static DEFINE_IFACE(TestIface1, test_iface1, test_iface1_base_init, test_iface1_default_init) - -#define TEST_TYPE_IFACE2 (test_iface2_get_type ()) -#define TEST_IFACE2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE2, TestIface2Class)) -typedef struct _TestIface2 TestIface2; -typedef struct _TestIfaceClass TestIface2Class; - -static void test_iface2_base_init (TestIface2Class *iface); - -static DEFINE_IFACE(TestIface2, test_iface2, test_iface2_base_init, NULL) - -#define TEST_TYPE_IFACE3 (test_iface3_get_type ()) -#define TEST_IFACE3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE3, TestIface3Class)) -typedef struct _TestIface3 TestIface3; -typedef struct _TestIfaceClass TestIface3Class; - -static void test_iface3_base_init (TestIface3Class *iface); - -static DEFINE_IFACE(TestIface3, test_iface3, test_iface3_base_init, NULL) - -#define TEST_TYPE_IFACE4 (test_iface4_get_type ()) -#define TEST_IFACE4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE4, TestIface4Class)) -typedef struct _TestIface4 TestIface4; -typedef struct _TestIfaceClass TestIface4Class; - -static void test_iface4_base_init (TestIface4Class *iface); - -static DEFINE_IFACE(TestIface4, test_iface4, test_iface4_base_init, NULL) - -#define TEST_TYPE_IFACE5 (test_iface5_get_type ()) -#define TEST_IFACE5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE5, TestIface5Class)) -typedef struct _TestIface5 TestIface5; -typedef struct _TestIfaceClass TestIface5Class; - -static void test_iface5_base_init (TestIface5Class *iface); - -static DEFINE_IFACE(TestIface5, test_iface5, test_iface5_base_init, NULL) - -#define TEST_TYPE_IFACE6 (test_iface6_get_type ()) -#define TEST_IFACE6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE6, TestIface6Class)) -typedef struct _TestIface6 TestIface6; -typedef struct _TestIfaceClass TestIface6Class; - -static void test_iface6_base_init (TestIface6Class *iface); - -static DEFINE_IFACE(TestIface6, test_iface6, test_iface6_base_init, NULL) - -/* - * BaseObject, a parent class for TestObject - */ -#define BASE_TYPE_OBJECT (base_object_get_type ()) -typedef struct _BaseObject BaseObject; -typedef struct _BaseObjectClass BaseObjectClass; - -struct _BaseObject -{ - GObject parent_instance; -}; -struct _BaseObjectClass -{ - GObjectClass parent_class; -}; - -/* - * TestObject, a parent class for TestObject - */ -#define TEST_TYPE_OBJECT (test_object_get_type ()) -typedef struct _TestObject TestObject; -typedef struct _TestObjectClass TestObjectClass; - -struct _TestObject -{ - BaseObject parent_instance; -}; -struct _TestObjectClass -{ - BaseObjectClass parent_class; -}; - -#define TEST_CALLED_ONCE() G_STMT_START { \ - static gboolean called = 0; \ - g_assert (!called); \ - called = TRUE; \ -} G_STMT_END - -#define CHECK_IFACE_TWICE(iface) G_STMT_START { \ - static guint n_calls = 0; \ - n_calls++; \ - g_assert (n_calls <= 2); \ - g_assert (G_TYPE_IS_INTERFACE (((GTypeInterface*) iface)->g_type)); \ - if (n_calls == 1) \ - g_assert (((GTypeInterface*) iface)->g_instance_type == 0); \ - else \ - g_assert (G_TYPE_IS_OBJECT (((GTypeInterface*) iface)->g_instance_type)); \ -} G_STMT_END - -#define ADD_IFACE(n) G_STMT_START { \ - static GInterfaceInfo iface_info = { \ - (GInterfaceInitFunc)test_object_test_iface##n##_init, \ - NULL, NULL }; \ - \ - g_type_add_interface_static (TEST_TYPE_OBJECT, \ - test_iface##n##_get_type (), \ - &iface_info); \ - \ -} G_STMT_END - -static gboolean base1, base2, base3, base4, base5, base6; -static gboolean iface1, iface2, iface3, iface4, iface5, iface6; - -static void test_object_test_iface1_init (TestIface1Class *iface); -static void test_object_test_iface2_init (TestIface1Class *iface); -static void test_object_test_iface3_init (TestIface3Class *iface); -static void test_object_test_iface4_init (TestIface4Class *iface); -static void test_object_test_iface5_init (TestIface5Class *iface); -static void test_object_test_iface6_init (TestIface6Class *iface); - -static GType test_object_get_type (void); - -static void -test_object_test_iface1_init (TestIface1Class *iface) -{ - TEST_CALLED_ONCE(); - - g_assert (iface->default_val == 0x111111); - - iface->val = 0x10001; - - ADD_IFACE(5); - - iface1 = TRUE; - g_print ("interface1 object initializer\n"); -} - -static void -test_object_test_iface2_init (TestIface2Class *iface) -{ - TEST_CALLED_ONCE(); - - iface->val = 0x20002; - - iface2 = TRUE; -} - -static void -test_object_test_iface3_init (TestIface3Class *iface) -{ - TEST_CALLED_ONCE(); - - iface->val = 0x30003; - - iface3 = TRUE; -} - -static void -test_object_test_iface4_init (TestIface4Class *iface) -{ - TEST_CALLED_ONCE(); - - iface->val = 0x40004; - - iface4 = TRUE; -} - -static void -test_object_test_iface5_init (TestIface5Class *iface) -{ - TEST_CALLED_ONCE(); - - iface->val = 0x50005; - - iface5 = TRUE; -} - -static void -test_object_test_iface6_init (TestIface6Class *iface) -{ - TEST_CALLED_ONCE(); - - iface->val = 0x60006; - - iface6 = TRUE; -} - -static void -test_iface1_default_init (TestIface1Class *iface, - gpointer class_data) -{ - TEST_CALLED_ONCE(); - g_assert (iface->base_iface.g_type == TEST_TYPE_IFACE1); - g_assert (iface->base_iface.g_instance_type == 0); - g_assert (iface->base_val == 0x110011); - g_assert (iface->val == 0); - g_assert (iface->default_val == 0); - iface->default_val = 0x111111; - g_print ("interface1 default initializer\n"); -} - -static void -test_iface1_base_init (TestIface1Class *iface) -{ - static guint n_calls = 0; - n_calls++; - g_assert (n_calls <= 2); - - if (n_calls == 1) - { - iface->base_val = 0x110011; - g_assert (iface->default_val == 0); - } - else - { - g_assert (iface->base_val == 0x110011); - g_assert (iface->default_val == 0x111111); - } - - if (n_calls == 1) - ADD_IFACE(3); - - base1 = TRUE; - g_print ("interface1 base initializer\n"); -} - -static void -test_iface2_base_init (TestIface2Class *iface) -{ - CHECK_IFACE_TWICE (iface); - - iface->base_val = 0x220022; - - base2 = TRUE; -} - -static void -test_iface3_base_init (TestIface3Class *iface) -{ - CHECK_IFACE_TWICE (iface); - - iface->base_val = 0x330033; - - base3 = TRUE; -} - -static void -test_iface4_base_init (TestIface4Class *iface) -{ - CHECK_IFACE_TWICE (iface); - - iface->base_val = 0x440044; - - base4 = TRUE; -} - -static void -test_iface5_base_init (TestIface5Class *iface) -{ - CHECK_IFACE_TWICE (iface); - - iface->base_val = 0x550055; - - base5 = TRUE; -} - -static void -test_iface6_base_init (TestIface6Class *iface) -{ - CHECK_IFACE_TWICE (iface); - - iface->base_val = 0x660066; - - base6 = TRUE; -} - -static void -base_object_base_init (BaseObjectClass *class) -{ - static int n_called = 0; - n_called++; - - /* The second time this is called is for TestObject */ - if (n_called == 2) - { - ADD_IFACE(2); - - /* No interface base init functions should have been called yet - */ - g_assert (!base1 && !base2 && !base3 && !base4 && !base5 && !base6); - g_assert (!iface1 && !iface2 && !iface3 && !iface4 && !iface5 && !iface6); - } -} - -static void -test_object_class_init (TestObjectClass *class) -{ - ADD_IFACE(4); - - /* At this point, the base init functions for all interfaces that have - * been added should be called, but no interface init functions. - */ - g_assert (base1 && base2 && base3 && base4 && !base5 && !base6); - g_assert (!iface1 && !iface2 && !iface3 && !iface4 && !iface5 && !iface6); -} - -static DEFINE_TYPE(BaseObject, base_object, - NULL, base_object_base_init, NULL, - G_TYPE_OBJECT); -static DEFINE_TYPE(TestObject, test_object, - test_object_class_init, NULL, NULL, - BASE_TYPE_OBJECT); - -int -main (int argc, - char *argv[]) -{ - TestObject *object; - TestObjectClass *object_class; - TestIfaceClass *iface; - - g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | - G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_CRITICAL); - g_type_init (); - - /* We force the interfaces to be registered in a different order - * than we add them, so our logic doesn't always deal with interfaces - * added at the end. - */ - (void)TEST_TYPE_IFACE4; - (void)TEST_TYPE_IFACE2; - (void)TEST_TYPE_IFACE6; - (void)TEST_TYPE_IFACE5; - (void)TEST_TYPE_IFACE3; - (void)TEST_TYPE_IFACE1; - - ADD_IFACE(1); - - object_class = g_type_class_ref (TEST_TYPE_OBJECT); - - ADD_IFACE(6); - - /* All base and interface init functions should have been called - */ - g_assert (base1 && base2 && base3 && base4 && base5 && base6); - g_assert (iface1 && iface2 && iface3 && iface4 && iface5 && iface6); - - object = g_object_new (TEST_TYPE_OBJECT, NULL); - - iface = TEST_IFACE1_GET_CLASS (object); - g_assert (iface && iface->val == 0x10001 && iface->base_val == 0x110011); - iface = TEST_IFACE3_GET_CLASS (object); - g_assert (iface && iface->val == 0x30003 && iface->base_val == 0x330033); - iface = TEST_IFACE4_GET_CLASS (object); - g_assert (iface && iface->val == 0x40004 && iface->base_val == 0x440044); - iface = TEST_IFACE5_GET_CLASS (object); - g_assert (iface && iface->val == 0x50005 && iface->base_val == 0x550055); - iface = TEST_IFACE6_GET_CLASS (object); - g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); - - g_print ("testifaceinit: all done.\n"); - - return 0; -} diff --git a/gobject/testoverride.c b/gobject/testoverride.c deleted file mode 100644 index 2ac34e9f2..000000000 --- a/gobject/testoverride.c +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- mode: C; c-basic-offset: 4 -*- */ -#include -#include - -static guint foo_signal_id = 0; -static guint bar_signal_id = 0; - - -static GType test_i_get_type (void); -static GType test_a_get_type (void); -static GType test_b_get_type (void); -static GType test_c_get_type (void); - -#define TEST_TYPE_I (test_i_get_type ()) -#define TEST_I(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_I, TestI)) -#define TEST_I_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), TEST_TYPE_I, TestIClass)) -#define TEST_IS_I(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_I)) -#define TEST_IS_I_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), TEST_TYPE_I)) -#define TEST_I_GET_CLASS(object) (G_TYPE_INSTANCE_GET_INTERFACE((object), TEST_TYPE_I, TestIClass)) - -typedef struct _TestI TestI; -typedef struct _TestIClass TestIClass; - -struct _TestIClass { - GTypeInterface base_iface; -}; - -static void -test_i_foo (TestI *self) -{ - g_print("TestI::foo called.\n"); -} - - -static void -test_i_base_init (gpointer g_class) -{ - static gboolean initialised = FALSE; - - if (!initialised) { - foo_signal_id = g_signal_newv("foo", - TEST_TYPE_I, - G_SIGNAL_RUN_LAST, - g_cclosure_new(G_CALLBACK(test_i_foo), - NULL, NULL), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0, NULL); - } - initialised = TRUE; -} - -static GType -test_i_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof (TestIClass), - (GBaseInitFunc) test_i_base_init, /* base_init */ - NULL, /* base_finalize */ - }; - - type = g_type_register_static (G_TYPE_INTERFACE, "TestI", - &type_info, 0); - } - - return type; -} - - - -#define TEST_TYPE_A (test_a_get_type()) -#define TEST_A(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_A, TestA)) -#define TEST_A_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_A, TestAClass)) -#define TEST_IS_A(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_A)) -#define TEST_IS_A_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_A)) -#define TEST_A_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_A, TestAClass)) - -typedef struct _TestA TestA; -typedef struct _TestAClass TestAClass; - -struct _TestA { - GObject parent; -}; -struct _TestAClass { - GObjectClass parent_class; - - void (* bar) (TestA *self); -}; - -static void -test_a_foo (TestI *self) -{ - GValue args[1] = { { 0, } }; - - g_print("TestA::foo called. Chaining up.\n"); - - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); - - g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); - g_signal_chain_from_overridden (args, NULL); - - g_value_unset (&args[0]); -} - -static void -test_a_bar (TestA *self) -{ - g_print("TestA::bar called.\n"); -} - -static void -test_a_class_init (TestAClass *class) -{ - class->bar = test_a_bar; - - bar_signal_id = g_signal_new("bar", - TEST_TYPE_A, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TestAClass, bar), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -test_a_interface_init (TestIClass *iface) -{ - g_signal_override_class_closure (foo_signal_id, - TEST_TYPE_A, - g_cclosure_new (G_CALLBACK (test_a_foo), - NULL, NULL)); -} - -static GType -test_a_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof(TestAClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) test_a_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(TestAClass), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - static const GInterfaceInfo interface_info = { - (GInterfaceInitFunc) test_a_interface_init, - NULL, - NULL - }; - - type = g_type_register_static (G_TYPE_OBJECT, "TestA", - &type_info, 0); - g_type_add_interface_static (type, TEST_TYPE_I, &interface_info); - } - - return type; -} - - -#define TEST_TYPE_B (test_b_get_type()) -#define TEST_B(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_B, TestB)) -#define TEST_B_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_B, TestBClass)) -#define TEST_IS_B(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_B)) -#define TEST_IS_B_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_B)) -#define TEST_B_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_B, TestBClass)) - -typedef struct _TestB TestB; -typedef struct _TestBClass TestBClass; - -struct _TestB { - TestA parent; -}; -struct _TestBClass { - TestAClass parent_class; -}; - -static void -test_b_foo (TestA *self) -{ - GValue args[1] = { { 0, } }; - - g_print("TestB::foo called. Chaining up.\n"); - - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); - - g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); - g_signal_chain_from_overridden (args, NULL); - - g_value_unset (&args[0]); -} - -static void -test_b_bar (TestI *self) -{ - GValue args[1] = { { 0, } }; - - g_print("TestB::bar called. Chaining up.\n"); - - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); - - g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); - g_signal_chain_from_overridden (args, NULL); - - g_value_unset (&args[0]); -} - -static void -test_b_class_init (TestBClass *class) -{ - g_signal_override_class_closure (foo_signal_id, - TEST_TYPE_B, - g_cclosure_new (G_CALLBACK (test_b_foo), - NULL, NULL)); - g_signal_override_class_closure (bar_signal_id, - TEST_TYPE_B, - g_cclosure_new (G_CALLBACK (test_b_bar), - NULL, NULL)); -} - -static GType -test_b_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof(TestBClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) test_b_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(TestBClass), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - type = g_type_register_static (TEST_TYPE_A, "TestB", - &type_info, 0); - } - - return type; -} - - -#define TEST_TYPE_C (test_c_get_type()) -#define TEST_C(object) (G_TYPE_CHECK_INSTANCE_CAST((object), TEST_TYPE_C, TestC)) -#define TEST_C_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_C, TestCClass)) -#define TEST_IS_C(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), TEST_TYPE_C)) -#define TEST_IS_C_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_C)) -#define TEST_C_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_C, TestCClass)) - -typedef struct _TestC TestC; -typedef struct _TestCClass TestCClass; - -struct _TestC { - TestB parent; -}; -struct _TestCClass { - TestBClass parent_class; -}; - -static void -test_c_foo (TestA *self) -{ - GValue args[1] = { { 0, } }; - - g_print("TestC::foo called. Chaining up.\n"); - - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); - - g_assert (g_signal_get_invocation_hint (self)->signal_id == foo_signal_id); - g_signal_chain_from_overridden (args, NULL); - - g_value_unset (&args[0]); -} - -static void -test_c_bar (TestI *self) -{ - GValue args[1] = { { 0, } }; - - g_print("TestC::bar called. Chaining up.\n"); - - g_value_init (&args[0], TEST_TYPE_A); - g_value_set_object (&args[0], self); - - g_assert (g_signal_get_invocation_hint (self)->signal_id == bar_signal_id); - g_signal_chain_from_overridden (args, NULL); - - g_value_unset (&args[0]); -} - -static void -test_c_class_init (TestBClass *class) -{ - g_signal_override_class_closure (foo_signal_id, - TEST_TYPE_C, - g_cclosure_new (G_CALLBACK (test_c_foo), - NULL, NULL)); - g_signal_override_class_closure (bar_signal_id, - TEST_TYPE_C, - g_cclosure_new (G_CALLBACK (test_c_bar), - NULL, NULL)); -} - -static GType -test_c_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo type_info = { - sizeof(TestCClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) test_c_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(TestCClass), - 0, /* n_preallocs */ - (GInstanceInitFunc) NULL, - }; - - type = g_type_register_static (TEST_TYPE_B, "TestC", - &type_info, 0); - } - - return type; -} - - -int -main (int argc, char **argv) -{ - GObject *self; - - g_type_init(); - - self = g_object_new(TEST_TYPE_A, NULL); - g_print("*** emiting foo on a TestA instance (expect chain A->I)\n"); - g_signal_emit(self, foo_signal_id, 0); - g_print("*** emiting bar on a TestA instance\n"); - g_signal_emit(self, bar_signal_id, 0); - g_object_unref(self); - - g_print("\n"); - - self = g_object_new(TEST_TYPE_B, NULL); - g_print("*** emiting foo on a TestB instance (expect chain B->A->I)\n"); - g_signal_emit(self, foo_signal_id, 0); - g_print("*** emiting bar on a TestB instance (expect chain B->A)\n"); - g_signal_emit(self, bar_signal_id, 0); - g_object_unref(self); - - g_print("\n"); - - self = g_object_new(TEST_TYPE_C, NULL); - g_print("*** emiting foo on a TestC instance (expect chain C->B->A->I)\n"); - g_signal_emit(self, foo_signal_id, 0); - g_print("*** emiting bar on a TestC instance (expect chain C->B->A)\n"); - g_signal_emit(self, bar_signal_id, 0); - g_object_unref(self); - - return 0; -}