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;
59 static void atk_object_class_init (AtkObjectClass *klass);
60 static void atk_object_init (AtkObject *accessible,
61 AtkObjectClass *klass);
62 static AtkRelationSet* atk_object_real_get_relation_set (AtkObject *accessible);
64 static void atk_object_real_set_property(GObject *object,
68 static void atk_object_real_get_property(GObject *object,
72 static void atk_object_finalize (GObject *object);
74 static gchar* state_names[NUM_POSSIBLE_STATES];
77 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
80 static gpointer parent_class = NULL;
82 static const gchar* atk_object_name_property_name = "accessible-name";
83 static const gchar* atk_object_name_property_state = "accessible-state";
84 static const gchar* atk_object_name_property_description = "accessible-description";
87 atk_object_get_type (void)
89 static GType type = 0;
93 static const GTypeInfo typeInfo =
95 sizeof (AtkObjectClass),
97 (GBaseFinalizeFunc) NULL,
98 (GClassInitFunc) atk_object_class_init,
99 (GClassFinalizeFunc) NULL,
103 (GInstanceInitFunc) atk_object_init,
105 type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
111 atk_object_class_init (AtkObjectClass *klass)
113 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
115 parent_class = g_type_class_ref (G_TYPE_OBJECT);
117 gobject_class->set_property = atk_object_real_set_property;
118 gobject_class->get_property = atk_object_real_get_property;
119 gobject_class->finalize = atk_object_finalize;
121 klass->get_relation_set = atk_object_real_get_relation_set;
123 state_names[ATK_STATE_ARMED] = "armed";
124 state_names[ATK_STATE_BUSY] = "busy";
125 state_names[ATK_STATE_CHECKED] = "checked";
126 state_names[ATK_STATE_COLLAPSED] = "collapsed";
127 state_names[ATK_STATE_EDITABLE] = "editable";
128 state_names[ATK_STATE_EXPANDABLE] = "expandable";
129 state_names[ATK_STATE_EXPANDED] = "expanded";
130 state_names[ATK_STATE_FOCUSABLE] = "focusable";
131 state_names[ATK_STATE_FOCUSED] = "focused";
132 state_names[ATK_STATE_HORIZONTAL] = "horizontal";
133 state_names[ATK_STATE_ICONIFIED] = "iconified";
134 state_names[ATK_STATE_MODAL] = "modal";
135 state_names[ATK_STATE_MULTI_LINE] = "multi-line";
136 state_names[ATK_STATE_MULTISELECTABLE] = "multiselectable";
137 state_names[ATK_STATE_OPAQUE] = "opaque";
138 state_names[ATK_STATE_PRESSED] = "pressed";
139 state_names[ATK_STATE_RESIZABLE] = "resizeable";
140 state_names[ATK_STATE_SELECTABLE] = "selectable";
141 state_names[ATK_STATE_SELECTED] = "selected";
142 state_names[ATK_STATE_SENSITIVE] = "sensitive";
143 state_names[ATK_STATE_SHOWING] = "showing";
144 state_names[ATK_STATE_SINGLE_LINE] = "single-line";
145 state_names[ATK_STATE_TRANSIENT] = "transient";
146 state_names[ATK_STATE_VERTICAL] = "vertical";
147 state_names[ATK_STATE_VISIBLE] = "visible";
149 klass->children_changed = NULL;
151 g_object_class_install_property (gobject_class,
153 g_param_spec_string (atk_object_name_property_name,
155 "Object instance\'s name formatted for "
156 "assistive technology access",
159 g_object_class_install_property (gobject_class,
161 g_param_spec_string (atk_object_name_property_description,
162 "Accessible Description",
163 "Description of an object, formatted for "
164 "assistive technology access",
167 g_object_class_install_property (gobject_class,
169 g_param_spec_int (atk_object_name_property_state,
171 "The current state of this object "
172 "or its UI component",
178 /* register some properties - these could be change signals instead */
179 g_object_class_install_property (gobject_class,
181 g_param_spec_ccallback ("accessible_parent", "Accessible Parent",
182 "First accessible ancestor (container or object) "
183 "which this object is a descendant of",
187 g_object_class_install_property (gobject_class,
189 g_param_spec_ccallback ("accessible_role", "Accessible Role",
190 "The user-interface role of this object",
192 g_object_class_install_property (gobject_class,
194 g_param_spec_ccallback ("accessible_state", "Accessible State",
195 "The current state of this object "
196 "or its UI component",
198 g_object_class_install_property (gobject_class,
200 g_param_spec_ccallback ("accessible_text", "Accessible Text",
201 "This object\'s accessible text contents",
203 g_object_class_install_property (gobject_class,
205 g_param_spec_ccallback ("accessible_caret", "Accessible Text Caret",
206 "The current text caret state and position "
207 "for this component",
209 gaccessible_signals[CHILDREN_CHANGED] =
210 g_signal_newc ("accessible_children_changed",
211 G_TYPE_FROM_CLASS (klass),
213 G_STRUCT_OFFSET (AtkObjectClass, children_changed), /* still need to declare and define this func */
215 g_cclosure_marshal_VOID__UINT_POINTER,
217 2, G_TYPE_UINT, ATK_TYPE_OBJECT);
222 atk_object_init (AtkObject *accessible,
223 AtkObjectClass *klass)
225 accessible->relation_set = g_malloc (sizeof (AtkRelationSet));
226 g_return_if_fail (accessible->relation_set != NULL);
227 accessible->relation_set->relations = NULL;
231 atk_implementor_get_type (void)
233 static GType type = 0;
237 static const GTypeInfo typeInfo =
239 sizeof (AtkImplementorIface),
240 (GBaseInitFunc) NULL,
241 (GBaseFinalizeFunc) NULL,
244 type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
250 G_CONST_RETURN gchar*
251 atk_object_get_name (AtkObject *accessible)
253 AtkObjectClass *klass;
255 g_return_val_if_fail (accessible != NULL, NULL);
256 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
258 klass = ATK_OBJECT_GET_CLASS (accessible);
260 return (klass->get_name) (accessible);
265 G_CONST_RETURN gchar*
266 atk_object_get_description (AtkObject *accessible)
268 AtkObjectClass *klass;
270 g_return_val_if_fail (accessible != NULL, NULL);
271 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
273 klass = ATK_OBJECT_GET_CLASS (accessible);
274 if (klass->get_description)
275 return (klass->get_description) (accessible);
281 atk_object_get_parent (AtkObject *accessible)
283 AtkObjectClass *klass;
285 g_return_val_if_fail (accessible != NULL, NULL);
286 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
288 klass = ATK_OBJECT_GET_CLASS (accessible);
289 if (klass->get_parent)
290 return (klass->get_parent) (accessible);
296 atk_object_get_n_accessible_children (AtkObject *accessible)
298 AtkObjectClass *klass;
300 g_return_val_if_fail (accessible != NULL, 0);
301 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
303 klass = ATK_OBJECT_GET_CLASS (accessible);
304 if (klass->get_n_children)
305 return (klass->get_n_children) (accessible);
311 atk_object_ref_accessible_child (AtkObject *accessible,
314 AtkObjectClass *klass;
316 g_return_val_if_fail (accessible != NULL, NULL);
317 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
319 klass = ATK_OBJECT_GET_CLASS (accessible);
320 if (klass->ref_child)
321 return (klass->ref_child) (accessible, i);
327 atk_object_get_relation_set (AtkObject *accessible)
329 AtkObjectClass *klass;
331 g_return_val_if_fail (accessible != NULL, NULL);
332 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
334 klass = ATK_OBJECT_GET_CLASS (accessible);
335 if (klass->get_relation_set)
336 return (klass->get_relation_set) (accessible);
342 atk_role_register (const gchar *name)
344 /* TODO: associate name with new type */
345 static guint type = ATK_ROLE_LAST_DEFINED;
350 atk_object_get_role (AtkObject *accessible) {
351 AtkObjectClass *klass;
353 g_return_val_if_fail (accessible != NULL, ATK_ROLE_UNKNOWN);
354 g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
356 klass = ATK_OBJECT_GET_CLASS (accessible);
358 return (klass->get_role) (accessible);
360 return ATK_ROLE_UNKNOWN;
364 atk_state_type_register (const gchar *name)
366 /* TODO: associate name with new type */
367 static guint type = ATK_STATE_LAST_DEFINED;
368 if (type < NUM_POSSIBLE_STATES) {
371 return ATK_STATE_INVALID; /* caller needs to check */
375 atk_object_get_state (AtkObject *accessible) {
376 AtkObjectClass *klass;
378 g_return_val_if_fail (accessible != NULL, 0);
379 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
381 klass = ATK_OBJECT_GET_CLASS (accessible);
382 if (klass->get_state)
383 return (klass->get_state) (accessible);
389 atk_object_get_index_in_parent (AtkObject *accessible)
391 AtkObjectClass *klass;
393 g_return_val_if_fail (accessible != NULL, -1);
394 g_return_val_if_fail (ATK_OBJECT (accessible), -1);
396 klass = ATK_OBJECT_GET_CLASS (accessible);
397 if (klass->get_index_in_parent)
398 return (klass->get_index_in_parent) (accessible);
404 atk_object_set_name (AtkObject *accessible,
407 AtkObjectClass *klass;
409 g_return_if_fail (accessible != NULL);
410 g_return_if_fail (ATK_IS_OBJECT (accessible));
411 g_return_if_fail (name != NULL);
413 klass = ATK_OBJECT_GET_CLASS (accessible);
416 (klass->set_name) (accessible, name);
417 g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
422 atk_object_set_description (AtkObject *accessible,
423 const gchar *description)
425 AtkObjectClass *klass;
427 g_return_if_fail (accessible != NULL);
428 g_return_if_fail (ATK_IS_OBJECT (accessible));
429 g_return_if_fail (description != NULL);
431 klass = ATK_OBJECT_GET_CLASS (accessible);
432 if (klass->set_description)
434 (klass->set_description) (accessible, description);
435 g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
440 atk_object_set_parent (AtkObject *accessible,
443 AtkObjectClass *klass;
445 g_return_if_fail (accessible != NULL);
446 g_return_if_fail (ATK_IS_OBJECT (accessible));
448 klass = ATK_OBJECT_GET_CLASS (accessible);
449 if (klass->set_parent)
450 (klass->set_parent) (accessible, parent);
454 atk_object_set_role (AtkObject *accessible,
457 AtkObjectClass *klass;
459 g_return_if_fail (accessible != NULL);
460 g_return_if_fail (ATK_IS_OBJECT (accessible));
462 klass = ATK_OBJECT_GET_CLASS (accessible);
464 (klass->set_role) (accessible, role);
468 atk_object_connect_property_change_handler (AtkObject *accessible,
469 AtkPropertyChangeHandler *handler)
471 AtkObjectClass *klass;
473 g_return_val_if_fail (accessible != NULL, 0);
474 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
475 g_return_val_if_fail ((handler != NULL), 0);
477 klass = ATK_OBJECT_GET_CLASS (accessible);
478 if (klass->connect_property_change_handler)
479 return (klass->connect_property_change_handler) (accessible, handler);
485 atk_object_remove_property_change_handler (AtkObject *accessible,
488 AtkObjectClass *klass;
490 g_return_if_fail (accessible != NULL);
491 g_return_if_fail (ATK_IS_OBJECT (accessible));
493 klass = ATK_OBJECT_GET_CLASS (accessible);
494 if (klass->remove_property_change_handler)
495 (klass->remove_property_change_handler) (accessible, handler_id);
499 atk_relation_type_register (const gchar *name)
501 /* TODO: associate name with new type */
502 static guint type = ATK_RELATION_LAST_DEFINED;
507 atk_relation_new (GArray *target,
508 AtkRelationType relationship)
510 AtkRelation* relation;
511 g_return_val_if_fail (target != NULL, NULL);
513 relation = (AtkRelation *) g_malloc (sizeof (AtkRelation));
515 g_return_val_if_fail ((relation != NULL), NULL);
517 relation->target = target;
518 relation->relationship = relationship;
524 atk_relation_set_contains (AtkRelationSet *set,
525 AtkRelationType relationship)
531 g_return_val_if_fail (set != NULL, FALSE);
533 array_item = set->relations;
534 if (array_item == NULL)
536 for (i = 0; i < array_item->len; i++)
538 item = g_array_index (array_item, AtkRelation*, i);
539 if (item->relationship == relationship)
546 atk_relation_set_remove (AtkRelationSet *set,
547 AtkRelation *relation)
553 g_return_if_fail (set != NULL);
554 g_return_if_fail (relation != NULL);
556 array_item = set->relations;
557 if (array_item == NULL)
559 for (i = 0; i < array_item->len; i++)
561 item = g_array_index (array_item, AtkRelation*, i);
562 if (item == relation)
564 g_array_remove_index (array_item, i);
571 atk_relation_set_add (AtkRelationSet *set,
572 AtkRelation *relation)
574 g_return_if_fail (set != NULL);
575 g_return_if_fail (relation != NULL);
577 if (set->relations == NULL)
579 set->relations = g_array_new (FALSE, TRUE, sizeof (AtkRelation));
581 set->relations = g_array_append_val (set->relations, relation);
585 atk_relation_set_get_n_relations (AtkRelationSet *set)
587 g_return_val_if_fail (set != NULL, 0);
589 if (set->relations == NULL)
592 return set->relations->len;
596 atk_relation_set_get_relation (AtkRelationSet *set,
602 g_return_val_if_fail (set != NULL, NULL);
603 g_return_val_if_fail (i >= 0, NULL);
605 array_item = set->relations;
606 if (array_item == NULL)
608 item = g_array_index (array_item, AtkRelation*, i);
616 atk_relation_set_get_relation_by_type (AtkRelationSet *set,
617 AtkRelationType relationship)
623 g_return_val_if_fail (set != NULL, NULL);
625 array_item = set->relations;
626 if (array_item == NULL)
628 for (i = 0; i < array_item->len; i++)
630 item = g_array_index (array_item, AtkRelation*, i);
631 if (item->relationship == relationship)
638 atk_relation_get_type (AtkRelation *relation)
640 g_return_val_if_fail (relation != NULL, 0);
641 return relation->relationship;
645 atk_relation_get_target (AtkRelation *relation)
647 g_return_val_if_fail (relation != NULL, 0);
648 return relation->target;
651 G_CONST_RETURN gchar*
652 atk_state_mask_get_name (AtkStateMask state)
659 for (n=0; n<NUM_POSSIBLE_STATES; ++n)
661 /* fall through and return null if multiple bits are set */
662 if (state == (1 << n)) return state_names[n];
669 atk_state_mask_for_name (const gchar *name)
673 g_return_val_if_fail ((strlen(name)>0), 0);
674 for (i=0; i<NUM_POSSIBLE_STATES; ++i)
676 if (!strcmp(name, state_names[i])) return ATK_STATE(i);
682 * Return a reference to an object's AtkObject implementation, if
683 * the object implements AtkObjectIface.
684 * @object: The GObject instance which should implement #AtkImplementorIface
685 * if a non-null return value is required.
688 atk_implementor_ref_accessible (AtkImplementor *object)
690 AtkImplementorIface *iface;
691 AtkObject *accessible = NULL;
693 g_return_val_if_fail (object != NULL, NULL);
694 g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
696 iface = ATK_IMPLEMENTOR_GET_IFACE (object);
699 accessible = iface->ref_accessible (object);
701 g_return_val_if_fail ((accessible != NULL), NULL);
707 atk_object_real_get_relation_set (AtkObject *accessible)
709 return accessible->relation_set;
713 atk_object_real_set_property (GObject *object,
718 AtkObject *accessible;
720 accessible = ATK_OBJECT (object);
725 atk_object_set_name (accessible, g_value_get_string (value));
727 case PROP_DESCRIPTION:
728 atk_object_set_description (accessible, g_value_get_string (value));
731 g_print ("This interface does not support setting the state of an accessible object\n");
739 atk_object_real_get_property (GObject *object,
744 AtkObject *accessible;
746 accessible = ATK_OBJECT (object);
751 g_value_set_string (value, atk_object_get_name (accessible));
753 case PROP_DESCRIPTION:
754 g_value_set_string (value, atk_object_get_description (accessible));
757 g_value_set_int (value, atk_object_get_state (accessible));
765 atk_object_finalize (GObject *object)
767 AtkObject *accessible;
770 g_return_if_fail (ATK_IS_OBJECT (object));
772 accessible = ATK_OBJECT (object);
774 g_free (accessible->name);
775 g_free (accessible->description);
778 * Free memory allocated for relations and relation sets;
780 relations = accessible->relation_set->relations;
783 gint len = relations->len;
785 AtkRelation *relation;
787 for (i = 0; i < len; i++)
789 relation = g_array_index (relations, AtkRelation*, i);
790 g_array_free (relation->target, TRUE);
792 g_array_free (relations, TRUE);
794 g_free (accessible->relation_set);
796 G_OBJECT_CLASS (parent_class)->finalize (object);