Fixed bug 85980.
[platform/core/uifw/at-spi2-atk.git] / libspi / 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 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* stateset.c : implements the StateSet interface */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <libspi/stateset.h>
28
29
30 static Accessibility_StateType *accessible_state_types = NULL;
31 static AtkStateType *atk_state_types = NULL;
32
33
34 static gboolean
35 spi_init_state_type_tables (void)
36 {
37   gint i;
38
39   if (accessible_state_types || atk_state_types)
40     return FALSE;
41   if (!accessible_state_types)
42     accessible_state_types = g_new (Accessibility_StateType, ATK_STATE_LAST_DEFINED);
43   if (!atk_state_types)
44     atk_state_types = g_new (AtkStateType, Accessibility_STATE_LAST_DEFINED);
45   g_return_val_if_fail (accessible_state_types, FALSE);
46   g_return_val_if_fail (atk_state_types, FALSE);
47   
48   for (i = 0; i < Accessibility_STATE_LAST_DEFINED; i++)
49     {
50       atk_state_types[i] = ATK_STATE_INVALID;
51     }
52
53   for (i=0; i < ATK_STATE_LAST_DEFINED; i++)
54     {
55       accessible_state_types[i] = Accessibility_STATE_INVALID;  
56     }
57
58   accessible_state_types[ATK_STATE_ACTIVE] = Accessibility_STATE_ACTIVE;
59   atk_state_types[Accessibility_STATE_ACTIVE] = ATK_STATE_ACTIVE;
60   accessible_state_types[ATK_STATE_ARMED] = Accessibility_STATE_ARMED;
61   atk_state_types[Accessibility_STATE_ARMED] = ATK_STATE_ARMED;
62   accessible_state_types[ATK_STATE_BUSY] = Accessibility_STATE_BUSY;
63   atk_state_types[Accessibility_STATE_BUSY] = ATK_STATE_BUSY;
64   accessible_state_types[ATK_STATE_CHECKED] = Accessibility_STATE_CHECKED;
65   atk_state_types[Accessibility_STATE_CHECKED] = ATK_STATE_CHECKED;
66   accessible_state_types[ATK_STATE_DEFUNCT] = Accessibility_STATE_DEFUNCT;
67   atk_state_types[Accessibility_STATE_DEFUNCT] = ATK_STATE_DEFUNCT;
68   accessible_state_types[ATK_STATE_EDITABLE] = Accessibility_STATE_EDITABLE;
69   atk_state_types[Accessibility_STATE_EDITABLE] = ATK_STATE_EDITABLE;  
70   accessible_state_types[ATK_STATE_ENABLED] = Accessibility_STATE_ENABLED;
71   atk_state_types[Accessibility_STATE_ENABLED] = ATK_STATE_ENABLED;  
72   accessible_state_types[ATK_STATE_EXPANDABLE] = Accessibility_STATE_EXPANDABLE;
73   atk_state_types[Accessibility_STATE_EXPANDABLE] = ATK_STATE_EXPANDABLE;
74   accessible_state_types[ATK_STATE_EXPANDED] = Accessibility_STATE_EXPANDED;
75   atk_state_types[Accessibility_STATE_EXPANDED] = ATK_STATE_EXPANDED;
76   accessible_state_types[ATK_STATE_FOCUSABLE] = Accessibility_STATE_FOCUSABLE;
77   atk_state_types[Accessibility_STATE_FOCUSABLE] = ATK_STATE_FOCUSABLE;
78   accessible_state_types[ATK_STATE_FOCUSED] = Accessibility_STATE_FOCUSED;
79   atk_state_types[Accessibility_STATE_FOCUSED] = ATK_STATE_FOCUSED;
80   accessible_state_types[ATK_STATE_HORIZONTAL] = Accessibility_STATE_HORIZONTAL;
81   atk_state_types[Accessibility_STATE_HORIZONTAL] = ATK_STATE_HORIZONTAL;
82   accessible_state_types[ATK_STATE_ICONIFIED] = Accessibility_STATE_ICONIFIED;
83   atk_state_types[Accessibility_STATE_ICONIFIED] = ATK_STATE_ICONIFIED;
84   accessible_state_types[ATK_STATE_MODAL] = Accessibility_STATE_MODAL;
85   atk_state_types[Accessibility_STATE_MODAL] = ATK_STATE_MODAL;
86   accessible_state_types[ATK_STATE_MULTI_LINE] = Accessibility_STATE_MULTI_LINE;
87   atk_state_types[Accessibility_STATE_MULTI_LINE] = ATK_STATE_MULTI_LINE;
88   accessible_state_types[ATK_STATE_MULTISELECTABLE] = Accessibility_STATE_MULTISELECTABLE;
89   atk_state_types[Accessibility_STATE_MULTISELECTABLE] = ATK_STATE_MULTISELECTABLE;
90   accessible_state_types[ATK_STATE_OPAQUE] = Accessibility_STATE_OPAQUE;
91   atk_state_types[Accessibility_STATE_OPAQUE] = ATK_STATE_OPAQUE;
92   accessible_state_types[ATK_STATE_PRESSED] = Accessibility_STATE_PRESSED;
93   atk_state_types[Accessibility_STATE_PRESSED] = ATK_STATE_PRESSED;
94   accessible_state_types[ATK_STATE_RESIZABLE] = Accessibility_STATE_RESIZABLE;
95   atk_state_types[Accessibility_STATE_RESIZABLE] = ATK_STATE_RESIZABLE;
96   accessible_state_types[ATK_STATE_SELECTABLE] = Accessibility_STATE_SELECTABLE;
97   atk_state_types[Accessibility_STATE_SELECTABLE] = ATK_STATE_SELECTABLE;
98   accessible_state_types[ATK_STATE_SELECTED] = Accessibility_STATE_SELECTED;
99   atk_state_types[Accessibility_STATE_SELECTED] = ATK_STATE_SELECTED;
100   accessible_state_types[ATK_STATE_SENSITIVE] = Accessibility_STATE_SENSITIVE;
101   atk_state_types[Accessibility_STATE_SENSITIVE] = ATK_STATE_SENSITIVE;
102   accessible_state_types[ATK_STATE_SHOWING] = Accessibility_STATE_SHOWING;
103   atk_state_types[Accessibility_STATE_SHOWING] = ATK_STATE_SHOWING;
104   accessible_state_types[ATK_STATE_SINGLE_LINE] = Accessibility_STATE_SINGLE_LINE;
105   atk_state_types[Accessibility_STATE_SINGLE_LINE] = ATK_STATE_SINGLE_LINE;
106   accessible_state_types[ATK_STATE_STALE] = Accessibility_STATE_STALE;
107   atk_state_types[Accessibility_STATE_STALE] = ATK_STATE_STALE;
108   accessible_state_types[ATK_STATE_TRANSIENT] = Accessibility_STATE_TRANSIENT;
109   atk_state_types[Accessibility_STATE_TRANSIENT] = ATK_STATE_TRANSIENT;
110   accessible_state_types[ATK_STATE_VERTICAL] = Accessibility_STATE_VERTICAL;
111   atk_state_types[Accessibility_STATE_VERTICAL] = ATK_STATE_VERTICAL;
112   accessible_state_types[ATK_STATE_VISIBLE] = Accessibility_STATE_VISIBLE;
113   atk_state_types[Accessibility_STATE_VISIBLE] = ATK_STATE_VISIBLE;
114
115   return TRUE;
116 }
117
118
119
120 static AtkStateSet *
121 atk_state_set_from_servant (PortableServer_Servant servant)
122 {
123   SpiBase *base = SPI_BASE (bonobo_object_from_servant(servant));
124
125   g_return_val_if_fail (base, NULL);
126   return  ATK_STATE_SET(base->gobj);
127 }
128
129
130
131 static AtkStateSet *
132 atk_state_set_from_accessibility_state_set (Accessibility_StateSet set, CORBA_Environment *ev)
133 {
134   AtkStateType *states, *tmp;
135   AtkStateSet *rv;
136   gint i;
137   Accessibility_StateSeq *seq;
138   
139   seq = Accessibility_StateSet_getStates (set, ev);
140   states = tmp = g_new (AtkStateType, seq->_length);
141   for (i = 0; i < seq->_length; i++)
142     *tmp++ = atk_state_types[seq->_buffer[i]];
143   rv = atk_state_set_new ();
144   atk_state_set_add_states (rv, states, seq->_length);
145   CORBA_free (seq);
146   g_free (states);
147   return rv;
148 }
149
150
151
152 SpiStateSet *
153 spi_state_set_new (AtkStateSet *obj)
154 {
155   SpiStateSet *new_set = g_object_new (SPI_STATE_SET_TYPE, NULL);
156   spi_base_construct (SPI_BASE (new_set), G_OBJECT (obj));
157   return new_set;
158 }
159
160
161
162 static CORBA_boolean
163 impl_contains (PortableServer_Servant servant,
164                const Accessibility_StateType state,
165                CORBA_Environment * ev)
166 {
167   AtkStateSet *set = atk_state_set_from_servant (servant);
168
169   g_return_val_if_fail (set, FALSE);
170   return atk_state_set_contains_state (set, atk_state_types[state]);
171 }
172
173
174
175 static void 
176 impl_add(PortableServer_Servant servant,
177     const Accessibility_StateType state,
178     CORBA_Environment * ev)
179 {
180   AtkStateSet *set = atk_state_set_from_servant (servant);
181
182   g_return_if_fail (set);
183   atk_state_set_add_state (set, atk_state_types[state]);
184 }
185
186
187
188 static void 
189 impl_remove (PortableServer_Servant servant,
190              const Accessibility_StateType state,
191              CORBA_Environment * ev)
192 {
193   AtkStateSet *set = atk_state_set_from_servant (servant);
194
195   g_return_if_fail (set);
196   atk_state_set_remove_state (set, atk_state_types[state]);
197 }
198
199
200
201 static CORBA_boolean
202 impl_equals (PortableServer_Servant servant,
203              const Accessibility_StateSet stateSet,
204              CORBA_Environment * ev)
205 {
206   AtkStateSet *set = atk_state_set_from_servant (servant);
207   AtkStateSet *set2, *return_set;
208   CORBA_boolean rv;
209   
210   g_return_val_if_fail (set, FALSE);
211
212   set2 = atk_state_set_from_accessibility_state_set (stateSet, ev);
213   g_return_val_if_fail (set2, FALSE);
214
215   return_set = atk_state_set_xor_sets (set, set2);
216   g_object_unref (G_OBJECT(set2));
217   if (return_set)
218     {
219       rv = atk_state_set_is_empty (return_set);
220       g_object_unref (G_OBJECT(return_set));
221     }
222   else
223     rv = FALSE;
224   return rv;
225 }
226
227
228
229 static Accessibility_StateSet
230 impl_compare (PortableServer_Servant servant,
231               const Accessibility_StateSet compareState,
232               CORBA_Environment * ev)
233 {
234   AtkStateSet *set = atk_state_set_from_servant (servant);
235   AtkStateSet *set2, *return_set;
236   SpiStateSet *spi_set;
237   
238   g_return_val_if_fail (set, FALSE);
239
240   set2 = atk_state_set_from_accessibility_state_set (compareState, ev);
241   g_return_val_if_fail (set2, CORBA_OBJECT_NIL);
242
243   return_set = atk_state_set_xor_sets (set, set2);
244   g_object_unref (G_OBJECT(set2));
245   spi_set = spi_state_set_new (return_set);
246   return bonobo_object_corba_objref (BONOBO_OBJECT(spi_set));
247 }
248
249
250
251 static CORBA_boolean
252 impl_isEmpty (PortableServer_Servant servant,
253               CORBA_Environment * ev)
254 {
255   AtkStateSet *set = atk_state_set_from_servant (servant);
256
257   g_return_val_if_fail (set, TRUE);
258   return atk_state_set_is_empty (set);
259 }
260
261
262
263 static Accessibility_StateSeq *
264 impl_getStates (PortableServer_Servant servant,
265                 CORBA_Environment * ev)
266 {
267   AtkStateSet *set = atk_state_set_from_servant (servant);
268   GSList *states = NULL;
269   GSList *tmp;
270   gint i = 0;
271   Accessibility_StateSeq *rv;
272   
273   g_return_val_if_fail (set, CORBA_OBJECT_NIL);
274
275   /* Argh-- this is bad!!! */
276
277   if (atk_state_set_contains_state (set, ATK_STATE_ACTIVE))
278     states = g_slist_append (states, (gpointer) Accessibility_STATE_ACTIVE);
279   if (atk_state_set_contains_state (set, ATK_STATE_ARMED))
280     states = g_slist_append (states, (gpointer) Accessibility_STATE_ARMED);
281   if (atk_state_set_contains_state (set, ATK_STATE_BUSY))
282     states = g_slist_append (states, (gpointer) Accessibility_STATE_BUSY);
283   if (atk_state_set_contains_state (set, ATK_STATE_CHECKED))
284     states = g_slist_append (states, (gpointer) Accessibility_STATE_CHECKED);
285   if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT))
286     states = g_slist_append (states, (gpointer) Accessibility_STATE_DEFUNCT);
287   if (atk_state_set_contains_state (set, ATK_STATE_EDITABLE))
288     states = g_slist_append (states, (gpointer) Accessibility_STATE_EDITABLE);
289   if (atk_state_set_contains_state (set, ATK_STATE_ENABLED))
290     states = g_slist_append (states, (gpointer) Accessibility_STATE_ENABLED);
291   if (atk_state_set_contains_state (set, ATK_STATE_EXPANDABLE))
292     states = g_slist_append (states, (gpointer) Accessibility_STATE_EXPANDABLE);
293   if (atk_state_set_contains_state (set, ATK_STATE_EXPANDED))
294     states = g_slist_append (states, (gpointer) Accessibility_STATE_EXPANDED);
295   if (atk_state_set_contains_state (set, ATK_STATE_FOCUSABLE))
296     states = g_slist_append (states, (gpointer) Accessibility_STATE_FOCUSABLE);
297   if (atk_state_set_contains_state (set, ATK_STATE_FOCUSED))
298     states = g_slist_append (states, (gpointer) Accessibility_STATE_FOCUSED);
299   if (atk_state_set_contains_state (set, ATK_STATE_HORIZONTAL))
300     states = g_slist_append (states, (gpointer) Accessibility_STATE_HORIZONTAL);
301   if (atk_state_set_contains_state (set, ATK_STATE_ICONIFIED))
302     states = g_slist_append (states, (gpointer) Accessibility_STATE_ICONIFIED);
303   if (atk_state_set_contains_state (set, ATK_STATE_MODAL))
304     states = g_slist_append (states, (gpointer) Accessibility_STATE_MODAL);
305   if (atk_state_set_contains_state (set, ATK_STATE_MULTI_LINE))
306     states = g_slist_append (states, (gpointer) Accessibility_STATE_MULTI_LINE);
307   if (atk_state_set_contains_state (set, ATK_STATE_MULTISELECTABLE))
308     states = g_slist_append (states, (gpointer) Accessibility_STATE_MULTISELECTABLE);
309   if (atk_state_set_contains_state (set, ATK_STATE_OPAQUE))
310     states = g_slist_append (states, (gpointer) Accessibility_STATE_OPAQUE);
311   if (atk_state_set_contains_state (set, ATK_STATE_PRESSED))
312     states = g_slist_append (states, (gpointer) Accessibility_STATE_PRESSED);
313   if (atk_state_set_contains_state (set, ATK_STATE_RESIZABLE))
314     states = g_slist_append (states, (gpointer) Accessibility_STATE_RESIZABLE);
315   if (atk_state_set_contains_state (set, ATK_STATE_SELECTABLE))
316     states = g_slist_append (states, (gpointer) Accessibility_STATE_SELECTABLE);
317   if (atk_state_set_contains_state (set, ATK_STATE_SELECTED))
318     states = g_slist_append (states, (gpointer) Accessibility_STATE_SELECTED);
319   if (atk_state_set_contains_state (set, ATK_STATE_SENSITIVE))
320     states = g_slist_append (states, (gpointer) Accessibility_STATE_SENSITIVE);
321   if (atk_state_set_contains_state (set, ATK_STATE_SHOWING))
322     states = g_slist_append (states, (gpointer) Accessibility_STATE_SHOWING);
323   if (atk_state_set_contains_state (set, ATK_STATE_SINGLE_LINE))
324     states = g_slist_append (states, (gpointer) Accessibility_STATE_SINGLE_LINE);
325   if (atk_state_set_contains_state (set, ATK_STATE_STALE))
326     states = g_slist_append (states, (gpointer) Accessibility_STATE_STALE);
327   if (atk_state_set_contains_state (set, ATK_STATE_TRANSIENT))
328     states = g_slist_append (states, (gpointer) Accessibility_STATE_TRANSIENT);
329   if (atk_state_set_contains_state (set, ATK_STATE_VERTICAL))
330     states = g_slist_append (states, (gpointer) Accessibility_STATE_VERTICAL);
331   if (atk_state_set_contains_state (set, ATK_STATE_VISIBLE))
332     states = g_slist_append (states, (gpointer) Accessibility_STATE_VISIBLE);
333
334   rv = Accessibility_StateSeq__alloc ();
335   rv->_length = rv->_maximum = g_slist_length (states);
336   rv->_buffer = Accessibility_StateSeq_allocbuf (rv->_length);
337   tmp = states;
338   while (tmp)
339     {
340       rv->_buffer[i++] = (Accessibility_StateType) tmp->data;
341       tmp = tmp->next;
342     }
343   g_slist_free (states);
344   return rv;
345 }
346
347
348
349 static void
350 spi_state_set_class_init (SpiStateSetClass *klass)
351 {
352   POA_Accessibility_StateSet__epv *epv = &klass->epv;
353
354   spi_init_state_type_tables ();
355   epv->contains = impl_contains;
356   epv->add = impl_add;
357   epv->remove = impl_remove;
358   epv->equals = impl_equals;
359   epv->compare = impl_compare;
360   epv->isEmpty = impl_isEmpty;
361   epv->getStates = impl_getStates;  
362 }
363
364
365 static void
366 spi_state_set_init (SpiStateSet *set)
367 {
368 }
369
370
371 BONOBO_TYPE_FUNC_FULL (SpiStateSet,
372                        Accessibility_StateSet,
373                        SPI_TYPE_BASE,
374                        spi_state_set);