Updated FSF's address
[platform/upstream/atk.git] / atk / atkstateset.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <glib-object.h>
19
20 #include "atkobject.h"
21 #include "atkstateset.h"
22
23 /**
24  * SECTION:atkstateset
25  * @Short_description: An AtkStateSet determines a component's state set.
26  * @Title:AtkStateSet
27  *
28  * An AtkStateSet determines a component's state set. It is composed
29  * of a set of AtkStates.
30  */
31
32 #define ATK_STATE(state_enum)             ((AtkState)((guint64)1 << ((state_enum)%64)))
33
34 struct _AtkRealStateSet
35 {
36   GObject parent;
37
38   AtkState state;
39 };
40
41 typedef struct _AtkRealStateSet      AtkRealStateSet;
42
43 static void            atk_state_set_class_init       (AtkStateSetClass  *klass);
44
45 GType
46 atk_state_set_get_type (void)
47 {
48   static GType type = 0;
49
50   if (!type)
51     {
52       static const GTypeInfo typeInfo =
53       {
54         sizeof (AtkStateSetClass),
55         (GBaseInitFunc) NULL,
56         (GBaseFinalizeFunc) NULL,
57         (GClassInitFunc) atk_state_set_class_init,
58         (GClassFinalizeFunc) NULL,
59         NULL,
60         sizeof (AtkRealStateSet),
61         0,
62         (GInstanceInitFunc) NULL,
63       } ;
64       type = g_type_register_static (G_TYPE_OBJECT, "AtkStateSet", &typeInfo, 0) ;
65     }
66   return type;
67 }
68
69 static void
70 atk_state_set_class_init (AtkStateSetClass *klass)
71 {
72 }
73
74 /**
75  * atk_state_set_new:
76  * 
77  * Creates a new empty state set.
78  * 
79  * Returns: a new #AtkStateSet 
80  **/
81 AtkStateSet*
82 atk_state_set_new (void)
83 {
84   return (AtkStateSet*) g_object_new (ATK_TYPE_STATE_SET, NULL);
85 }
86
87 /**
88  * atk_state_set_is_empty:
89  * @set: an #AtkStateType
90  *
91  * Checks whether the state set is empty, i.e. has no states set.
92  *
93  * Returns: %TRUE if @set has no states set, otherwise %FALSE
94  **/
95 gboolean
96 atk_state_set_is_empty (AtkStateSet   *set)
97 {
98   AtkRealStateSet *real_set;
99   g_return_val_if_fail (ATK_IS_STATE_SET (set), FALSE);
100
101   real_set = (AtkRealStateSet *)set;
102
103   if (real_set->state)
104     return FALSE;
105   else
106     return TRUE;
107 }
108
109 /**
110  * atk_state_set_add_state:
111  * @set: an #AtkStateSet
112  * @type: an #AtkStateType
113  *
114  * Add a new state for the specified type to the current state set if
115  * it is not already present.
116  *
117  * Returns: %TRUE if  the state for @type is not already in @set.
118  **/
119 gboolean
120 atk_state_set_add_state (AtkStateSet   *set,
121                          AtkStateType  type)
122 {
123   AtkRealStateSet *real_set;
124   g_return_val_if_fail (ATK_IS_STATE_SET (set), FALSE);
125
126   real_set = (AtkRealStateSet *)set;
127
128   if (real_set->state & ATK_STATE (type))
129     return FALSE;
130   else
131   {
132     real_set->state |= ATK_STATE (type);
133     return TRUE;
134   }
135 }
136 /**
137  * atk_state_set_add_states:
138  * @set: an #AtkStateSet
139  * @types: (array length=n_types): an array of #AtkStateType
140  * @n_types: The number of elements in the array
141  *
142  * Add the states for the specified types to the current state set.
143  **/
144 void
145 atk_state_set_add_states (AtkStateSet   *set,
146                           AtkStateType  *types,
147                           gint          n_types)
148 {
149   AtkRealStateSet *real_set;
150   gint     i;
151   g_return_if_fail (ATK_IS_STATE_SET (set));
152
153   real_set = (AtkRealStateSet *)set;
154
155   for (i = 0; i < n_types; i++)
156   {
157     real_set->state |= ATK_STATE (types[i]);
158   }
159 }
160
161 /**
162  * atk_state_set_clear_states:
163  * @set: an #AtkStateSet
164  *
165  * Removes all states from the state set.
166  **/
167 void
168 atk_state_set_clear_states (AtkStateSet   *set)
169 {
170   AtkRealStateSet *real_set;
171   g_return_if_fail (ATK_IS_STATE_SET (set));
172
173   real_set = (AtkRealStateSet *)set;
174
175   real_set->state = 0;
176 }
177
178 /**
179  * atk_state_set_contains_state:
180  * @set: an #AtkStateSet
181  * @type: an #AtkStateType
182  *
183  * Checks whether the state for the specified type is in the specified set.
184  *
185  * Returns: %TRUE if @type is the state type is in @set.
186  **/
187 gboolean
188 atk_state_set_contains_state (AtkStateSet   *set,
189                               AtkStateType  type)
190 {
191   AtkRealStateSet *real_set;
192   g_return_val_if_fail (ATK_IS_STATE_SET (set), FALSE);
193
194   real_set = (AtkRealStateSet *)set;
195
196   if (real_set->state & ATK_STATE (type))
197     return TRUE;
198   else
199     return FALSE;
200 }
201
202 /**
203  * atk_state_set_contains_states:
204  * @set: an #AtkStateSet
205  * @types: (array length=n_types): an array of #AtkStateType
206  * @n_types: The number of elements in the array
207  *
208  * Checks whether the states for all the specified types are in the 
209  * specified set.
210  *
211  * Returns: %TRUE if all the states for @type are in @set.
212  **/
213 gboolean
214 atk_state_set_contains_states (AtkStateSet   *set,
215                                AtkStateType  *types,
216                                gint          n_types)
217 {
218   AtkRealStateSet *real_set;
219   gint i;
220   g_return_val_if_fail (ATK_IS_STATE_SET (set), FALSE);
221
222   real_set = (AtkRealStateSet *)set;
223
224   for (i = 0; i < n_types; i++)
225   {
226     if (!(real_set->state & ATK_STATE (types[i])))
227       return FALSE;
228   }
229   return TRUE;
230 }
231
232 /**
233  * atk_state_set_remove_state:
234  * @set: an #AtkStateSet
235  * @type: an #AtkType
236  *
237  * Removes the state for the specified type from the state set.
238  *
239  * Returns: %TRUE if @type was the state type is in @set.
240  **/
241 gboolean
242 atk_state_set_remove_state (AtkStateSet  *set,
243                             AtkStateType type)
244 {
245   AtkRealStateSet *real_set;
246   g_return_val_if_fail (ATK_IS_STATE_SET (set), FALSE);
247
248   real_set = (AtkRealStateSet *)set;
249
250   if (real_set->state & ATK_STATE (type))
251   {
252     real_set->state ^= ATK_STATE (type);
253     return TRUE;
254   }
255   else
256     return FALSE;
257 }
258
259 /**
260  * atk_state_set_and_sets:
261  * @set: an #AtkStateSet
262  * @compare_set: another #AtkStateSet
263  *
264  * Constructs the intersection of the two sets, returning %NULL if the
265  * intersection is empty.
266  *
267  * Returns: (transfer full): a new #AtkStateSet which is the intersection of
268  * the two sets.
269  **/
270 AtkStateSet*
271 atk_state_set_and_sets (AtkStateSet  *set,
272                         AtkStateSet  *compare_set)
273 {
274   AtkRealStateSet *real_set, *real_compare_set;
275   AtkStateSet *return_set = NULL;
276   AtkState state;
277
278   g_return_val_if_fail (ATK_IS_STATE_SET (set), NULL);
279   g_return_val_if_fail (ATK_IS_STATE_SET (compare_set), NULL);
280
281   real_set = (AtkRealStateSet *)set;
282   real_compare_set = (AtkRealStateSet *)compare_set;
283
284   state = real_set->state & real_compare_set->state;
285   if (state)
286   {
287     return_set = atk_state_set_new();
288     ((AtkRealStateSet *) return_set)->state = state;
289   }
290   return return_set;
291 }
292
293 /**
294  * atk_state_set_or_sets:
295  * @set: an #AtkStateSet
296  * @compare_set: another #AtkStateSet
297  *
298  * Constructs the union of the two sets.
299  *
300  * Returns: (transfer full): a new #AtkStateSet which is the union of the two
301  * sets, returning %NULL is empty.
302  **/
303 AtkStateSet*
304 atk_state_set_or_sets (AtkStateSet  *set,
305                        AtkStateSet  *compare_set)
306 {
307   AtkRealStateSet *real_set, *real_compare_set;
308   AtkStateSet *return_set = NULL;
309   AtkState state;
310
311   g_return_val_if_fail (ATK_IS_STATE_SET (set), NULL);
312   g_return_val_if_fail (ATK_IS_STATE_SET (compare_set), NULL);
313
314   real_set = (AtkRealStateSet *)set;
315   real_compare_set = (AtkRealStateSet *)compare_set;
316
317   state = real_set->state | real_compare_set->state;
318
319   if (state)
320   {
321     return_set = atk_state_set_new();
322     ((AtkRealStateSet *) return_set)->state = state;
323   }
324
325   return return_set;
326 }
327
328 /**
329  * atk_state_set_xor_sets:
330  * @set: an #AtkStateSet
331  * @compare_set: another #AtkStateSet
332  *
333  * Constructs the exclusive-or of the two sets, returning %NULL is empty.
334  * The set returned by this operation contains the states in exactly
335  * one of the two sets.
336  *
337  * Returns: (transfer full): a new #AtkStateSet which contains the states
338  * which are in exactly one of the two sets.
339  **/
340 AtkStateSet*
341 atk_state_set_xor_sets (AtkStateSet  *set,
342                         AtkStateSet  *compare_set)
343 {
344   AtkRealStateSet *real_set, *real_compare_set;
345   AtkStateSet *return_set = NULL;
346   AtkState state, state1, state2;
347
348   g_return_val_if_fail (ATK_IS_STATE_SET (set), NULL);
349   g_return_val_if_fail (ATK_IS_STATE_SET (compare_set), NULL);
350
351   real_set = (AtkRealStateSet *)set;
352   real_compare_set = (AtkRealStateSet *)compare_set;
353
354   state1 = real_set->state & (~real_compare_set->state);
355   state2 = (~real_set->state) & real_compare_set->state;
356   state = state1 | state2;
357
358   if (state)
359   {
360     return_set = atk_state_set_new();
361     ((AtkRealStateSet *) return_set)->state = state;
362   }
363   return return_set;
364 }