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