2002-11-19 Darren Kenny <darren.kenny@sun.com>
[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, 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
118   return TRUE;
119 }
120
121
122
123 static AtkStateSet *
124 atk_state_set_from_servant (PortableServer_Servant servant)
125 {
126   SpiBase *base = SPI_BASE (bonobo_object_from_servant(servant));
127
128   g_return_val_if_fail (base, NULL);
129   return  ATK_STATE_SET(base->gobj);
130 }
131
132
133
134 static AtkStateSet *
135 atk_state_set_from_accessibility_state_set (Accessibility_StateSet set, CORBA_Environment *ev)
136 {
137   AtkStateType *states, *tmp;
138   AtkStateSet *rv;
139   gint i;
140   Accessibility_StateSeq *seq;
141   
142   seq = Accessibility_StateSet_getStates (set, ev);
143   states = tmp = g_new (AtkStateType, seq->_length);
144   for (i = 0; i < seq->_length; i++)
145     *tmp++ = atk_state_types[seq->_buffer[i]];
146   rv = atk_state_set_new ();
147   atk_state_set_add_states (rv, states, seq->_length);
148   CORBA_free (seq);
149   g_free (states);
150   return rv;
151 }
152
153
154
155 SpiStateSet *
156 spi_state_set_new (AtkStateSet *obj)
157 {
158   SpiStateSet *new_set = g_object_new (SPI_STATE_SET_TYPE, NULL);
159   spi_base_construct (SPI_BASE (new_set), G_OBJECT (obj));
160   return new_set;
161 }
162
163
164
165 static CORBA_boolean
166 impl_contains (PortableServer_Servant servant,
167                const Accessibility_StateType state,
168                CORBA_Environment * ev)
169 {
170   AtkStateSet *set = atk_state_set_from_servant (servant);
171
172   g_return_val_if_fail (set, FALSE);
173   return atk_state_set_contains_state (set, atk_state_types[state]);
174 }
175
176
177
178 static void 
179 impl_add(PortableServer_Servant servant,
180     const Accessibility_StateType state,
181     CORBA_Environment * ev)
182 {
183   AtkStateSet *set = atk_state_set_from_servant (servant);
184
185   g_return_if_fail (set);
186   atk_state_set_add_state (set, atk_state_types[state]);
187 }
188
189
190
191 static void 
192 impl_remove (PortableServer_Servant servant,
193              const Accessibility_StateType state,
194              CORBA_Environment * ev)
195 {
196   AtkStateSet *set = atk_state_set_from_servant (servant);
197
198   g_return_if_fail (set);
199   atk_state_set_remove_state (set, atk_state_types[state]);
200 }
201
202
203
204 static CORBA_boolean
205 impl_equals (PortableServer_Servant servant,
206              const Accessibility_StateSet stateSet,
207              CORBA_Environment * ev)
208 {
209   AtkStateSet *set = atk_state_set_from_servant (servant);
210   AtkStateSet *set2, *return_set;
211   CORBA_boolean rv;
212   
213   g_return_val_if_fail (set, FALSE);
214
215   set2 = atk_state_set_from_accessibility_state_set (stateSet, ev);
216   g_return_val_if_fail (set2, FALSE);
217
218   return_set = atk_state_set_xor_sets (set, set2);
219   g_object_unref (G_OBJECT(set2));
220   if (return_set)
221     {
222       rv = atk_state_set_is_empty (return_set);
223       g_object_unref (G_OBJECT(return_set));
224     }
225   else
226     rv = FALSE;
227   return rv;
228 }
229
230
231
232 static Accessibility_StateSet
233 impl_compare (PortableServer_Servant servant,
234               const Accessibility_StateSet compareState,
235               CORBA_Environment * ev)
236 {
237   AtkStateSet *set = atk_state_set_from_servant (servant);
238   AtkStateSet *set2, *return_set;
239   SpiStateSet *spi_set;
240   
241   g_return_val_if_fail (set, FALSE);
242
243   set2 = atk_state_set_from_accessibility_state_set (compareState, ev);
244   g_return_val_if_fail (set2, CORBA_OBJECT_NIL);
245
246   return_set = atk_state_set_xor_sets (set, set2);
247   g_object_unref (G_OBJECT(set2));
248   spi_set = spi_state_set_new (return_set);
249   return bonobo_object_corba_objref (BONOBO_OBJECT(spi_set));
250 }
251
252
253
254 static CORBA_boolean
255 impl_isEmpty (PortableServer_Servant servant,
256               CORBA_Environment * ev)
257 {
258   AtkStateSet *set = atk_state_set_from_servant (servant);
259
260   g_return_val_if_fail (set, TRUE);
261   return atk_state_set_is_empty (set);
262 }
263
264
265
266 static Accessibility_StateSeq *
267 impl_getStates (PortableServer_Servant servant,
268                 CORBA_Environment * ev)
269 {
270   AtkStateSet *set = atk_state_set_from_servant (servant);
271   GSList *states = NULL;
272   GSList *tmp;
273   gint i = 0;
274   Accessibility_StateSeq *rv;
275   
276   g_return_val_if_fail (set, CORBA_OBJECT_NIL);
277
278   /* Argh-- this is bad!!! */
279
280   if (atk_state_set_contains_state (set, ATK_STATE_ACTIVE))
281     states = g_slist_append (states, (gpointer) Accessibility_STATE_ACTIVE);
282   if (atk_state_set_contains_state (set, ATK_STATE_ARMED))
283     states = g_slist_append (states, (gpointer) Accessibility_STATE_ARMED);
284   if (atk_state_set_contains_state (set, ATK_STATE_BUSY))
285     states = g_slist_append (states, (gpointer) Accessibility_STATE_BUSY);
286   if (atk_state_set_contains_state (set, ATK_STATE_CHECKED))
287     states = g_slist_append (states, (gpointer) Accessibility_STATE_CHECKED);
288   if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT))
289     states = g_slist_append (states, (gpointer) Accessibility_STATE_DEFUNCT);
290   if (atk_state_set_contains_state (set, ATK_STATE_EDITABLE))
291     states = g_slist_append (states, (gpointer) Accessibility_STATE_EDITABLE);
292   if (atk_state_set_contains_state (set, ATK_STATE_ENABLED))
293     states = g_slist_append (states, (gpointer) Accessibility_STATE_ENABLED);
294   if (atk_state_set_contains_state (set, ATK_STATE_EXPANDABLE))
295     states = g_slist_append (states, (gpointer) Accessibility_STATE_EXPANDABLE);
296   if (atk_state_set_contains_state (set, ATK_STATE_EXPANDED))
297     states = g_slist_append (states, (gpointer) Accessibility_STATE_EXPANDED);
298   if (atk_state_set_contains_state (set, ATK_STATE_FOCUSABLE))
299     states = g_slist_append (states, (gpointer) Accessibility_STATE_FOCUSABLE);
300   if (atk_state_set_contains_state (set, ATK_STATE_FOCUSED))
301     states = g_slist_append (states, (gpointer) Accessibility_STATE_FOCUSED);
302   if (atk_state_set_contains_state (set, ATK_STATE_HORIZONTAL))
303     states = g_slist_append (states, (gpointer) Accessibility_STATE_HORIZONTAL);
304   if (atk_state_set_contains_state (set, ATK_STATE_ICONIFIED))
305     states = g_slist_append (states, (gpointer) Accessibility_STATE_ICONIFIED);
306   if (atk_state_set_contains_state (set, ATK_STATE_MODAL))
307     states = g_slist_append (states, (gpointer) Accessibility_STATE_MODAL);
308   if (atk_state_set_contains_state (set, ATK_STATE_MULTI_LINE))
309     states = g_slist_append (states, (gpointer) Accessibility_STATE_MULTI_LINE);
310   if (atk_state_set_contains_state (set, ATK_STATE_MULTISELECTABLE))
311     states = g_slist_append (states, (gpointer) Accessibility_STATE_MULTISELECTABLE);
312   if (atk_state_set_contains_state (set, ATK_STATE_OPAQUE))
313     states = g_slist_append (states, (gpointer) Accessibility_STATE_OPAQUE);
314   if (atk_state_set_contains_state (set, ATK_STATE_PRESSED))
315     states = g_slist_append (states, (gpointer) Accessibility_STATE_PRESSED);
316   if (atk_state_set_contains_state (set, ATK_STATE_RESIZABLE))
317     states = g_slist_append (states, (gpointer) Accessibility_STATE_RESIZABLE);
318   if (atk_state_set_contains_state (set, ATK_STATE_SELECTABLE))
319     states = g_slist_append (states, (gpointer) Accessibility_STATE_SELECTABLE);
320   if (atk_state_set_contains_state (set, ATK_STATE_SELECTED))
321     states = g_slist_append (states, (gpointer) Accessibility_STATE_SELECTED);
322   if (atk_state_set_contains_state (set, ATK_STATE_SENSITIVE))
323     states = g_slist_append (states, (gpointer) Accessibility_STATE_SENSITIVE);
324   if (atk_state_set_contains_state (set, ATK_STATE_SHOWING))
325     states = g_slist_append (states, (gpointer) Accessibility_STATE_SHOWING);
326   if (atk_state_set_contains_state (set, ATK_STATE_SINGLE_LINE))
327     states = g_slist_append (states, (gpointer) Accessibility_STATE_SINGLE_LINE);
328   if (atk_state_set_contains_state (set, ATK_STATE_STALE))
329     states = g_slist_append (states, (gpointer) Accessibility_STATE_STALE);
330   if (atk_state_set_contains_state (set, ATK_STATE_TRANSIENT))
331     states = g_slist_append (states, (gpointer) Accessibility_STATE_TRANSIENT);
332   if (atk_state_set_contains_state (set, ATK_STATE_VERTICAL))
333     states = g_slist_append (states, (gpointer) Accessibility_STATE_VERTICAL);
334   if (atk_state_set_contains_state (set, ATK_STATE_VISIBLE))
335     states = g_slist_append (states, (gpointer) Accessibility_STATE_VISIBLE);
336   if (atk_state_set_contains_state (set, ATK_STATE_MANAGES_DESCENDANTS))
337     states = g_slist_append (states, (gpointer) Accessibility_STATE_MANAGES_DESCENDANTS);
338
339   rv = Accessibility_StateSeq__alloc ();
340   rv->_length = rv->_maximum = g_slist_length (states);
341   rv->_buffer = Accessibility_StateSeq_allocbuf (rv->_length);
342   tmp = states;
343   while (tmp)
344     {
345       rv->_buffer[i++] = (Accessibility_StateType) tmp->data;
346       tmp = tmp->next;
347     }
348   g_slist_free (states);
349   return rv;
350 }
351
352
353
354 static void
355 spi_state_set_class_init (SpiStateSetClass *klass)
356 {
357   POA_Accessibility_StateSet__epv *epv = &klass->epv;
358
359   spi_init_state_type_tables ();
360   epv->contains = impl_contains;
361   epv->add = impl_add;
362   epv->remove = impl_remove;
363   epv->equals = impl_equals;
364   epv->compare = impl_compare;
365   epv->isEmpty = impl_isEmpty;
366   epv->getStates = impl_getStates;  
367 }
368
369
370 static void
371 spi_state_set_init (SpiStateSet *set)
372 {
373 }
374
375
376 BONOBO_TYPE_FUNC_FULL (SpiStateSet,
377                        Accessibility_StateSet,
378                        SPI_TYPE_BASE,
379                        spi_state_set);