1 /* ATK - Accessibility Toolkit
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include <glib-object.h>
24 #define NUM_POSSIBLE_STATES (sizeof(AtkStateMask)*8)
26 /* New GObject properties registered by AtkObject */
29 PROP_0, /* gobject convention */
33 PROP_PARENT, /* ancestry has changed */
34 PROP_CHILD, /* children have changed in number or identity */
35 PROP_ROLE, /* AtkRole has changed */
36 PROP_STATE, /* AtkState has changed */
37 PROP_TEXT, /* Used only by AtkText implementors */
38 PROP_CARET, /* Used only by AtkText implementors */
39 PROP_LAST /* gobject convention */
47 struct _AtkRelationSet
55 AtkRelationType relationship;
62 } _AtkIfaceImplementor;
64 static void atk_object_class_init (AtkObjectClass *klass);
65 static void atk_object_init (AtkObject *accessible,
66 AtkObjectClass *klass);
67 static AtkRelationSet* atk_object_real_get_relation_set (AtkObject *accessible);
69 static void atk_object_real_set_property(GObject *object,
73 static void atk_object_real_get_property(GObject *object,
77 static void atk_object_finalize (GObject *object);
79 static gchar* state_names[NUM_POSSIBLE_STATES];
82 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
85 static gpointer parent_class = NULL;
87 static const gchar* atk_object_name_property_name = "accessible-name";
88 static const gchar* atk_object_name_property_state = "accessible-state";
89 static const gchar* atk_object_name_property_description = "accessible-description";
92 atk_object_get_type (void)
94 static GType type = 0;
98 static const GTypeInfo typeInfo =
100 sizeof (AtkObjectClass),
101 (GBaseInitFunc) NULL,
102 (GBaseFinalizeFunc) NULL,
103 (GClassInitFunc) atk_object_class_init,
104 (GClassFinalizeFunc) NULL,
108 (GInstanceInitFunc) atk_object_init,
110 type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
116 atk_object_class_init (AtkObjectClass *klass)
118 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
120 parent_class = g_type_class_ref (G_TYPE_OBJECT);
122 gobject_class->set_property = atk_object_real_set_property;
123 gobject_class->get_property = atk_object_real_get_property;
124 gobject_class->finalize = atk_object_finalize;
126 klass->get_relation_set = atk_object_real_get_relation_set;
128 state_names[ATK_STATE_ARMED] = "armed";
129 state_names[ATK_STATE_BUSY] = "busy";
130 state_names[ATK_STATE_CHECKED] = "checked";
131 state_names[ATK_STATE_COLLAPSED] = "collapsed";
132 state_names[ATK_STATE_EDITABLE] = "editable";
133 state_names[ATK_STATE_EXPANDABLE] = "expandable";
134 state_names[ATK_STATE_EXPANDED] = "expanded";
135 state_names[ATK_STATE_FOCUSABLE] = "focusable";
136 state_names[ATK_STATE_FOCUSED] = "focused";
137 state_names[ATK_STATE_HORIZONTAL] = "horizontal";
138 state_names[ATK_STATE_ICONIFIED] = "iconified";
139 state_names[ATK_STATE_MODAL] = "modal";
140 state_names[ATK_STATE_MULTI_LINE] = "multi-line";
141 state_names[ATK_STATE_MULTISELECTABLE] = "multiselectable";
142 state_names[ATK_STATE_OPAQUE] = "opaque";
143 state_names[ATK_STATE_PRESSED] = "pressed";
144 state_names[ATK_STATE_RESIZABLE] = "resizeable";
145 state_names[ATK_STATE_SELECTABLE] = "selectable";
146 state_names[ATK_STATE_SELECTED] = "selected";
147 state_names[ATK_STATE_SENSITIVE] = "sensitive";
148 state_names[ATK_STATE_SHOWING] = "showing";
149 state_names[ATK_STATE_SINGLE_LINE] = "single-line";
150 state_names[ATK_STATE_TRANSIENT] = "transient";
151 state_names[ATK_STATE_VERTICAL] = "vertical";
152 state_names[ATK_STATE_VISIBLE] = "visible";
154 klass->children_changed = NULL;
156 g_object_class_install_property (gobject_class,
158 g_param_spec_string (atk_object_name_property_name,
160 "Object instance\'s name formatted for "
161 "assistive technology access",
164 g_object_class_install_property (gobject_class,
166 g_param_spec_string (atk_object_name_property_description,
167 "Accessible Description",
168 "Description of an object, formatted for "
169 "assistive technology access",
172 g_object_class_install_property (gobject_class,
174 g_param_spec_int (atk_object_name_property_state,
176 "The current state of this object "
177 "or its UI component",
183 /* register some properties - these could be change signals instead */
184 g_object_class_install_property (gobject_class,
186 g_param_spec_ccallback ("accessible_parent", "Accessible Parent",
187 "First accessible ancestor (container or object) "
188 "which this object is a descendant of",
192 g_object_class_install_property (gobject_class,
194 g_param_spec_ccallback ("accessible_role", "Accessible Role",
195 "The user-interface role of this object",
197 g_object_class_install_property (gobject_class,
199 g_param_spec_ccallback ("accessible_state", "Accessible State",
200 "The current state of this object "
201 "or its UI component",
203 g_object_class_install_property (gobject_class,
205 g_param_spec_ccallback ("accessible_text", "Accessible Text",
206 "This object\'s accessible text contents",
208 g_object_class_install_property (gobject_class,
210 g_param_spec_ccallback ("accessible_caret", "Accessible Text Caret",
211 "The current text caret state and position "
212 "for this component",
214 gaccessible_signals[CHILDREN_CHANGED] =
215 g_signal_newc ("accessible_children_changed",
216 G_TYPE_FROM_CLASS (klass),
218 G_STRUCT_OFFSET (AtkObjectClass, children_changed), /* still need to declare and define this func */
220 g_cclosure_marshal_VOID__UINT_POINTER,
222 2, G_TYPE_UINT, ATK_TYPE_OBJECT);
227 atk_object_init (AtkObject *accessible,
228 AtkObjectClass *klass)
230 accessible->relation_set = g_malloc (sizeof (AtkRelationSet));
231 g_return_if_fail (accessible->relation_set != NULL);
232 accessible->relation_set->relations = NULL;
236 atk_object_iface_get_type (void)
238 static GType type = 0;
242 static const GTypeInfo typeInfo =
244 sizeof (AtkObjectIface),
245 (GBaseInitFunc) NULL,
246 (GBaseFinalizeFunc) NULL,
249 type = g_type_register_static (G_TYPE_INTERFACE, "AtkObjectIface", &typeInfo, 0) ;
255 G_CONST_RETURN gchar*
256 atk_object_get_name (AtkObject *accessible)
258 AtkObjectClass *klass;
260 g_return_val_if_fail ((accessible != NULL), NULL);
261 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
263 klass = ATK_OBJECT_GET_CLASS (accessible);
265 return (klass->get_name) (accessible);
270 G_CONST_RETURN gchar*
271 atk_object_get_description (AtkObject *accessible)
273 AtkObjectClass *klass;
275 g_return_val_if_fail ((accessible != NULL), NULL);
276 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
278 klass = ATK_OBJECT_GET_CLASS (accessible);
279 if (klass->get_description)
280 return (klass->get_description) (accessible);
286 atk_object_get_parent (AtkObject *accessible)
288 AtkObjectClass *klass;
290 g_return_val_if_fail ((accessible != NULL), NULL);
291 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
293 klass = ATK_OBJECT_GET_CLASS (accessible);
294 if (klass->get_parent)
295 return (klass->get_parent) (accessible);
301 atk_object_get_n_accessible_children (AtkObject *accessible)
303 AtkObjectClass *klass;
305 g_return_val_if_fail ((accessible != NULL), 0);
306 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
308 klass = ATK_OBJECT_GET_CLASS (accessible);
309 if (klass->get_n_children)
310 return (klass->get_n_children) (accessible);
316 atk_object_ref_accessible_child (AtkObject *accessible,
319 AtkObjectClass *klass;
321 g_return_val_if_fail ((accessible != NULL), NULL);
322 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
324 klass = ATK_OBJECT_GET_CLASS (accessible);
325 if (klass->ref_child)
326 return (klass->ref_child) (accessible, i);
332 atk_object_get_relation_set (AtkObject *accessible)
334 AtkObjectClass *klass;
336 g_return_val_if_fail ((accessible != NULL), NULL);
337 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
339 klass = ATK_OBJECT_GET_CLASS (accessible);
340 if (klass->get_relation_set)
341 return (klass->get_relation_set) (accessible);
347 atk_role_register (gchar *name)
349 /* TODO: associate name with new type */
350 static guint type = ATK_ROLE_LAST_DEFINED;
355 atk_object_get_role (AtkObject *accessible) {
356 AtkObjectClass *klass;
358 g_return_val_if_fail ((accessible != NULL), ATK_ROLE_UNKNOWN);
359 g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
361 klass = ATK_OBJECT_GET_CLASS (accessible);
363 return (klass->get_role) (accessible);
365 return ATK_ROLE_UNKNOWN;
369 atk_state_type_register (gchar *name)
371 /* TODO: associate name with new type */
372 static guint type = ATK_STATE_LAST_DEFINED;
373 if (type < NUM_POSSIBLE_STATES) {
376 return ATK_STATE_INVALID; /* caller needs to check */
380 atk_object_get_state (AtkObject *accessible) {
381 AtkObjectClass *klass;
383 g_return_val_if_fail ((accessible != NULL), 0);
384 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
386 klass = ATK_OBJECT_GET_CLASS (accessible);
387 if (klass->get_state)
388 return (klass->get_state) (accessible);
394 atk_object_get_index_in_parent (AtkObject *accessible)
396 AtkObjectClass *klass;
398 g_return_val_if_fail ((accessible != NULL), -1);
399 g_return_val_if_fail (ATK_OBJECT (accessible), -1);
401 klass = ATK_OBJECT_GET_CLASS (accessible);
402 if (klass->get_index_in_parent)
403 return (klass->get_index_in_parent) (accessible);
409 atk_object_set_name (AtkObject *accessible,
412 AtkObjectClass *klass;
414 g_return_if_fail ((accessible != NULL));
415 g_return_if_fail (ATK_IS_OBJECT (accessible));
416 g_return_if_fail ((name != NULL));
418 klass = ATK_OBJECT_GET_CLASS (accessible);
421 (klass->set_name) (accessible, name);
422 g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
427 atk_object_set_description (AtkObject *accessible,
428 const gchar *description)
430 AtkObjectClass *klass;
432 g_return_if_fail ((accessible != NULL));
433 g_return_if_fail (ATK_IS_OBJECT (accessible));
434 g_return_if_fail ((description != NULL));
436 klass = ATK_OBJECT_GET_CLASS (accessible);
437 if (klass->set_description)
439 (klass->set_description) (accessible, description);
440 g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
445 atk_object_set_parent (AtkObject *accessible,
448 AtkObjectClass *klass;
450 g_return_if_fail ((accessible != NULL));
451 g_return_if_fail (ATK_IS_OBJECT (accessible));
453 klass = ATK_OBJECT_GET_CLASS (accessible);
454 if (klass->set_parent)
455 (klass->set_parent) (accessible, parent);
459 atk_object_set_role (AtkObject *accessible,
462 AtkObjectClass *klass;
464 g_return_if_fail ((accessible != NULL));
465 g_return_if_fail (ATK_IS_OBJECT (accessible));
467 klass = ATK_OBJECT_GET_CLASS (accessible);
469 (klass->set_role) (accessible, role);
473 atk_object_connect_property_change_handler (AtkObject *accessible,
474 AtkPropertyChangeHandler *handler)
476 AtkObjectClass *klass;
478 g_return_val_if_fail ((accessible != NULL), 0);
479 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
480 g_return_val_if_fail ((handler != NULL), 0);
482 klass = ATK_OBJECT_GET_CLASS (accessible);
483 if (klass->connect_property_change_handler)
484 return (klass->connect_property_change_handler) (accessible, handler);
490 atk_object_remove_property_change_handler (AtkObject *accessible,
493 AtkObjectClass *klass;
495 g_return_if_fail ((accessible != NULL));
496 g_return_if_fail (ATK_IS_OBJECT (accessible));
498 klass = ATK_OBJECT_GET_CLASS (accessible);
499 if (klass->remove_property_change_handler)
500 (klass->remove_property_change_handler) (accessible, handler_id);
504 atk_relation_type_register (gchar *name)
506 /* TODO: associate name with new type */
507 static guint type = ATK_RELATION_LAST_DEFINED;
512 atk_relation_new (GArray *target,
513 AtkRelationType relationship)
515 AtkRelation* relation;
516 g_return_val_if_fail ((target != NULL), NULL);
518 relation = (AtkRelation *) g_malloc (sizeof (AtkRelation));
520 g_return_val_if_fail ((relation != NULL), NULL);
522 relation->target = target;
523 relation->relationship = relationship;
529 atk_relation_set_contains (AtkRelationSet *set,
530 AtkRelationType relationship)
536 g_return_val_if_fail ((set != NULL), FALSE);
538 array_item = set->relations;
539 if (array_item == NULL)
541 for (i = 0; i < array_item->len; i++)
543 item = g_array_index (array_item, AtkRelation*, i);
544 if (item->relationship == relationship)
551 atk_relation_set_remove (AtkRelationSet *set,
552 AtkRelation *relation)
558 g_return_if_fail (set != NULL);
559 g_return_if_fail (relation != NULL);
561 array_item = set->relations;
562 if (array_item == NULL)
564 for (i = 0; i < array_item->len; i++)
566 item = g_array_index (array_item, AtkRelation*, i);
567 if (item == relation)
569 g_array_remove_index (array_item, i);
576 atk_relation_set_add (AtkRelationSet *set,
577 AtkRelation *relation)
579 g_return_if_fail (set != NULL);
580 g_return_if_fail (relation != NULL);
582 if (set->relations == NULL)
584 set->relations = g_array_new (FALSE, TRUE, sizeof (AtkRelation));
586 set->relations = g_array_append_val (set->relations, relation);
590 atk_relation_set_get_n_relations (AtkRelationSet *set)
592 g_return_val_if_fail (set != NULL, 0);
594 if (set->relations == NULL)
597 return set->relations->len;
601 atk_relation_set_get_relation (AtkRelationSet *set,
607 g_return_val_if_fail (set != NULL, NULL);
608 g_return_val_if_fail (i >= 0, NULL);
610 array_item = set->relations;
611 if (array_item == NULL)
613 item = g_array_index (array_item, AtkRelation*, i);
621 atk_relation_set_get_relation_by_type (AtkRelationSet *set,
622 AtkRelationType relationship)
628 g_return_val_if_fail (set != NULL, NULL);
630 array_item = set->relations;
631 if (array_item == NULL)
633 for (i = 0; i < array_item->len; i++)
635 item = g_array_index (array_item, AtkRelation*, i);
636 if (item->relationship == relationship)
643 atk_relation_get_type (AtkRelation *relation)
645 g_return_val_if_fail (relation != NULL, 0);
646 return relation->relationship;
650 atk_relation_get_target (AtkRelation *relation)
652 g_return_val_if_fail (relation != NULL, 0);
653 return relation->target;
657 atk_state_mask_get_name (AtkStateMask state)
664 for (n=0; n<NUM_POSSIBLE_STATES; ++n)
666 /* fall through and return null if multiple bits are set */
667 if (state == (1 << n)) return state_names[n];
674 atk_state_mask_for_name (gchar *name)
678 g_return_val_if_fail ((strlen(name)>0), 0);
679 for (i=0; i<NUM_POSSIBLE_STATES; ++i)
681 if (!strcmp(name, state_names[i])) return ATK_STATE(i);
687 * Return a reference to an object's AtkObject implementation, if
688 * the object implements AtkObjectIface.
689 * @object: The GObject instance which should implement #AtkObjectIface
690 * if a non-null return value is required.
693 atk_object_ref_accessible (AtkIfaceImplementor *object)
695 AtkObjectIface *iface;
696 AtkObject *accessible = NULL;
698 g_return_val_if_fail ((object != NULL), NULL);
699 g_return_val_if_fail ((iface = ATK_OBJECT_GET_IFACE (object)), NULL );
701 if (iface != NULL) accessible = (*(iface->ref_accessible)) (object) ;
703 g_return_val_if_fail ((accessible != NULL), NULL);
705 return ATK_OBJECT (accessible) ;
709 atk_object_real_get_relation_set (AtkObject *accessible)
711 return accessible->relation_set;
715 atk_object_real_set_property (GObject *object,
720 AtkObject *accessible;
722 accessible = ATK_OBJECT (object);
727 atk_object_set_name (accessible, g_value_get_string (value));
729 case PROP_DESCRIPTION:
730 atk_object_set_description (accessible, g_value_get_string (value));
733 g_print ("This interface does not support setting the state of an accessible object\n");
741 atk_object_real_get_property (GObject *object,
746 AtkObject *accessible;
748 accessible = ATK_OBJECT (object);
753 g_value_set_string (value, atk_object_get_name (accessible));
755 case PROP_DESCRIPTION:
756 g_value_set_string (value, atk_object_get_description (accessible));
759 g_value_set_int (value, atk_object_get_state (accessible));
767 atk_object_finalize (GObject *object)
769 AtkObject *accessible;
772 g_return_if_fail (ATK_IS_OBJECT (object));
774 accessible = ATK_OBJECT (object);
776 g_free (accessible->name);
777 g_free (accessible->description);
780 * Free memory allocated for relations and relation sets;
782 relations = accessible->relation_set->relations;
785 gint len = relations->len;
787 AtkRelation *relation;
789 for (i = 0; i < len; i++)
791 relation = g_array_index (relations, AtkRelation*, i);
792 g_array_free (relation->target, TRUE);
794 g_array_free (relations, TRUE);
796 g_free (accessible->relation_set);
798 G_OBJECT_CLASS (parent_class)->finalize (object);