tests: Fix build on pre-C99
[platform/upstream/atk.git] / tests / testvalue.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  * Copyright 2014 Igalia S.L.
4  *
5  * Author: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 #include <atk/atk.h>
23
24 /**
25  * SECTION:testvalue
26  * @Short_description: this example serves as a unit test for AtkValue
27  *  and also as an example of how to implement #AtkValue on a given
28  *  GObject.
29  *
30  *  This test will represent a volume slider, smart enough to have
31  *  classify the values on the global range [0,1] with the
32  *  descriptions "low", "medium", "high" and "very high".  As the
33  *  clasification is fixed, it also expose all the four possible
34  *  subranges. To fill the description name it will use some of the
35  *  already defined #AtkValueType.
36  *
37  *  This will implement all the methods of #AtkValue, but note that
38  *  this is not mandatory on all the cases. In several cases it is not
39  *  needed to implement the subranges methods. See #AtkValue
40  *  documentation for further information.
41  *
42  */
43
44 #define EXPECTED_NUMBER 7
45
46 #define LOWER_LIMIT 0
47 #define LOW_THRESHOLD 0.2
48 #define NORMAL_THRESHOLD 0.4
49 #define HIGH_THRESHOLD 0.8
50 #define RISKY_THRESHOLD 1.0
51 #define UPPER_LIMIT 1.0
52 #define INCREMENT 0.15
53
54 GMainLoop *global_loop = NULL;
55 gint global_number_emissions = 0;
56 gboolean test_success = TRUE;
57 GObject *my_value;
58
59 #define TEST_TYPE_VALUE                         (test_value_get_type ())
60 #define TEST_VALUE(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_VALUE, TestValue))
61 #define TEST_VALUE_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_VALUE, TestValueClass))
62 #define TEST_IS_VALUE(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_VALUE))
63 #define TEST_IS_VALUE_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_VALUE))
64 #define TEST_VALUE_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_VALUE, TestValueClass))
65
66 typedef struct _TestValue        TestValue;
67 typedef struct _TestValueClass   TestValueClass;
68
69 struct _TestValue
70 {
71   AtkObject parent;
72
73   gdouble value;
74 };
75
76 struct _TestValueClass
77 {
78   AtkObjectClass parent_class;
79 };
80
81 GType       test_value_get_type (void) G_GNUC_CONST;
82 static void test_value_interface_init (AtkValueIface *iface);
83
84 G_DEFINE_TYPE_WITH_CODE (TestValue,
85                          test_value,
86                          ATK_TYPE_OBJECT,
87                          G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE,
88                                                 test_value_interface_init));
89
90 static void
91 test_value_class_init (TestValueClass *klass)
92 {
93 }
94
95 static void
96 test_value_init (TestValue *value)
97 {
98 }
99
100
101 static const gchar*
102 get_description (gdouble value)
103 {
104   const gchar *description = NULL;
105
106   if (value < LOW_THRESHOLD)
107     description = atk_value_type_get_localized_name (ATK_VALUE_LOW);
108   else if (value < NORMAL_THRESHOLD)
109     description = atk_value_type_get_localized_name (ATK_VALUE_MEDIUM);
110   else if (value < HIGH_THRESHOLD)
111     description = atk_value_type_get_localized_name (ATK_VALUE_HIGH);
112   else description = atk_value_type_get_localized_name (ATK_VALUE_VERY_HIGH);
113
114   return description;
115 }
116
117 static void
118 test_value_get_value_and_text (AtkValue *value,
119                                gdouble *current_value,
120                                gchar **description)
121 {
122   TestValue *self;
123
124   g_return_if_fail (TEST_IS_VALUE (value));
125
126   self = TEST_VALUE (value);
127
128   if (current_value != NULL)
129     *current_value = self->value;
130
131   if (description != NULL)
132     *description = g_strdup (get_description (self->value));
133 }
134
135 AtkRange*
136 test_value_get_range (AtkValue *value)
137 {
138   AtkRange *result;
139
140   g_return_val_if_fail (TEST_IS_VALUE (value), NULL);
141
142   result = atk_range_new (LOWER_LIMIT,
143                                     UPPER_LIMIT,
144                                     NULL);
145
146   return result;
147 }
148
149 gdouble
150 test_value_get_increment (AtkValue *value)
151 {
152   g_return_val_if_fail (TEST_IS_VALUE (value), 0.0);
153
154   return INCREMENT;
155 }
156
157 GSList*
158 test_value_get_sub_ranges (AtkValue *value)
159 {
160   GSList *result = NULL;
161   AtkRange *range = NULL;
162
163   g_return_val_if_fail (TEST_IS_VALUE (value), NULL);
164
165   /* low */
166   range = atk_range_new (LOWER_LIMIT, LOW_THRESHOLD,
167                          get_description (LOWER_LIMIT));
168
169   result = g_slist_append (result, range);
170
171   /* normal */
172   range = atk_range_new (LOW_THRESHOLD, NORMAL_THRESHOLD,
173                          get_description (LOW_THRESHOLD));
174   result = g_slist_append (result, range);
175
176   /* high */
177   range = atk_range_new (NORMAL_THRESHOLD, HIGH_THRESHOLD,
178                          get_description (NORMAL_THRESHOLD));
179   result = g_slist_append (result, range);
180
181   /* very high */
182   range = atk_range_new (HIGH_THRESHOLD, UPPER_LIMIT,
183                          get_description (HIGH_THRESHOLD));
184   result = g_slist_append (result, range);
185
186   return result;
187 }
188
189 void
190 test_value_set_value (AtkValue *value,
191                       double new_value)
192 {
193   TestValue *self;
194
195   g_return_if_fail (TEST_IS_VALUE (value));
196
197   self = TEST_VALUE (value);
198
199   if (new_value < LOWER_LIMIT)
200     new_value = LOWER_LIMIT;
201
202   if (new_value > UPPER_LIMIT)
203     new_value = UPPER_LIMIT;
204
205   if (new_value != self->value) {
206     gchar *description = g_strdup (get_description (new_value));
207     self->value = new_value;
208     g_signal_emit_by_name (value, "value-changed", new_value, description, NULL);
209     g_free (description);
210   }
211 }
212
213 static void
214 test_value_interface_init (AtkValueIface *iface)
215 {
216   iface->get_value_and_text = test_value_get_value_and_text;
217   iface->get_range = test_value_get_range;
218   iface->get_increment = test_value_get_increment;
219   iface->get_sub_ranges = test_value_get_sub_ranges;
220   iface->set_value = test_value_set_value;
221 }
222
223 static void
224 value_page_changed_cb (AtkValue *value,
225                        gdouble new_value,
226                        gchar *new_description,
227                        gpointer data)
228 {
229   g_print ("value-changed callback=(%f,%s)\n", new_value, new_description);
230   global_number_emissions++;
231 }
232
233 /**
234  * This call simulates a user interacting with the slider.
235  *
236  */
237 static gboolean
238 do_value_changed (gpointer data)
239 {
240   TestValue* test_value = TEST_VALUE (data);
241
242   atk_value_set_value (ATK_VALUE (test_value),
243                        test_value->value + INCREMENT);
244
245   if (global_number_emissions == EXPECTED_NUMBER) {
246     g_main_loop_quit (global_loop);
247     return G_SOURCE_REMOVE;
248   } else
249     return G_SOURCE_CONTINUE;
250 }
251
252 /**
253  * Prints all the info from an AtkValue
254  */
255 static void
256 print_info (AtkValue *atk_value)
257 {
258   double value;
259   gchar *description;
260   AtkRange *range;
261   GSList *sub_ranges;
262   GSList *iter;
263   gdouble increment;
264   gint i = 0;
265
266   atk_value_get_value_and_text (atk_value, &value, &description);
267   range = atk_value_get_range (atk_value);
268   increment = atk_value_get_increment (atk_value);
269   atk_value_set_value (atk_value, 0);
270
271   g_print ("Current AtkValue data:\n");
272   g_print ("\t (value,description)=(%f,%s) \n", value, description);
273   if (range != NULL)
274     g_print ("\t (min,max,description)=(%f, %f, %s)\n",
275              atk_range_get_lower_limit (range), atk_range_get_upper_limit (range), atk_range_get_description (range));
276   else
277     test_success = FALSE; /* Any AtkValue implementation should provide a range */
278   g_print ("\t minimum increment=%f\n", increment);
279
280   if (range)
281     atk_range_free (range);
282
283   sub_ranges = atk_value_get_sub_ranges (atk_value);
284   for (iter = sub_ranges; iter != NULL; iter = g_slist_next (iter),i++) {
285     range = iter->data;
286     g_print ("\t\t sub_range%i = (%f, %f, %s)\n", i,
287              atk_range_get_lower_limit (range), atk_range_get_upper_limit (range), atk_range_get_description (range));
288   }
289
290   g_slist_free_full (sub_ranges, (GDestroyNotify) atk_range_free);
291 }
292
293
294 static gboolean
295 init_test_value (void)
296 {
297   my_value = g_object_new (TEST_TYPE_VALUE, NULL);
298
299   g_signal_connect (my_value, "value-changed",
300                     G_CALLBACK (value_page_changed_cb),
301                     NULL);
302
303   print_info (ATK_VALUE (my_value));
304
305   g_idle_add (do_value_changed, my_value);
306
307   return TRUE;
308 }
309
310
311 int
312 main (gint  argc,
313       char* argv[])
314 {
315   global_loop = g_main_loop_new (NULL, FALSE);
316
317   g_print("Starting Value test suite\n\n\n");
318
319   init_test_value ();
320   g_main_loop_run (global_loop);
321
322   if (global_number_emissions == EXPECTED_NUMBER && test_success)
323     g_print ("\n\nValue tests succeeded\n\n\n");
324   else
325     g_print ("\n\nValue tests failed\n\n\n");
326
327   print_info (ATK_VALUE (my_value));
328
329   return 0;
330 }