Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / tests / gobject / accumulator.c
1 /* GObject - GLib Type, Object, Parameter and Signal Library
2  * Copyright (C) 2001, 2003 Red Hat, Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #undef  G_LOG_DOMAIN
21 #define G_LOG_DOMAIN "TestAccumulator"
22
23 #undef G_DISABLE_ASSERT
24 #undef G_DISABLE_CHECKS
25 #undef G_DISABLE_CAST_CHECKS
26
27 #include <string.h>
28
29 #include        <glib-object.h>
30
31 #include "testmarshal.h"
32 #include "testcommon.h"
33
34 /* What this test tests is the behavior of signal accumulators
35  * Two accumulators are tested:
36  *
37  * 1: A custom accumulator that appends the returned strings
38  * 2: The standard g_signal_accumulator_true_handled that stops
39  *    emission on TRUE returns.
40  */
41
42 /*
43  * TestObject, a parent class for TestObject
44  */
45 #define TEST_TYPE_OBJECT          (test_object_get_type ())
46 typedef struct _TestObject        TestObject;
47 typedef struct _TestObjectClass   TestObjectClass;
48
49 struct _TestObject
50 {
51   GObject parent_instance;
52 };
53 struct _TestObjectClass
54 {
55   GObjectClass parent_class;
56
57   gchar*   (*test_signal1) (TestObject *tobject,
58                             gint        param);
59   gboolean (*test_signal2) (TestObject *tobject,
60                             gint        param);
61 };
62
63 static GType test_object_get_type (void);
64
65 static gboolean
66 test_signal1_accumulator (GSignalInvocationHint *ihint,
67                           GValue                *return_accu,
68                           const GValue          *handler_return,
69                           gpointer               data)
70 {
71   const gchar *accu_string = g_value_get_string (return_accu);
72   const gchar *new_string = g_value_get_string (handler_return);
73   gchar *result_string;
74
75   if (accu_string)
76     result_string = g_strconcat (accu_string, new_string, NULL);
77   else if (new_string)
78     result_string = g_strdup (new_string);
79   else
80     result_string = NULL;
81
82   g_value_set_string_take_ownership (return_accu, result_string);
83
84   return TRUE;
85 }
86
87 gchar*
88 test_object_signal1_callback_before (TestObject *tobject,
89                                      gint        param,
90                                      gpointer    data)
91 {
92   return g_strdup ("<before>");
93 }
94
95 gchar*
96 test_object_real_signal1 (TestObject *tobject,
97                           gint        param)
98 {
99   return g_strdup ("<default>");
100 }
101
102 gchar*
103 test_object_signal1_callback_after (TestObject *tobject,
104                                     gint        param,
105                                     gpointer    data)
106 {
107   return g_strdup ("<after>");
108 }
109
110 gboolean
111 test_object_signal2_callback_before (TestObject *tobject,
112                                      gint        param)
113 {
114   switch (param)
115     {
116     case 1: return TRUE;
117     case 2: return FALSE;
118     case 3: return FALSE;
119     case 4: return FALSE;
120     }
121
122   g_assert_not_reached ();
123   return FALSE;
124 }
125
126 gboolean
127 test_object_real_signal2 (TestObject *tobject,
128                           gint        param)
129 {
130   switch (param)
131     {
132     case 1: g_assert_not_reached (); return FALSE;
133     case 2: return TRUE;
134     case 3: return FALSE;
135     case 4: return FALSE;
136     }
137   
138   g_assert_not_reached ();
139   return FALSE;
140 }
141
142 gboolean
143 test_object_signal2_callback_after (TestObject *tobject,
144                                      gint        param)
145 {
146   switch (param)
147     {
148     case 1: g_assert_not_reached (); return FALSE;
149     case 2: g_assert_not_reached (); return FALSE;
150     case 3: return TRUE;
151     case 4: return FALSE;
152     }
153       
154   g_assert_not_reached ();
155   return FALSE;
156 }
157
158 static void
159 test_object_class_init (TestObjectClass *class)
160 {
161   class->test_signal1 = test_object_real_signal1;
162   class->test_signal2 = test_object_real_signal2;
163   
164   g_signal_new ("test-signal1",
165                 G_OBJECT_CLASS_TYPE (class),
166                 G_SIGNAL_RUN_LAST,
167                 G_STRUCT_OFFSET (TestObjectClass, test_signal1),
168                 test_signal1_accumulator, NULL,
169                 test_marshal_STRING__INT,
170                 G_TYPE_STRING, 1, G_TYPE_INT);
171   g_signal_new ("test-signal2",
172                 G_OBJECT_CLASS_TYPE (class),
173                 G_SIGNAL_RUN_LAST,
174                 G_STRUCT_OFFSET (TestObjectClass, test_signal2),
175                 g_signal_accumulator_true_handled, NULL,
176                 test_marshal_BOOLEAN__INT,
177                 G_TYPE_BOOLEAN, 1, G_TYPE_INT);
178 }
179
180 static DEFINE_TYPE(TestObject, test_object,
181                    test_object_class_init, NULL, NULL,
182                    G_TYPE_OBJECT)
183
184 int
185 main (int   argc,
186       char *argv[])
187 {
188   TestObject *object;
189   gchar *string_result;
190   gboolean bool_result;
191         
192   g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
193                           G_LOG_LEVEL_WARNING |
194                           G_LOG_LEVEL_CRITICAL);
195   g_type_init ();
196
197   object = g_object_new (TEST_TYPE_OBJECT, NULL);
198
199   g_signal_connect (object, "test-signal1",
200                     G_CALLBACK (test_object_signal1_callback_before), NULL);
201   g_signal_connect_after (object, "test-signal1",
202                           G_CALLBACK (test_object_signal1_callback_after), NULL);
203   
204   g_signal_emit_by_name (object, "test-signal1", 0, &string_result);
205   g_assert (strcmp (string_result, "<before><default><after>") == 0);
206   g_free (string_result);
207
208   g_signal_connect (object, "test-signal2",
209                     G_CALLBACK (test_object_signal2_callback_before), NULL);
210   g_signal_connect_after (object, "test-signal2",
211                           G_CALLBACK (test_object_signal2_callback_after), NULL);
212   
213   bool_result = FALSE;
214   g_signal_emit_by_name (object, "test-signal2", 1, &bool_result);
215   g_assert (bool_result == TRUE);
216   bool_result = FALSE;
217   g_signal_emit_by_name (object, "test-signal2", 2, &bool_result);
218   g_assert (bool_result == TRUE);
219   bool_result = FALSE;
220   g_signal_emit_by_name (object, "test-signal2", 3, &bool_result);
221   g_assert (bool_result == TRUE);
222   bool_result = TRUE;
223   g_signal_emit_by_name (object, "test-signal2", 4, &bool_result);
224   g_assert (bool_result == FALSE);
225
226   return 0;
227 }