Removed po directory from Makefile.am for now.
[platform/core/uifw/at-spi2-atk.git] / libspi / accessible.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 /* accessible.c: the core of the accessibility implementation */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <bonobo/bonobo-exception.h>
28 #include <atk/atk.h>
29 #include <libspi/libspi.h>
30
31 /* Our parent Gtk object type  */
32 #define PARENT_TYPE SPI_TYPE_BASE
33
34 static AtkObject *
35 get_accessible_from_servant (PortableServer_Servant servant)
36 {
37   SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
38
39   if (!object)
40     {
41       return NULL;
42     }
43
44   return object->atko;
45 }
46
47 /*
48  * CORBA Accessibility::Accessible::get_name method implementation
49  */
50 static CORBA_char *
51 impl_accessibility_accessible_get_name (PortableServer_Servant servant,
52                                         CORBA_Environment     *ev)
53 {
54   const gchar *name;
55   CORBA_char  *retval;
56   AtkObject   *object = get_accessible_from_servant (servant);
57
58   g_return_val_if_fail (object != NULL, CORBA_string_dup (""));
59
60   name = atk_object_get_name (object);
61
62   if (name)
63     {
64       retval = CORBA_string_dup (name);
65     }
66   else
67     {
68       retval = CORBA_string_dup ("");
69     }
70
71   return retval;
72 }
73
74 /*
75  * CORBA Accessibility::Accessible::set_name method implementation
76  */
77 static void
78 impl_accessibility_accessible_set_name (PortableServer_Servant servant,
79                                         const CORBA_char      *name,
80                                         CORBA_Environment     *ev)
81 {
82   AtkObject *object = get_accessible_from_servant (servant);
83
84   g_return_if_fail (object != NULL);
85
86   atk_object_set_name (object, name);
87 }
88
89 /*
90  * CORBA Accessibility::Accessible::get_description method implementation
91  */
92 static CORBA_char *
93 impl_accessibility_accessible_get_description (PortableServer_Servant servant,
94                                                CORBA_Environment     *ev)
95 {
96   const gchar *descr;
97   CORBA_char  *retval;
98   AtkObject   *object = get_accessible_from_servant (servant);
99
100   g_return_val_if_fail (object != NULL, CORBA_string_dup (""));
101
102   descr = atk_object_get_description (object);
103
104   if (descr)
105     {
106       retval = CORBA_string_dup (descr);
107     }
108   else
109     {
110       retval = CORBA_string_dup ("");
111     }
112
113   return retval;
114 }
115
116 /*
117  * CORBA Accessibility::Accessible::set_description method implementation
118  */
119 static void
120 impl_accessibility_accessible_set_description (PortableServer_Servant servant,
121                                                const CORBA_char      *descr,
122                                                CORBA_Environment     *ev)
123 {
124   AtkObject *object = get_accessible_from_servant (servant);
125
126   g_return_if_fail (object != NULL);
127
128   atk_object_set_description (object, descr);
129 }
130
131 /*
132  * CORBA Accessibility::Accessible::get_parent method implementation
133  */
134 static Accessibility_Accessible
135 impl_accessibility_accessible_get_parent (PortableServer_Servant servant,
136                                           CORBA_Environment     *ev)
137 {
138   AtkObject *parent;
139   AtkObject *object = get_accessible_from_servant (servant);
140
141   g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL);
142
143   parent = atk_object_get_parent (object);
144
145   return spi_accessible_new_return (parent, FALSE, ev);
146 }
147
148 /*
149  * CORBA Accessibility::Accessible::get_IndexInParent method implementation
150  */
151 static CORBA_long
152 impl_accessibility_accessible_get_index_in_parent (PortableServer_Servant servant,
153                                                    CORBA_Environment     *ev)
154 {
155   AtkObject *object = get_accessible_from_servant (servant);
156
157   g_return_val_if_fail (object != NULL, -1);
158
159   return atk_object_get_index_in_parent (object);
160 }
161
162 /*
163  * CORBA Accessibility::Accessible::get_childCount method implementation
164  */
165 static CORBA_long
166 impl_accessibility_accessible_get_child_count (PortableServer_Servant servant,
167                                                CORBA_Environment     *ev)
168 {
169   AtkObject *object = get_accessible_from_servant (servant);
170
171   g_return_val_if_fail (object != NULL, 0);
172
173   return atk_object_get_n_accessible_children (object);
174 }
175
176 /*
177  * CORBA Accessibility::Accessible::getChildAtIndex method implementation
178  */
179 static Accessibility_Accessible
180 impl_accessibility_accessible_get_child_at_index (PortableServer_Servant servant,
181                                                   const CORBA_long      index,
182                                                   CORBA_Environment     *ev)
183 {
184   AtkObject *child;
185   AtkObject *object = get_accessible_from_servant (servant);
186
187   g_return_val_if_fail (object != NULL, 0);
188
189   child = atk_object_ref_accessible_child (object, index);
190
191   return spi_accessible_new_return (child, TRUE, ev);
192 }
193
194 /*
195  * CORBA Accessibility::Accessible::getState method implementation
196  */
197 static Accessibility_StateSet
198 impl_accessibility_accessible_get_state (PortableServer_Servant servant,
199                                          CORBA_Environment     *ev)
200 {
201   AtkObject *object = get_accessible_from_servant (servant);
202
203   bonobo_return_val_if_fail (object != NULL, NULL, ev);
204
205   printf ("SpiAccessible get_state.\n");
206
207   /* TODO: implement the bonobo stateset class */
208   return (Accessibility_StateSet) NULL;
209 }
210
211 /*
212  * CORBA Accessibility::Accessible::getRelationSet method implementation
213  */
214 static Accessibility_RelationSet *
215 impl_accessibility_accessible_get_relation_set (PortableServer_Servant servant,
216                                                 CORBA_Environment     *ev)
217 {
218   Accessibility_RelationSet *retval;
219   gint n_relations;
220   gint i;
221   AtkRelationSet *relation_set;
222   AtkObject      *object = get_accessible_from_servant (servant);
223
224   bonobo_return_val_if_fail (object != NULL, NULL, ev);
225
226   relation_set = atk_object_ref_relation_set (object);
227
228   n_relations = atk_relation_set_get_n_relations (relation_set);
229   retval = CORBA_sequence_Accessibility_Relation__alloc ();
230   CORBA_sequence_Accessibility_Relation_allocbuf (n_relations);
231           
232   for (i = 0; i < n_relations; ++i)
233     {
234       retval->_buffer[i] =
235         bonobo_object_dup_ref (
236           BONOBO_OBJREF (
237             spi_relation_new (atk_relation_set_get_relation (relation_set, i))),
238           ev);
239     }
240   
241   printf ("SpiAccessible get_relation_set.\n");
242   return retval;
243 }
244
245 /*
246  * CORBA Accessibility::Accessible::getRole method implementation
247  */
248 static Accessibility_Role
249 impl_accessibility_accessible_get_role (PortableServer_Servant servant,
250                                         CORBA_Environment     *ev)
251 {
252   AtkRole            role;
253   Accessibility_Role retval;
254   AtkObject         *object = get_accessible_from_servant (servant);
255
256   g_return_val_if_fail (object != NULL, 0);
257
258   role = atk_object_get_role (object);
259   retval = role; /* FIXME: relies on ability to cast these back and forth */
260
261   return retval;
262 }
263
264 static void
265 spi_accessible_class_init (SpiAccessibleClass *klass)
266 {
267         POA_Accessibility_Accessible__epv *epv = &klass->epv;
268
269         epv->_get_name = impl_accessibility_accessible_get_name;
270         epv->_set_name = impl_accessibility_accessible_set_name;
271         epv->_get_description = impl_accessibility_accessible_get_description;
272         epv->_set_description = impl_accessibility_accessible_set_description;
273
274         epv->_get_parent = impl_accessibility_accessible_get_parent;
275         epv->_get_childCount = impl_accessibility_accessible_get_child_count;
276         epv->getChildAtIndex = impl_accessibility_accessible_get_child_at_index;
277         epv->getIndexInParent = impl_accessibility_accessible_get_index_in_parent;
278
279         epv->getRelationSet = impl_accessibility_accessible_get_relation_set;
280         epv->getState = impl_accessibility_accessible_get_state;
281         epv->getRole = impl_accessibility_accessible_get_role;
282 }
283
284 static void
285 spi_accessible_init (SpiAccessible *accessible)
286 {
287 }
288
289 BONOBO_TYPE_FUNC_FULL (SpiAccessible,
290                        Accessibility_Accessible,
291                        PARENT_TYPE,
292                        spi_accessible);
293
294 static GHashTable *public_corba_refs = NULL;
295
296 static GHashTable *
297 get_public_refs (void)
298 {
299   if (!public_corba_refs)
300     {
301       public_corba_refs = g_hash_table_new (NULL, NULL);
302     }
303   return public_corba_refs;
304 }
305
306 static void
307 de_register_public_ref (SpiBase *object)
308 {
309   g_hash_table_remove (get_public_refs (), object->atko);
310 }
311
312 SpiAccessible *
313 spi_accessible_new (AtkObject *o)
314 {
315     SpiAccessible *retval;
316     CORBA_Environment ev;
317
318     CORBA_exception_init (&ev);
319
320     g_assert (o);
321
322     if ((retval = g_hash_table_lookup (get_public_refs (), o)))
323       {
324         bonobo_object_ref (BONOBO_OBJECT (retval));
325         return retval;
326       }
327
328     retval = g_object_new (SPI_ACCESSIBLE_TYPE, NULL);
329
330     spi_base_construct (SPI_BASE (retval), o);
331
332     g_hash_table_insert (get_public_refs (), o, retval);
333     g_signal_connect (G_OBJECT (retval), "destroy",
334                       G_CALLBACK (de_register_public_ref),
335                       NULL);
336
337     /* aggregate appropriate SPI interfaces based on ATK interfaces */
338
339     if (ATK_IS_ACTION (o))
340       {
341         bonobo_object_add_interface (bonobo_object (retval),
342                                      BONOBO_OBJECT (spi_action_interface_new (o)));
343       }
344
345     if (ATK_IS_COMPONENT (o))
346       {
347         bonobo_object_add_interface (bonobo_object (retval),
348                                      BONOBO_OBJECT (spi_component_interface_new (o)));
349       }
350
351     if (ATK_IS_EDITABLE_TEXT (o))
352       {
353         bonobo_object_add_interface (bonobo_object (retval),
354                                      BONOBO_OBJECT(spi_editable_text_interface_new (o)));
355       }
356
357     else if (ATK_IS_HYPERTEXT (o))
358       {
359         bonobo_object_add_interface (bonobo_object (retval),
360                                      BONOBO_OBJECT (spi_hypertext_interface_new (o)));
361       }
362
363     else if (ATK_IS_TEXT (o))
364       {
365         bonobo_object_add_interface (bonobo_object (retval),
366                                      BONOBO_OBJECT (spi_text_interface_new (o)));
367       }
368
369     if (ATK_IS_IMAGE (o))
370       {
371         bonobo_object_add_interface (bonobo_object (retval),
372                                      BONOBO_OBJECT (spi_image_interface_new (o)));
373       }
374
375     if (ATK_IS_SELECTION (o))
376       {
377         bonobo_object_add_interface (bonobo_object (retval),
378                                      BONOBO_OBJECT (spi_selection_interface_new (o)));
379       }
380
381     if (ATK_IS_TABLE (o))
382       {
383         bonobo_object_add_interface (bonobo_object (retval),
384                                      BONOBO_OBJECT (spi_table_interface_new (o)));
385       }
386
387     if (ATK_IS_VALUE (o))
388       {
389         bonobo_object_add_interface (bonobo_object (retval),
390                                      BONOBO_OBJECT (spi_value_interface_new (o)));
391       }
392
393     return retval;
394 }
395
396 /**
397  * spi_accessible_new_return:
398  * @o: an AtkObject or NULL
399  * @release_ref: whether to unref this AtkObject before return
400  * @ev: a CORBA environment
401  * 
402  * A helper function to instantiate a CORBA accessiblility
403  * proxy from an AtkObject.
404  * 
405  * Return value: the proxy or CORBA_OBJECT_NIL
406  **/
407 Accessibility_Accessible
408 spi_accessible_new_return (AtkObject         *o,
409                            gboolean           release_ref,
410                            CORBA_Environment *ev)
411 {
412   SpiAccessible *accessible;
413
414   if (!o)
415     {
416       return CORBA_OBJECT_NIL;
417     }
418
419   accessible = spi_accessible_new (o);
420
421   if (release_ref)
422     {
423       g_object_unref (G_OBJECT (o));
424     }
425
426   return CORBA_Object_duplicate (BONOBO_OBJREF (accessible), ev);
427 }