Imported version 2.7.91
[platform/core/uifw/at-spi2-core.git] / atspi / atspi-stateset.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001, 2002 Sun Microsystems Inc.,
6  * Copyright 2001, 2002 Ximian, Inc.
7  * Copyright 2010, 2011 Novell, 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 "atspi-private.h"
26
27 static void atspi_state_set_class_init (AtspiStateSetClass *klass);
28
29 G_DEFINE_TYPE (AtspiStateSet, atspi_state_set, G_TYPE_OBJECT)
30
31 static const char *state_names [] =
32 {
33   "invalid",
34   "active",
35   "armed",
36   "busy",
37   "checked",
38   "collapsed",
39   "defunct",
40   "editable",
41   "enabled",
42   "expandable",
43   "expanded",
44   "focusable",
45   "focused",
46   "has-tool-tip",
47   "horizontal",
48   "iconified",
49   "modal",
50   "multi-line",
51   "multiselectable",
52   "opaque",
53   "pressed",
54   "resizable",
55   "selectable",
56   "selected",
57   "sensitive",
58   "showing",
59   "singleLine",
60   "stale",
61   "transient",
62   "vertical",
63   "visible",
64   "manages-descendants",
65   "indeterminate",
66   "required",
67   "truncated",
68   "animated",
69   "invalid-entry",
70   "supports-autocompletion",
71   "selectable-text",
72   "is-default",
73   "visited",
74   NULL
75 };
76
77 static void
78 atspi_state_set_init (AtspiStateSet *set)
79 {
80   set->states = 0;
81 }
82
83 static void
84 atspi_state_set_class_init (AtspiStateSetClass* klass)
85 {
86 }
87
88 /**
89  * atspi_state_set_new:
90  * @states: (element-type AtspiStateType): An array of states with which the
91  *          method initializes the state set.
92  *
93  * Generates an #AtspiStateSet with the given @states.
94  *
95  * Returns: A new #AtspiStateSet with the given states.
96  **/
97 AtspiStateSet *
98 atspi_state_set_new (GArray *states)
99 {
100   AtspiStateSet *set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
101   gint i;
102
103   if (!set || !states)
104     return set;
105
106   for (i = 0; i < states->len; i++)
107     atspi_state_set_add (set, g_array_index (states, AtspiStateType, i));
108   return set;
109 }
110
111 AtspiStateSet *
112 _atspi_state_set_new_internal (AtspiAccessible *accessible, gint64 states)
113 {
114   AtspiStateSet *set;
115   
116   set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
117   g_return_val_if_fail (set != NULL, NULL);
118
119   set->accessible = accessible;
120   set->states = states;
121   return set;
122 }
123
124 /**
125  * atspi_state_set_set_by_name:
126  * @set: a pointer to the #AtspiStateSet object on which to operate.
127  * @name: a string corresponding to a state name.
128  * @enabled: if #TRUE, @name should be enabled in the @set in question;
129  *          otherwise, it should be disabled.
130  *
131  * Enables/disables a state in an #AtspiStateSet according to its @name.
132  **/
133 void
134 atspi_state_set_set_by_name (AtspiStateSet *set, const gchar *name, gboolean enabled)
135 {
136   gint i = 0;
137
138   if (set->accessible &&
139       !(set->accessible->cached_properties & ATSPI_CACHE_STATES))
140     return;
141
142   /* TODO: This could perhaps be optimized */
143   for (i = 0; state_names [i]; i++)
144   {
145     if (!strcmp (state_names [i], name))
146     {
147       if (enabled)
148         set->states |= ((gint64)1 << i);
149       else
150         set->states &= ~((gint64)1 << i);
151       return;
152     }
153   }
154   g_warning ("at-spi: Attempt to set unknown state '%s'", name);
155 }
156
157 static void
158 refresh_states (AtspiStateSet *set)
159 {
160   GArray *state_array;
161   dbus_uint32_t *states;
162
163   if (!set->accessible ||
164       (set->accessible->cached_properties & ATSPI_CACHE_STATES))
165     return;
166
167   if (!_atspi_dbus_call (set->accessible, atspi_interface_accessible, "GetState", NULL, "=>au", &state_array))
168     return;
169
170   states = (dbus_uint32_t *) state_array->data;
171
172   set->states = ((gint64)states [1]) << 32;
173   set->states |= (gint64) states [0];
174   g_array_free (state_array, TRUE);
175 }
176
177 /**
178  * atspi_state_set_add:
179  * @set: a pointer to the #AtspiStateSet object on which to operate.
180  * @state: an #AtspiStateType to be added to the specified #AtspiStateSet.
181  *
182  * Adds a particular #AtspiState to an #AtspiStateSet (i.e. sets the
183  *       given state to #TRUE in the stateset).
184  *
185  **/
186 void
187 atspi_state_set_add (AtspiStateSet *set, AtspiStateType state)
188 {
189   g_return_if_fail (set != NULL);
190   set->states |= (((gint64)1) << state);
191 }
192
193 /**
194  * atspi_state_set_compare:
195  * @set: a pointer to the first #AtspiStateSet object on which to operate.
196  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
197  *
198  * Determines the differences between two instances of #AtspiStateSet.
199  *
200  * @see #atspi_state_set_equals.
201  *
202  * Returns: (transfer full): an #AtspiStateSet object containing all states
203  * contained on one of the two sets but not the other.
204  *
205  **/
206 AtspiStateSet *
207 atspi_state_set_compare (AtspiStateSet *set,
208                          AtspiStateSet *set2)
209 {
210   g_return_val_if_fail (set != NULL, NULL);
211   g_return_val_if_fail (set2 != NULL, NULL);
212
213   return _atspi_state_set_new_internal (NULL, set->states ^ set2->states);
214 }
215
216 /**
217  * atspi_state_set_contains:
218  * @set: a pointer to the #AtspiStateSet object on which to operate.
219  * @state: an #AtspiStateType for which the specified #AtspiStateSet
220  *          will be queried.
221  *
222  * Determines whether a given #AtspiStateSet includes a given state; that is,
223  *          whether @state is true for the @set in question.
224  *
225  * Returns: #TRUE if @state is true/included in the given #AtspiStateSet,
226  *          otherwise #FALSE.
227  *
228  **/
229 gboolean
230 atspi_state_set_contains (AtspiStateSet *set,
231                              AtspiStateType state)
232 {
233   if (!set)
234     return FALSE;
235   refresh_states (set);
236   return (set->states & ((gint64)1 << state)) ? TRUE : FALSE;
237 }
238
239 /**
240  * atspi_state_set_equals:
241  * @set: a pointer to the first #AtspiStateSet object on which to operate.
242  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
243  *
244  * Determines whether two instances of #AtspiStateSet are equivalent (i.e.
245  *          consist of the same #AtspiStates).  Useful for checking multiple
246  *          state variables at once.
247  *
248  * @see #atspi_state_set_compare.
249  *
250  * Returns: #TRUE if the two #AtspiStateSets are equivalent,
251  * otherwise #FALSE.
252  *
253  **/
254 gboolean
255 atspi_state_set_equals (AtspiStateSet *set,
256                            AtspiStateSet *set2)
257 {
258   if (set == set2)
259     return TRUE;
260   if (set == NULL || set2 == NULL)
261     return FALSE;
262   return (set->states == set2->states);
263 }
264
265 /**
266  * atspi_state_set_get_states:
267  * @set: The #AtspiStateSet to be queried.
268  *
269  * Returns the states in an #AtspiStateSet as an array.
270  *
271  * Returns: (element-type AtspiStateType) (transfer full): A #GArray of state
272  *          types representing the current state.
273  **/
274 GArray *
275 atspi_state_set_get_states (AtspiStateSet *set)
276 {
277   gint i = 0;
278   guint64 val = 1;
279   GArray *ret;
280
281   g_return_val_if_fail (set != NULL, NULL);
282   refresh_states (set);
283   ret = g_array_new (TRUE, TRUE, sizeof (AtspiStateType));
284   if (!ret)
285     return NULL;
286   for (i = 0; i < 64; i++)
287   {
288     if (set->states & val)
289       ret = g_array_append_val (ret, i);
290     val <<= 1;
291   }
292   return ret;
293 }
294
295 /**
296  * atspi_state_set_is_empty:
297  * @set: The #AtspiStateSet to query.
298  *
299  * Returns: #TRUE if the state set contains no states; #FALSE otherwise.
300  **/
301 gboolean
302 atspi_state_set_is_empty (AtspiStateSet *set)
303 {
304   return (set->states == 0);
305 }
306
307 /**
308  * atspi_state_set_remove:
309  * @set: a pointer to the #AtspiStateSet object on which to operate.
310  * @state: an #AtspiStateType to remove from the specified @set.
311  *
312  * Removes a particular #AtspiState to an #AtspiStateSet (i.e. sets the
313  *       given state to #FALSE in the stateset.)
314  *
315  **/
316 void
317 atspi_state_set_remove (AtspiStateSet *set, AtspiStateType state)
318 {
319   g_return_if_fail (set != NULL);
320   set->states &= ~((gint64)1 << state);
321 }
322