05d73033e1f557ef16045cf7f759d524de047a1d
[platform/upstream/at-spi2-atk.git] / atk-adaptor / adaptors / value-adaptor.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2008 Novell, Inc.
6  * Copyright 2001, 2002 Sun Microsystems Inc.,
7  * Copyright 2001, 2002 Ximian, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include <math.h>
26
27 #include <atk/atk.h>
28 #include <droute/droute.h>
29 #include "bridge.h"
30
31 #include "spi-dbus.h"
32 #include "introspection.h"
33
34 static dbus_bool_t
35 impl_get_MinimumValue (DBusMessageIter * iter, void *user_data)
36 {
37   AtkValue *value = (AtkValue *) user_data;
38   GValue src = { 0 };
39   GValue dest = { 0 };
40   gdouble dub;
41
42   g_return_val_if_fail (ATK_IS_VALUE (user_data), FALSE);
43   AtkValueIface *iface = ATK_VALUE_GET_IFACE (value);
44   if (iface->get_range)
45     {
46       AtkRange *range = atk_value_get_range (value);
47       dub = atk_range_get_lower_limit (range);
48       atk_range_free (range);
49       return droute_return_v_double (iter, dub);
50     }
51
52   g_value_init (&src, G_TYPE_DOUBLE);
53   atk_value_get_minimum_value (value, &src);
54   g_value_init (&dest, G_TYPE_DOUBLE);
55
56   if (g_value_transform (&src, &dest))
57     {
58       dub = g_value_get_double (&dest);
59       return droute_return_v_double (iter, dub);
60     }
61   else
62     {
63       return FALSE;
64     }
65 }
66
67 static dbus_bool_t
68 impl_get_MaximumValue (DBusMessageIter * iter, void *user_data)
69 {
70   AtkValue *value = (AtkValue *) user_data;
71   GValue src = { 0 };
72   GValue dest = { 0 };
73   gdouble dub = 0;
74
75   g_return_val_if_fail (ATK_IS_VALUE (user_data), FALSE);
76
77   AtkValueIface *iface = ATK_VALUE_GET_IFACE (value);
78   if (iface->get_range)
79     {
80       AtkRange *range = atk_value_get_range (value);
81       dub = atk_range_get_upper_limit (range);
82       atk_range_free (range);
83       return droute_return_v_double (iter, dub);
84     }
85
86   g_value_init (&src, G_TYPE_DOUBLE);
87   atk_value_get_maximum_value (value, &src);
88   g_value_init (&dest, G_TYPE_DOUBLE);
89
90   if (g_value_transform (&src, &dest))
91     {
92       dub = g_value_get_double (&dest);
93     }
94   return droute_return_v_double (iter, dub);
95 }
96
97 static dbus_bool_t
98 impl_get_MinimumIncrement (DBusMessageIter * iter, void *user_data)
99 {
100   AtkValue *value = (AtkValue *) user_data;
101   GValue src = { 0 };
102   GValue dest = { 0 };
103   gdouble dub = 0;
104
105   g_return_val_if_fail (ATK_IS_VALUE (user_data), FALSE);
106
107   AtkValueIface *iface = ATK_VALUE_GET_IFACE (value);
108   if (iface->get_increment)
109     {
110       dub = atk_value_get_increment (value);
111       return droute_return_v_double (iter, dub);
112     }
113
114   g_value_init (&src, G_TYPE_DOUBLE);
115   atk_value_get_minimum_increment (value, &src);
116   g_value_init (&dest, G_TYPE_DOUBLE);
117
118   if (g_value_transform (&src, &dest))
119     {
120       dub = g_value_get_double (&dest);
121     }
122   return droute_return_v_double (iter, dub);
123 }
124
125 static dbus_bool_t
126 impl_get_CurrentValue (DBusMessageIter * iter, void *user_data)
127 {
128   AtkValue *value = (AtkValue *) user_data;
129   GValue src = { 0 };
130   GValue dest = { 0 };
131   gdouble dub = 0;
132
133   g_return_val_if_fail (ATK_IS_VALUE (user_data), FALSE);
134
135   AtkValueIface *iface = ATK_VALUE_GET_IFACE (value);
136   if (iface->get_value_and_text)
137     {
138       gchar *text = NULL;
139       atk_value_get_value_and_text (value, &dub, &text);
140       return droute_return_v_double (iter, dub);
141     }
142
143   g_value_init (&src, G_TYPE_DOUBLE);
144   atk_value_get_current_value (value, &src);
145   g_value_init (&dest, G_TYPE_DOUBLE);
146
147   if (g_value_transform (&src, &dest))
148     {
149       dub = g_value_get_double (&dest);
150     }
151   return droute_return_v_double (iter, dub);
152 }
153
154 static dbus_bool_t
155 impl_set_CurrentValue (DBusMessageIter * iter, void *user_data)
156 {
157   AtkValue *value = (AtkValue *) user_data;
158   GValue src = { 0 };
159   GValue dest = { 0 };
160   gdouble dub;
161   DBusMessageIter iter_variant;
162
163   g_return_val_if_fail (ATK_IS_VALUE (user_data), FALSE);
164
165   dbus_message_iter_recurse (iter, &iter_variant);
166   if (dbus_message_iter_get_arg_type (&iter_variant) != DBUS_TYPE_DOUBLE)
167     {
168       g_warning ("TODO: Support setting value from a non-double");
169       return FALSE;
170     }
171   dbus_message_iter_get_basic (&iter_variant, &dub);
172
173   AtkValueIface *iface = ATK_VALUE_GET_IFACE (value);
174   if (iface->set_value)
175     {
176       atk_value_set_value (value, dub);
177       return TRUE;
178     }
179
180   g_value_init (&src, G_TYPE_DOUBLE);
181   g_value_set_double (&src, dub);
182
183   atk_value_get_current_value (value, &dest);
184
185   if (g_value_transform (&src, &dest))
186     {
187       atk_value_set_current_value (value, &dest);
188       return TRUE;
189     }
190   else
191     {
192       return FALSE;
193     }
194 }
195
196 /* keeping this method around for backwards-compatibility for now; see
197  *  * BGO#652596 */
198 static DBusMessage *
199 impl_SetCurrentValue (DBusConnection * bus, DBusMessage * message,
200                        void *user_data)
201 {
202   AtkValue *value = (AtkValue *) user_data;
203   dbus_bool_t rv;
204   DBusMessage *reply;
205   gdouble dub = 0;
206   GValue new_value = { 0 };
207
208   g_return_val_if_fail (ATK_IS_VALUE (value),
209                         droute_not_yet_handled_error (message));
210
211   if (!dbus_message_get_args
212       (message, NULL, DBUS_TYPE_DOUBLE, &dub, DBUS_TYPE_INVALID))
213     {
214       return droute_invalid_arguments_error (message);
215     }
216
217   g_value_init (&new_value, G_TYPE_DOUBLE);
218   g_value_set_double (&new_value, dub);
219   rv = atk_value_set_current_value (value, &new_value);
220
221   reply = dbus_message_new_method_return (message);
222   if (reply)
223     {
224       dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &rv,
225                                 DBUS_TYPE_INVALID);
226     }
227   return reply;
228 }
229
230 static DRouteMethod methods[] = {
231   {impl_SetCurrentValue, "SetCurrentValue"},
232   {NULL, NULL}
233 };
234
235 static DRouteProperty properties[] = {
236   {impl_get_MinimumValue, NULL, "MinimumValue"},
237   {impl_get_MaximumValue, NULL, "MaximumValue"},
238   {impl_get_MinimumIncrement, NULL, "MinimumIncrement"},
239   {impl_get_CurrentValue, impl_set_CurrentValue, "CurrentValue"},
240   {NULL, NULL, NULL}
241 };
242
243 void
244 spi_initialize_value (DRoutePath * path)
245 {
246   spi_atk_add_interface (path,
247                          ATSPI_DBUS_INTERFACE_VALUE, spi_org_a11y_atspi_Value, methods, properties);
248 };