2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2001 Sun Microsystems Inc.
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.
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.
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.
23 /* accessible.c: the core of the accessibility implementation */
27 #include <bonobo/bonobo-exception.h>
29 #include <libspi/libspi.h>
31 /* Our parent Gtk object type */
32 #define PARENT_TYPE SPI_TYPE_BASE
34 static Accessibility_Role
35 spi_role_from_atk_role (AtkRole role)
37 Accessibility_Role spi_role;
39 /* TODO: finish and/or make efficient! */
42 case ATK_ROLE_INVALID:
43 spi_role = Accessibility_ROLE_INVALID;
45 case ATK_ROLE_ACCEL_LABEL:
47 case ATK_ROLE_ANIMATION:
49 case ATK_ROLE_CALENDAR:
51 case ATK_ROLE_CHECK_BOX:
52 case ATK_ROLE_CHECK_MENU_ITEM:
53 case ATK_ROLE_COLOR_CHOOSER:
54 case ATK_ROLE_COLUMN_HEADER:
55 case ATK_ROLE_COMBO_BOX:
56 case ATK_ROLE_DATE_EDITOR:
57 case ATK_ROLE_DESKTOP_ICON:
58 case ATK_ROLE_DESKTOP_FRAME:
61 case ATK_ROLE_DIRECTORY_PANE:
62 case ATK_ROLE_DRAWING_AREA:
63 case ATK_ROLE_FILE_CHOOSER:
65 case ATK_ROLE_FONT_CHOOSER:
67 case ATK_ROLE_GLASS_PANE:
68 case ATK_ROLE_HTML_CONTAINER:
71 case ATK_ROLE_INTERNAL_FRAME:
73 case ATK_ROLE_LAYERED_PANE:
75 case ATK_ROLE_LIST_ITEM:
77 case ATK_ROLE_MENU_BAR:
78 case ATK_ROLE_MENU_ITEM:
79 case ATK_ROLE_OPTION_PANE:
80 case ATK_ROLE_PAGE_TAB:
81 case ATK_ROLE_PAGE_TAB_LIST:
83 case ATK_ROLE_PASSWORD_TEXT:
84 case ATK_ROLE_POPUP_MENU:
85 case ATK_ROLE_PROGRESS_BAR:
86 case ATK_ROLE_PUSH_BUTTON:
87 case ATK_ROLE_RADIO_BUTTON:
88 case ATK_ROLE_RADIO_MENU_ITEM:
89 case ATK_ROLE_ROOT_PANE:
90 case ATK_ROLE_ROW_HEADER:
91 case ATK_ROLE_SCROLL_BAR:
92 case ATK_ROLE_SCROLL_PANE:
93 case ATK_ROLE_SEPARATOR:
95 case ATK_ROLE_SPLIT_PANE:
96 case ATK_ROLE_SPIN_BUTTON:
97 case ATK_ROLE_STATUSBAR:
99 case ATK_ROLE_TABLE_CELL:
100 case ATK_ROLE_TABLE_COLUMN_HEADER:
101 case ATK_ROLE_TABLE_ROW_HEADER:
102 case ATK_ROLE_TEAR_OFF_MENU_ITEM:
103 case ATK_ROLE_TERMINAL:
105 case ATK_ROLE_TOGGLE_BUTTON:
106 case ATK_ROLE_TOOL_BAR:
107 case ATK_ROLE_TOOL_TIP:
109 case ATK_ROLE_TREE_TABLE:
110 case ATK_ROLE_UNKNOWN:
111 case ATK_ROLE_VIEWPORT:
112 case ATK_ROLE_WINDOW:
113 case ATK_ROLE_LAST_DEFINED:
115 spi_role = Accessibility_ROLE_EXTENDED;
121 get_accessible_from_servant (PortableServer_Servant servant)
123 SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
134 * CORBA Accessibility::Accessible::get_name method implementation
137 impl_accessibility_accessible_get_name (PortableServer_Servant servant,
138 CORBA_Environment *ev)
142 AtkObject *object = get_accessible_from_servant (servant);
144 g_return_val_if_fail (object != NULL, CORBA_string_dup (""));
146 name = atk_object_get_name (object);
150 retval = CORBA_string_dup (name);
154 retval = CORBA_string_dup ("");
161 * CORBA Accessibility::Accessible::set_name method implementation
164 impl_accessibility_accessible_set_name (PortableServer_Servant servant,
165 const CORBA_char *name,
166 CORBA_Environment *ev)
168 AtkObject *object = get_accessible_from_servant (servant);
170 g_return_if_fail (object != NULL);
172 atk_object_set_name (object, name);
176 * CORBA Accessibility::Accessible::get_description method implementation
179 impl_accessibility_accessible_get_description (PortableServer_Servant servant,
180 CORBA_Environment *ev)
184 AtkObject *object = get_accessible_from_servant (servant);
186 g_return_val_if_fail (object != NULL, CORBA_string_dup (""));
188 descr = atk_object_get_description (object);
192 retval = CORBA_string_dup (descr);
196 retval = CORBA_string_dup ("");
203 * CORBA Accessibility::Accessible::set_description method implementation
206 impl_accessibility_accessible_set_description (PortableServer_Servant servant,
207 const CORBA_char *descr,
208 CORBA_Environment *ev)
210 AtkObject *object = get_accessible_from_servant (servant);
212 g_return_if_fail (object != NULL);
214 atk_object_set_description (object, descr);
218 * CORBA Accessibility::Accessible::get_parent method implementation
220 static Accessibility_Accessible
221 impl_accessibility_accessible_get_parent (PortableServer_Servant servant,
222 CORBA_Environment *ev)
225 AtkObject *object = get_accessible_from_servant (servant);
227 g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL);
229 parent = atk_object_get_parent (object);
231 return spi_accessible_new_return (parent, FALSE, ev);
235 * CORBA Accessibility::Accessible::get_IndexInParent method implementation
238 impl_accessibility_accessible_get_index_in_parent (PortableServer_Servant servant,
239 CORBA_Environment *ev)
241 AtkObject *object = get_accessible_from_servant (servant);
243 g_return_val_if_fail (object != NULL, -1);
245 return atk_object_get_index_in_parent (object);
249 * CORBA Accessibility::Accessible::get_childCount method implementation
252 impl_accessibility_accessible_get_child_count (PortableServer_Servant servant,
253 CORBA_Environment *ev)
255 AtkObject *object = get_accessible_from_servant (servant);
257 g_return_val_if_fail (object != NULL, 0);
259 return atk_object_get_n_accessible_children (object);
263 * CORBA Accessibility::Accessible::getChildAtIndex method implementation
265 static Accessibility_Accessible
266 impl_accessibility_accessible_get_child_at_index (PortableServer_Servant servant,
267 const CORBA_long index,
268 CORBA_Environment *ev)
271 AtkObject *object = get_accessible_from_servant (servant);
273 g_return_val_if_fail (object != NULL, 0);
275 child = atk_object_ref_accessible_child (object, index);
277 return spi_accessible_new_return (child, TRUE, ev);
281 * CORBA Accessibility::Accessible::getState method implementation
283 static Accessibility_StateSet
284 impl_accessibility_accessible_get_state (PortableServer_Servant servant,
285 CORBA_Environment *ev)
287 AtkObject *object = get_accessible_from_servant (servant);
289 bonobo_return_val_if_fail (object != NULL, NULL, ev);
291 printf ("SpiAccessible get_state.\n");
293 /* TODO: implement the bonobo stateset class */
294 return (Accessibility_StateSet) NULL;
298 * CORBA Accessibility::Accessible::getRelationSet method implementation
300 static Accessibility_RelationSet *
301 impl_accessibility_accessible_get_relation_set (PortableServer_Servant servant,
302 CORBA_Environment *ev)
304 Accessibility_RelationSet *retval;
307 AtkRelationSet *relation_set;
308 AtkObject *object = get_accessible_from_servant (servant);
310 bonobo_return_val_if_fail (object != NULL, NULL, ev);
312 relation_set = atk_object_ref_relation_set (object);
314 n_relations = atk_relation_set_get_n_relations (relation_set);
315 retval = CORBA_sequence_Accessibility_Relation__alloc ();
316 CORBA_sequence_Accessibility_Relation_allocbuf (n_relations);
318 for (i = 0; i < n_relations; ++i)
321 bonobo_object_dup_ref (
323 spi_relation_new (atk_relation_set_get_relation (relation_set, i))),
327 printf ("SpiAccessible get_relation_set.\n");
332 * CORBA Accessibility::Accessible::getRole method implementation
334 static Accessibility_Role
335 impl_accessibility_accessible_get_role (PortableServer_Servant servant,
336 CORBA_Environment *ev)
339 Accessibility_Role retval;
340 AtkObject *object = get_accessible_from_servant (servant);
342 g_return_val_if_fail (object != NULL, 0);
344 role = atk_object_get_role (object);
345 retval = spi_role_from_atk_role (role);
351 * CORBA Accessibility::Accessible::getRole method implementation
354 impl_accessibility_accessible_get_role_name (PortableServer_Servant servant,
355 CORBA_Environment *ev)
358 Accessibility_Role retval;
359 AtkObject *object = get_accessible_from_servant (servant);
361 g_return_val_if_fail (object != NULL, 0);
363 role = atk_object_get_role (object);
365 return CORBA_string_dup (atk_role_get_name (role));
369 spi_accessible_class_init (SpiAccessibleClass *klass)
371 POA_Accessibility_Accessible__epv *epv = &klass->epv;
373 epv->_get_name = impl_accessibility_accessible_get_name;
374 epv->_set_name = impl_accessibility_accessible_set_name;
375 epv->_get_description = impl_accessibility_accessible_get_description;
376 epv->_set_description = impl_accessibility_accessible_set_description;
378 epv->_get_parent = impl_accessibility_accessible_get_parent;
379 epv->_get_childCount = impl_accessibility_accessible_get_child_count;
380 epv->getChildAtIndex = impl_accessibility_accessible_get_child_at_index;
381 epv->getIndexInParent = impl_accessibility_accessible_get_index_in_parent;
383 epv->getRelationSet = impl_accessibility_accessible_get_relation_set;
384 epv->getState = impl_accessibility_accessible_get_state;
385 epv->getRole = impl_accessibility_accessible_get_role;
386 epv->getRoleName = impl_accessibility_accessible_get_role_name;
390 spi_accessible_init (SpiAccessible *accessible)
394 BONOBO_TYPE_FUNC_FULL (SpiAccessible,
395 Accessibility_Accessible,
399 static GHashTable *public_corba_refs = NULL;
402 get_public_refs (void)
404 if (!public_corba_refs)
406 public_corba_refs = g_hash_table_new (NULL, NULL);
408 return public_corba_refs;
412 de_register_public_ref (SpiBase *object)
414 g_hash_table_remove (get_public_refs (), object->atko);
418 spi_accessible_new (AtkObject *o)
420 SpiAccessible *retval;
421 CORBA_Environment ev;
423 CORBA_exception_init (&ev);
427 if ((retval = g_hash_table_lookup (get_public_refs (), o)))
429 bonobo_object_ref (BONOBO_OBJECT (retval));
433 retval = g_object_new (SPI_ACCESSIBLE_TYPE, NULL);
435 spi_base_construct (SPI_BASE (retval), o);
437 g_hash_table_insert (get_public_refs (), o, retval);
438 g_signal_connect (G_OBJECT (retval), "destroy",
439 G_CALLBACK (de_register_public_ref),
442 /* aggregate appropriate SPI interfaces based on ATK interfaces */
444 if (ATK_IS_ACTION (o))
446 bonobo_object_add_interface (bonobo_object (retval),
447 BONOBO_OBJECT (spi_action_interface_new (o)));
450 if (ATK_IS_COMPONENT (o))
452 bonobo_object_add_interface (bonobo_object (retval),
453 BONOBO_OBJECT (spi_component_interface_new (o)));
456 if (ATK_IS_EDITABLE_TEXT (o))
458 bonobo_object_add_interface (bonobo_object (retval),
459 BONOBO_OBJECT(spi_editable_text_interface_new (o)));
462 else if (ATK_IS_HYPERTEXT (o))
464 bonobo_object_add_interface (bonobo_object (retval),
465 BONOBO_OBJECT (spi_hypertext_interface_new (o)));
468 else if (ATK_IS_TEXT (o))
470 bonobo_object_add_interface (bonobo_object (retval),
471 BONOBO_OBJECT (spi_text_interface_new (o)));
474 if (ATK_IS_IMAGE (o))
476 bonobo_object_add_interface (bonobo_object (retval),
477 BONOBO_OBJECT (spi_image_interface_new (o)));
480 if (ATK_IS_SELECTION (o))
482 bonobo_object_add_interface (bonobo_object (retval),
483 BONOBO_OBJECT (spi_selection_interface_new (o)));
486 if (ATK_IS_TABLE (o))
488 bonobo_object_add_interface (bonobo_object (retval),
489 BONOBO_OBJECT (spi_table_interface_new (o)));
492 if (ATK_IS_VALUE (o))
494 bonobo_object_add_interface (bonobo_object (retval),
495 BONOBO_OBJECT (spi_value_interface_new (o)));
502 * spi_accessible_new_return:
503 * @o: an AtkObject or NULL
504 * @release_ref: whether to unref this AtkObject before return
505 * @ev: a CORBA environment
507 * A helper function to instantiate a CORBA accessiblility
508 * proxy from an AtkObject.
510 * Return value: the proxy or CORBA_OBJECT_NIL
512 Accessibility_Accessible
513 spi_accessible_new_return (AtkObject *o,
514 gboolean release_ref,
515 CORBA_Environment *ev)
517 SpiAccessible *accessible;
521 return CORBA_OBJECT_NIL;
524 accessible = spi_accessible_new (o);
528 g_object_unref (G_OBJECT (o));
531 return CORBA_Object_duplicate (BONOBO_OBJREF (accessible), ev);