Improving atspi-relation documentation.
[platform/upstream/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  *
91  * @states: (element-type AtspiStateType): An array of states with which to initialize
92  * the state set.
93  *
94  * Returns: A new #AtspiStateSet with the given states.
95  **/
96 AtspiStateSet *
97 atspi_state_set_new (GArray *states)
98 {
99   AtspiStateSet *set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
100   gint i;
101
102   if (!set || !states)
103     return set;
104
105   for (i = 0; i < states->len; i++)
106     atspi_state_set_add (set, g_array_index (states, AtspiStateType, i));
107   return set;
108 }
109
110 AtspiStateSet *
111 _atspi_state_set_new_internal (AtspiAccessible *accessible, gint64 states)
112 {
113   AtspiStateSet *set;
114   
115   set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
116   g_return_val_if_fail (set != NULL, NULL);
117
118   set->accessible = accessible;
119   set->states = states;
120   return set;
121 }
122
123 void
124 atspi_state_set_set_by_name (AtspiStateSet *set, const gchar *name, gboolean enabled)
125 {
126   gint i = 0;
127
128   if (set->accessible &&
129       !(set->accessible->cached_properties & ATSPI_CACHE_STATES))
130     return;
131
132   /* TODO: This could perhaps be optimized */
133   for (i = 0; state_names [i]; i++)
134   {
135     if (!strcmp (state_names [i], name))
136     {
137       if (enabled)
138         set->states |= ((gint64)1 << i);
139       else
140         set->states &= ~((gint64)1 << i);
141       return;
142     }
143   }
144   g_warning ("at-spi: Attempt to set unknown state '%s'", name);
145 }
146
147 static void
148 refresh_states (AtspiStateSet *set)
149 {
150   GArray *state_array;
151   dbus_uint32_t *states;
152
153   if (!set->accessible ||
154       (set->accessible->cached_properties & ATSPI_CACHE_STATES))
155     return;
156
157   if (!_atspi_dbus_call (set->accessible, atspi_interface_accessible, "GetState", NULL, "=>au", &state_array))
158     return;
159
160   states = (dbus_uint32_t *) state_array->data;
161
162   set->states = ((gint64)states [1]) << 32;
163   set->states |= (gint64) states [0];
164   g_array_free (state_array, TRUE);
165 }
166
167 /**
168  * atspi_state_set_add:
169  *
170  * @set: a pointer to the #AtspiStateSet object on which to operate.
171  * @state: an #AtspiStateType to be added to the specified #AtspiStateSet.
172  *
173  * Add a particular #AtspiState to an #AtspiStateSet (i.e. set the
174  *       given state to #TRUE in the stateset.
175  *
176  **/
177 void
178 atspi_state_set_add (AtspiStateSet *set, AtspiStateType state)
179 {
180   g_return_if_fail (set != NULL);
181   set->states |= (((gint64)1) << state);
182 }
183
184 /**
185  * atspi_state_set_compare:
186  * @set: a pointer to the first #AtspiStateSet object on which to operate.
187  * @set: a pointer to the second #AtspiStateSet setect on which to operate.
188  *
189  * Determine the differences between two instances of #AtspiStateSet.
190  *.
191  * @see AtspiStateSet_equals().
192  *
193  * Returns: (transfer full): an #AtspiStateSet object containing all states
194  *          contained on one of the two sets but not the other.
195  *
196  **/
197 AtspiStateSet *
198 atspi_state_set_compare (AtspiStateSet *set,
199                          AtspiStateSet *set2)
200 {
201   g_return_val_if_fail (set != NULL, NULL);
202   g_return_val_if_fail (set2 != NULL, NULL);
203
204   return _atspi_state_set_new_internal (NULL, set->states ^ set2->states);
205 }
206
207 /**
208  * atspi_state_set_contains:
209  * @set: a pointer to the #AtspiStateSet object on which to operate.
210  * @state: an #AtspiStateType for which the specified #AtspiStateSet
211  *       will be queried.
212  *
213  * Determine whether a given #AtspiStateSet includes a given state; that is,
214  *       whether @state is true for the stateset in question.
215  *
216  * Returns: #TRUE if @state is true/included in the given #AtspiStateSet,
217  *          otherwise #FALSE.
218  *
219  **/
220 gboolean
221 atspi_state_set_contains (AtspiStateSet *set,
222                              AtspiStateType state)
223 {
224   if (!set)
225     return FALSE;
226   refresh_states (set);
227   return (set->states & ((gint64)1 << state)) ? TRUE : FALSE;
228 }
229
230 /**
231  * atspi_state_set_equals:
232  * @set: a pointer to the first #AtspiStateSet object on which to operate.
233  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
234  *
235  * Determine whether two instances of #AtspiStateSet are equivalent (i.e.
236  *         consist of the same #AtspiStates).  Useful for checking multiple
237  *         state variables at once; construct the target state then compare against it.
238  *
239  * @see AtspiStateSet_compare().
240  *
241  * Returns: #TRUE if the two #AtspiStateSets are equivalent,
242  *          otherwise #FALSE.
243  *
244  **/
245 gboolean
246 atspi_state_set_equals (AtspiStateSet *set,
247                            AtspiStateSet *set2)
248 {
249   if (set == set2)
250     return TRUE;
251   if (set == NULL || set2 == NULL)
252     return FALSE;
253   return (set->states == set2->states);
254 }
255
256 /**
257  * atspi_state_set_get_states:
258  *
259  * @set: The #AtspiStateSet to be queried.
260  *
261  * Return the states in an #AtspiStateSet as an array.
262  *
263  * Returns: (element-type AtspiStateType) (transfer full): A #GArray of state
264  *          types representing the current state.
265  **/
266 GArray *
267 atspi_state_set_get_states (AtspiStateSet *set)
268 {
269   gint i = 0;
270   guint64 val = 1;
271   GArray *ret;
272
273   g_return_val_if_fail (set != NULL, NULL);
274   refresh_states (set);
275   ret = g_array_new (TRUE, TRUE, sizeof (AtspiStateType));
276   if (!ret)
277     return NULL;
278   for (i = 0; i < 64; i++)
279   {
280     if (set->states & val)
281     {
282       GArray *new_array = g_array_append_val (ret, i);
283       if (new_array)
284         ret = new_array;
285     }
286     val <<= 1;
287   }
288   return ret;
289 }
290
291 /**
292  * atspi_state_set_is_empty:
293  *
294  * @set: The #AtspiStateSet to query.
295  *
296  * Returns: #TRUE if the state set contains no states; #FALSE otherwise.
297  **/
298 gboolean
299 atspi_state_set_is_empty (AtspiStateSet *set)
300 {
301   return (set->states == 0);
302 }
303
304 /**
305  * atspi_state_set_remove:
306  *
307  * @set: a pointer to the #AtspiStateSet object on which to operate.
308  * @state: an #AtspiStateType to remove from the specifiedn state set.
309  *
310  * Remove a particular #AtspiState to an #AtspiStateSet (i.e. set the
311  *       given state to #FALSE in the stateset.)
312  *
313  **/
314 void
315 atspi_state_set_remove (AtspiStateSet *set, AtspiStateType state)
316 {
317   g_return_if_fail (set != NULL);
318   set->states &= ~((gint64)1 << state);
319 }
320