roles: new roles for ARIA roles
[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 void
32 atspi_state_set_init (AtspiStateSet *set)
33 {
34   set->states = 0;
35 }
36
37 static void
38 atspi_state_set_class_init (AtspiStateSetClass* klass)
39 {
40 }
41
42 /**
43  * atspi_state_set_new:
44  * @states: (element-type AtspiStateType): An array of states with which the
45  *          method initializes the state set.
46  *
47  * Generates an #AtspiStateSet with the given @states.
48  *
49  * Returns: A new #AtspiStateSet with the given states.
50  **/
51 AtspiStateSet *
52 atspi_state_set_new (GArray *states)
53 {
54   AtspiStateSet *set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
55   gint i;
56
57   if (!set || !states)
58     return set;
59
60   for (i = 0; i < states->len; i++)
61     atspi_state_set_add (set, g_array_index (states, AtspiStateType, i));
62   return set;
63 }
64
65 AtspiStateSet *
66 _atspi_state_set_new_internal (AtspiAccessible *accessible, gint64 states)
67 {
68   AtspiStateSet *set;
69   
70   set = g_object_new (ATSPI_TYPE_STATE_SET, NULL);
71   g_return_val_if_fail (set != NULL, NULL);
72
73   set->accessible = accessible;
74   set->states = states;
75   return set;
76 }
77
78 /**
79  * atspi_state_set_set_by_name:
80  * @set: a pointer to the #AtspiStateSet object on which to operate.
81  * @name: a string corresponding to a state name.
82  * @enabled: if #TRUE, @name should be enabled in the @set in question;
83  *          otherwise, it should be disabled.
84  *
85  * Enables/disables a state in an #AtspiStateSet according to its @name.
86  **/
87 void
88 atspi_state_set_set_by_name (AtspiStateSet *set, const gchar *name, gboolean enabled)
89 {
90   GTypeClass *type_class;
91   GEnumValue *value;
92
93   type_class = g_type_class_ref (ATSPI_TYPE_STATE_TYPE);
94
95   if (set->accessible &&
96       !(set->accessible->cached_properties & ATSPI_CACHE_STATES))
97     return;
98
99   value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
100   if (!value)
101   {
102     g_warning ("AT-SPI: Attempt to set unknown state '%s'", name);
103   }
104
105   if (enabled)
106     set->states |= ((gint64)1 << value->value);
107   else
108     set->states &= ~((gint64)1 << value->value);
109 }
110
111 static void
112 refresh_states (AtspiStateSet *set)
113 {
114   GArray *state_array;
115   dbus_uint32_t *states;
116
117   if (!set->accessible ||
118       (set->accessible->cached_properties & ATSPI_CACHE_STATES))
119     return;
120
121   if (!_atspi_dbus_call (set->accessible, atspi_interface_accessible, "GetState", NULL, "=>au", &state_array))
122     return;
123
124   states = (dbus_uint32_t *) state_array->data;
125
126   set->states = ((gint64)states [1]) << 32;
127   set->states |= (gint64) states [0];
128   g_array_free (state_array, TRUE);
129 }
130
131 /**
132  * atspi_state_set_add:
133  * @set: a pointer to the #AtspiStateSet object on which to operate.
134  * @state: an #AtspiStateType to be added to the specified #AtspiStateSet.
135  *
136  * Adds a particular #AtspiState to an #AtspiStateSet (i.e. sets the
137  *       given state to #TRUE in the stateset).
138  *
139  **/
140 void
141 atspi_state_set_add (AtspiStateSet *set, AtspiStateType state)
142 {
143   g_return_if_fail (set != NULL);
144   set->states |= (((gint64)1) << state);
145 }
146
147 /**
148  * atspi_state_set_compare:
149  * @set: a pointer to the first #AtspiStateSet object on which to operate.
150  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
151  *
152  * Determines the differences between two instances of #AtspiStateSet.
153  *
154  * @see #atspi_state_set_equals.
155  *
156  * Returns: (transfer full): an #AtspiStateSet object containing all states
157  * contained on one of the two sets but not the other.
158  *
159  **/
160 AtspiStateSet *
161 atspi_state_set_compare (AtspiStateSet *set,
162                          AtspiStateSet *set2)
163 {
164   g_return_val_if_fail (set != NULL, NULL);
165   g_return_val_if_fail (set2 != NULL, NULL);
166
167   return _atspi_state_set_new_internal (NULL, set->states ^ set2->states);
168 }
169
170 /**
171  * atspi_state_set_contains:
172  * @set: a pointer to the #AtspiStateSet object on which to operate.
173  * @state: an #AtspiStateType for which the specified #AtspiStateSet
174  *          will be queried.
175  *
176  * Determines whether a given #AtspiStateSet includes a given state; that is,
177  *          whether @state is true for the @set in question.
178  *
179  * Returns: #TRUE if @state is true/included in the given #AtspiStateSet,
180  *          otherwise #FALSE.
181  *
182  **/
183 gboolean
184 atspi_state_set_contains (AtspiStateSet *set,
185                              AtspiStateType state)
186 {
187   if (!set)
188     return FALSE;
189   refresh_states (set);
190   return (set->states & ((gint64)1 << state)) ? TRUE : FALSE;
191 }
192
193 /**
194  * atspi_state_set_equals:
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 whether two instances of #AtspiStateSet are equivalent (i.e.
199  *          consist of the same #AtspiStates).  Useful for checking multiple
200  *          state variables at once.
201  *
202  * @see #atspi_state_set_compare.
203  *
204  * Returns: #TRUE if the two #AtspiStateSets are equivalent,
205  * otherwise #FALSE.
206  *
207  **/
208 gboolean
209 atspi_state_set_equals (AtspiStateSet *set,
210                            AtspiStateSet *set2)
211 {
212   if (set == set2)
213     return TRUE;
214   if (set == NULL || set2 == NULL)
215     return FALSE;
216   return (set->states == set2->states);
217 }
218
219 /**
220  * atspi_state_set_get_states:
221  * @set: The #AtspiStateSet to be queried.
222  *
223  * Returns the states in an #AtspiStateSet as an array.
224  *
225  * Returns: (element-type AtspiStateType) (transfer full): A #GArray of state
226  *          types representing the current state.
227  **/
228 GArray *
229 atspi_state_set_get_states (AtspiStateSet *set)
230 {
231   gint i = 0;
232   guint64 val = 1;
233   GArray *ret;
234
235   g_return_val_if_fail (set != NULL, NULL);
236   refresh_states (set);
237   ret = g_array_new (TRUE, TRUE, sizeof (AtspiStateType));
238   if (!ret)
239     return NULL;
240   for (i = 0; i < 64; i++)
241   {
242     if (set->states & val)
243       ret = g_array_append_val (ret, i);
244     val <<= 1;
245   }
246   return ret;
247 }
248
249 /**
250  * atspi_state_set_is_empty:
251  * @set: The #AtspiStateSet to query.
252  *
253  * Returns: #TRUE if the state set contains no states; #FALSE otherwise.
254  **/
255 gboolean
256 atspi_state_set_is_empty (AtspiStateSet *set)
257 {
258   return (set->states == 0);
259 }
260
261 /**
262  * atspi_state_set_remove:
263  * @set: a pointer to the #AtspiStateSet object on which to operate.
264  * @state: an #AtspiStateType to remove from the specified @set.
265  *
266  * Removes a particular #AtspiState to an #AtspiStateSet (i.e. sets the
267  *       given state to #FALSE in the stateset.)
268  *
269  **/
270 void
271 atspi_state_set_remove (AtspiStateSet *set, AtspiStateType state)
272 {
273   g_return_if_fail (set != NULL);
274   set->states &= ~((gint64)1 << state);
275 }