1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 2013 Red Hat, Inc.
3 * Copy and pasted from accumulator.c and modified.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #undef G_LOG_DOMAIN
20 #define G_LOG_DOMAIN "TestSignals"
21
22 #undef G_DISABLE_ASSERT
23 #undef G_DISABLE_CHECKS
24 #undef G_DISABLE_CAST_CHECKS
25
26 #include <glib-object.h>
27
28 #include "testcommon.h"
29
30 /* What this test tests is the behavior of signal disconnection
31 * from within a signal handler for the signal being disconnected.
32 *
33 * The test demonstrates that signal handlers disconnected from a signal
34 * from an earlier handler in the same emission will not be run.
35 *
36 * It also demonstrates that signal handlers connected from a signal
37 * from an earlier handler in the same emission will not be run.
38 */
39
40 /*
41 * TestObject, a parent class for TestObject
42 */
43 #define TEST_TYPE_OBJECT (test_object_get_type ())
44 typedef struct _TestObject TestObject;
45 typedef struct _TestObjectClass TestObjectClass;
46 static gboolean callback1_ran = FALSE, callback2_ran = FALSE, callback3_ran = FALSE, default_handler_ran = FALSE;
47
48 struct _TestObject
49 {
50 GObject parent_instance;
51 };
52 struct _TestObjectClass
53 {
54 GObjectClass parent_class;
55
56 void (*test_signal) (TestObject *object);
57 };
58
59 static GType test_object_get_type (void);
60
61 static void
test_object_real_signal(TestObject * object)62 test_object_real_signal (TestObject *object)
63 {
64 default_handler_ran = TRUE;
65 }
66
67 static void
test_object_signal_callback3(TestObject * object,gpointer data)68 test_object_signal_callback3 (TestObject *object,
69 gpointer data)
70 {
71 callback3_ran = TRUE;
72 }
73
74 static void
test_object_signal_callback2(TestObject * object,gpointer data)75 test_object_signal_callback2 (TestObject *object,
76 gpointer data)
77 {
78 callback2_ran = TRUE;
79 }
80
81 static void
test_object_signal_callback1(TestObject * object,gpointer data)82 test_object_signal_callback1 (TestObject *object,
83 gpointer data)
84 {
85 callback1_ran = TRUE;
86 g_signal_handlers_disconnect_by_func (G_OBJECT (object),
87 test_object_signal_callback2,
88 data);
89 g_signal_connect (object, "test-signal",
90 G_CALLBACK (test_object_signal_callback3), NULL);
91 }
92
93 static void
test_object_class_init(TestObjectClass * class)94 test_object_class_init (TestObjectClass *class)
95 {
96 class->test_signal = test_object_real_signal;
97
98 g_signal_new ("test-signal",
99 G_OBJECT_CLASS_TYPE (class),
100 G_SIGNAL_RUN_LAST,
101 G_STRUCT_OFFSET (TestObjectClass, test_signal),
102 NULL, NULL, NULL, G_TYPE_NONE, 0);
103 }
104
DEFINE_TYPE(TestObject,test_object,test_object_class_init,NULL,NULL,G_TYPE_OBJECT)105 static DEFINE_TYPE(TestObject, test_object,
106 test_object_class_init, NULL, NULL,
107 G_TYPE_OBJECT)
108
109 int
110 main (int argc,
111 char *argv[])
112 {
113 TestObject *object;
114
115 g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
116 G_LOG_LEVEL_WARNING |
117 G_LOG_LEVEL_CRITICAL);
118
119 object = g_object_new (TEST_TYPE_OBJECT, NULL);
120
121 g_signal_connect (object, "test-signal",
122 G_CALLBACK (test_object_signal_callback1), NULL);
123 g_signal_connect (object, "test-signal",
124 G_CALLBACK (test_object_signal_callback2), NULL);
125 g_signal_emit_by_name (object, "test-signal");
126
127 g_assert (callback1_ran);
128 g_assert (!callback2_ran);
129 g_assert (!callback3_ran);
130 g_assert (default_handler_ran);
131
132 g_object_unref (object);
133 return 0;
134 }
135