2.34.0
[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 Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 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  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, 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   if (set->accessible &&
94       !(set->accessible->cached_properties & ATSPI_CACHE_STATES))
95     return;
96
97   type_class = g_type_class_ref (ATSPI_TYPE_STATE_TYPE);
98
99   value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
100
101   if (!value)
102   {
103     g_warning ("AT-SPI: Attempt to set unknown state '%s'", name);
104   }
105   else
106     if (enabled)
107       set->states |= ((gint64)1 << value->value);
108     else
109       set->states &= ~((gint64)1 << value->value);
110
111   g_type_class_unref (type_class);
112 }
113
114 static void
115 refresh_states (AtspiStateSet *set)
116 {
117   GArray *state_array;
118   dbus_uint32_t *states;
119
120   if (!set->accessible ||
121       (set->accessible->cached_properties & ATSPI_CACHE_STATES))
122     return;
123
124   if (!_atspi_dbus_call (set->accessible, atspi_interface_accessible, "GetState", NULL, "=>au", &state_array))
125     return;
126
127   states = (dbus_uint32_t *) state_array->data;
128
129   set->states = ((gint64)states [1]) << 32;
130   set->states |= (gint64) states [0];
131   g_array_free (state_array, TRUE);
132 }
133
134 /**
135  * atspi_state_set_add:
136  * @set: a pointer to the #AtspiStateSet object on which to operate.
137  * @state: an #AtspiStateType to be added to the specified #AtspiStateSet.
138  *
139  * Adds a particular #AtspiState to an #AtspiStateSet (i.e. sets the
140  *       given state to #TRUE in the stateset).
141  *
142  **/
143 void
144 atspi_state_set_add (AtspiStateSet *set, AtspiStateType state)
145 {
146   g_return_if_fail (set != NULL);
147   set->states |= (((gint64)1) << state);
148 }
149
150 /**
151  * atspi_state_set_compare:
152  * @set: a pointer to the first #AtspiStateSet object on which to operate.
153  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
154  *
155  * Determines the differences between two instances of #AtspiStateSet.
156  *
157  * @see #atspi_state_set_equals.
158  *
159  * Returns: (transfer full): an #AtspiStateSet object containing all states
160  * contained on one of the two sets but not the other.
161  *
162  **/
163 AtspiStateSet *
164 atspi_state_set_compare (AtspiStateSet *set,
165                          AtspiStateSet *set2)
166 {
167   g_return_val_if_fail (set != NULL, NULL);
168   g_return_val_if_fail (set2 != NULL, NULL);
169
170   return _atspi_state_set_new_internal (NULL, set->states ^ set2->states);
171 }
172
173 /**
174  * atspi_state_set_contains:
175  * @set: a pointer to the #AtspiStateSet object on which to operate.
176  * @state: an #AtspiStateType for which the specified #AtspiStateSet
177  *          will be queried.
178  *
179  * Determines whether a given #AtspiStateSet includes a given state; that is,
180  *          whether @state is true for the @set in question.
181  *
182  * Returns: #TRUE if @state is true/included in the given #AtspiStateSet,
183  *          otherwise #FALSE.
184  *
185  **/
186 gboolean
187 atspi_state_set_contains (AtspiStateSet *set,
188                              AtspiStateType state)
189 {
190   if (!set)
191     return FALSE;
192   refresh_states (set);
193   return (set->states & ((gint64)1 << state)) ? TRUE : FALSE;
194 }
195
196 /**
197  * atspi_state_set_equals:
198  * @set: a pointer to the first #AtspiStateSet object on which to operate.
199  * @set2: a pointer to the second #AtspiStateSet object on which to operate.
200  *
201  * Determines whether two instances of #AtspiStateSet are equivalent (i.e.
202  *          consist of the same #AtspiStates).  Useful for checking multiple
203  *          state variables at once.
204  *
205  * @see #atspi_state_set_compare.
206  *
207  * Returns: #TRUE if the two #AtspiStateSets are equivalent,
208  * otherwise #FALSE.
209  *
210  **/
211 gboolean
212 atspi_state_set_equals (AtspiStateSet *set,
213                            AtspiStateSet *set2)
214 {
215   if (set == set2)
216     return TRUE;
217   if (set == NULL || set2 == NULL)
218     return FALSE;
219   return (set->states == set2->states);
220 }
221
222 /**
223  * atspi_state_set_get_states:
224  * @set: The #AtspiStateSet to be queried.
225  *
226  * Returns the states in an #AtspiStateSet as an array.
227  *
228  * Returns: (element-type AtspiStateType) (transfer full): A #GArray of state
229  *          types representing the current state.
230  **/
231 GArray *
232 atspi_state_set_get_states (AtspiStateSet *set)
233 {
234   gint i = 0;
235   guint64 val = 1;
236   GArray *ret;
237
238   g_return_val_if_fail (set != NULL, NULL);
239   refresh_states (set);
240   ret = g_array_new (TRUE, TRUE, sizeof (AtspiStateType));
241   if (!ret)
242     return NULL;
243   for (i = 0; i < 64; i++)
244   {
245     if (set->states & val)
246       ret = g_array_append_val (ret, i);
247     val <<= 1;
248   }
249   return ret;
250 }
251
252 /**
253  * atspi_state_set_is_empty:
254  * @set: The #AtspiStateSet to query.
255  *
256  * Returns: #TRUE if the state set contains no states; #FALSE otherwise.
257  **/
258 gboolean
259 atspi_state_set_is_empty (AtspiStateSet *set)
260 {
261   return (set->states == 0);
262 }
263
264 /**
265  * atspi_state_set_remove:
266  * @set: a pointer to the #AtspiStateSet object on which to operate.
267  * @state: an #AtspiStateType to remove from the specified @set.
268  *
269  * Removes a particular #AtspiState to an #AtspiStateSet (i.e. sets the
270  *       given state to #FALSE in the stateset.)
271  *
272  **/
273 void
274 atspi_state_set_remove (AtspiStateSet *set, AtspiStateType state)
275 {
276   g_return_if_fail (set != NULL);
277   set->states &= ~((gint64)1 << state);
278 }