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.
22 #include <glib-object.h>
26 /* New GObject properties registered by AtkObject */
29 PROP_0, /* gobject convention */
33 PROP_PARENT, /* ancestry has changed */
34 PROP_STATE, /* AtkStateSet for the object has changed */
38 PROP_TABLE_COLUMN_DESCRIPTION,
39 PROP_TABLE_COLUMN_HEADER,
40 PROP_TABLE_ROW_DESCRIPTION,
41 PROP_TABLE_ROW_HEADER,
43 PROP_LAST /* gobject convention */
56 static void atk_object_class_init (AtkObjectClass *klass);
57 static void atk_object_init (AtkObject *accessible,
58 AtkObjectClass *klass);
59 static AtkRelationSet* atk_object_real_ref_relation_set
60 (AtkObject *accessible);
62 static void atk_object_real_set_property (GObject *object,
66 static void atk_object_real_get_property (GObject *object,
70 static void atk_object_finalize (GObject *object);
71 static G_CONST_RETURN gchar*
72 atk_object_real_get_name (AtkObject *object);
73 static G_CONST_RETURN gchar*
74 atk_object_real_get_description
76 static AtkObject* atk_object_real_get_parent (AtkObject *object);
77 static AtkRole atk_object_real_get_role (AtkObject *object);
78 static AtkStateSet* atk_object_real_ref_state_set
80 static void atk_object_real_set_name (AtkObject *object,
82 static void atk_object_real_set_description
84 const gchar *description);
85 static void atk_object_real_set_parent (AtkObject *object,
87 static void atk_object_real_set_role (AtkObject *object,
89 static guint atk_object_real_connect_property_change_handler
91 AtkPropertyChangeHandler
93 static void atk_object_real_remove_property_change_handler
96 static void atk_object_notify (GObject *obj,
100 static guint atk_object_signals[LAST_SIGNAL] = { 0, };
102 static gpointer parent_class = NULL;
104 static const gchar* atk_object_name_property_name = "accessible-name";
105 static const gchar* atk_object_name_property_description = "accessible-description";
106 static const gchar* atk_object_name_property_parent = "accessible-parent";
107 static const gchar* atk_object_name_property_value = "accessible-value";
108 static const gchar* atk_object_name_property_role = "accessible-role";
109 static const gchar* atk_object_name_property_table_caption = "accessible-table-caption";
110 static const gchar* atk_object_name_property_table_column_description = "accessible-table-column-description";
111 static const gchar* atk_object_name_property_table_column_header = "accessible-table-column-header";
112 static const gchar* atk_object_name_property_table_row_description = "accessible-table-row-description";
113 static const gchar* atk_object_name_property_table_row_header = "accessible-table-row-header";
114 static const gchar* atk_object_name_property_table_summary = "accessible-table-summary";
117 atk_object_get_type (void)
119 static GType type = 0;
123 static const GTypeInfo typeInfo =
125 sizeof (AtkObjectClass),
126 (GBaseInitFunc) NULL,
127 (GBaseFinalizeFunc) NULL,
128 (GClassInitFunc) atk_object_class_init,
129 (GClassFinalizeFunc) NULL,
133 (GInstanceInitFunc) atk_object_init,
135 type = g_type_register_static (G_TYPE_OBJECT, "AtkObject", &typeInfo, 0) ;
141 atk_object_class_init (AtkObjectClass *klass)
143 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
145 parent_class = g_type_class_ref (G_TYPE_OBJECT);
147 gobject_class->set_property = atk_object_real_set_property;
148 gobject_class->get_property = atk_object_real_get_property;
149 gobject_class->finalize = atk_object_finalize;
150 gobject_class->notify = atk_object_notify;
152 klass->get_name = atk_object_real_get_name;
153 klass->get_description = atk_object_real_get_description;
154 klass->get_parent = atk_object_real_get_parent;
155 klass->get_n_children = NULL;
156 klass->ref_child = NULL;
157 klass->get_index_in_parent = NULL;
158 klass->ref_relation_set = atk_object_real_ref_relation_set;
159 klass->get_role = atk_object_real_get_role;
160 klass->ref_state_set = atk_object_real_ref_state_set;
161 klass->set_name = atk_object_real_set_name;
162 klass->set_description = atk_object_real_set_description;
163 klass->set_parent = atk_object_real_set_parent;
164 klass->set_role = atk_object_real_set_role;
165 klass->connect_property_change_handler =
166 atk_object_real_connect_property_change_handler;
167 klass->remove_property_change_handler =
168 atk_object_real_remove_property_change_handler;
171 * We do not define default signal handlers here
173 klass->children_changed = NULL;
174 klass->focus_event = NULL;
175 klass->property_change = NULL;
176 klass->visible_data_changed = NULL;
178 g_object_class_install_property (gobject_class,
180 g_param_spec_string (atk_object_name_property_name,
182 "Object instance\'s name formatted for "
183 "assistive technology access",
186 g_object_class_install_property (gobject_class,
188 g_param_spec_string (atk_object_name_property_description,
189 "Accessible Description",
190 "Description of an object, formatted for "
191 "assistive technology access",
194 g_object_class_install_property (gobject_class,
196 g_param_spec_object (atk_object_name_property_parent,
198 "Is used to notify that the parent has changed ",
201 g_object_class_install_property (gobject_class,
203 g_param_spec_double (atk_object_name_property_value,
205 "Is used to notify that the value has changed ",
210 g_object_class_install_property (gobject_class,
212 g_param_spec_int (atk_object_name_property_role,
214 "The accessible role this object ",
219 g_object_class_install_property (gobject_class,
221 g_param_spec_string (atk_object_name_property_table_caption,
222 "Accessible Table Caption",
223 "Is used to notify that the table caption has changed ",
226 g_object_class_install_property (gobject_class,
227 PROP_TABLE_COLUMN_HEADER,
228 g_param_spec_object (atk_object_name_property_table_column_header,
229 "Accessible Table Column Header",
230 "Is used to notify that the table column header has changed ",
233 g_object_class_install_property (gobject_class,
234 PROP_TABLE_COLUMN_DESCRIPTION,
235 g_param_spec_string (atk_object_name_property_table_column_description,
236 "Accessible Table Column Description",
237 "Is used to notify that the table columnscription has changed ",
240 g_object_class_install_property (gobject_class,
241 PROP_TABLE_ROW_HEADER,
242 g_param_spec_object (atk_object_name_property_table_row_header,
243 "Accessible Table Row Header",
244 "Is used to notify that the table row header has changed ",
247 g_object_class_install_property (gobject_class,
248 PROP_TABLE_ROW_DESCRIPTION,
249 g_param_spec_string (atk_object_name_property_table_row_description,
250 "Accessible Table Row Description",
251 "Is used to notify that the table row description has changed ",
254 g_object_class_install_property (gobject_class,
256 g_param_spec_object (atk_object_name_property_table_summary,
257 "Accessible Table Summary",
258 "Is used to notify that the table summary has changed ",
262 * The signal "children_changed" supports two details:
265 atk_object_signals[CHILDREN_CHANGED] =
266 g_signal_new ("children_changed",
267 G_TYPE_FROM_CLASS (klass),
268 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
269 G_STRUCT_OFFSET (AtkObjectClass, children_changed),
271 g_cclosure_marshal_VOID__UINT_POINTER,
273 2, G_TYPE_UINT, G_TYPE_POINTER);
274 atk_object_signals[FOCUS_EVENT] =
275 g_signal_new ("focus_event",
276 G_TYPE_FROM_CLASS (klass),
278 G_STRUCT_OFFSET (AtkObjectClass, focus_event),
280 g_cclosure_marshal_VOID__BOOLEAN,
283 atk_object_signals[PROPERTY_CHANGE] =
284 g_signal_new ("property_change",
285 G_TYPE_FROM_CLASS (klass),
286 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
287 G_STRUCT_OFFSET (AtkObjectClass, property_change),
288 (GSignalAccumulator) NULL, NULL,
289 g_cclosure_marshal_VOID__POINTER,
293 * The "state_change" signal supports details, one for each accessible
297 atk_object_signals[STATE_CHANGE] =
298 g_signal_new ("state_change",
299 G_TYPE_FROM_CLASS (klass),
300 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
301 G_STRUCT_OFFSET (AtkObjectClass, state_change),
302 (GSignalAccumulator) NULL, NULL,
303 g_cclosure_marshal_VOID__BOOLEAN,
306 atk_object_signals[VISIBLE_DATA_CHANGED] =
307 g_signal_new ("visible_data_changed",
308 G_TYPE_FROM_CLASS (klass),
310 G_STRUCT_OFFSET (AtkObjectClass, visible_data_changed),
311 (GSignalAccumulator) NULL, NULL,
312 g_cclosure_marshal_VOID__VOID,
317 atk_object_init (AtkObject *accessible,
318 AtkObjectClass *klass)
320 accessible->name = NULL;
321 accessible->description = NULL;
322 accessible->accessible_parent = NULL;
323 accessible->relation_set = atk_relation_set_new();
324 accessible->role = ATK_ROLE_UNKNOWN;
328 atk_implementor_get_type (void)
330 static GType type = 0;
334 static const GTypeInfo typeInfo =
336 sizeof (AtkImplementorIface),
337 (GBaseInitFunc) NULL,
338 (GBaseFinalizeFunc) NULL,
341 type = g_type_register_static (G_TYPE_INTERFACE, "AtkImplementorIface", &typeInfo, 0) ;
348 * atk_object_get_name:
349 * @accessible: an #AtkObject
351 * Gets the accessible name of the accessible.
353 * Returns: a character string representing the accessible name of the object.
355 G_CONST_RETURN gchar*
356 atk_object_get_name (AtkObject *accessible)
358 AtkObjectClass *klass;
360 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
362 klass = ATK_OBJECT_GET_CLASS (accessible);
364 return (klass->get_name) (accessible);
370 * atk_object_get_description:
371 * @accessible: an #AtkObject
373 * Gets the accessible description of the accessible.
375 * Returns: a character string representing the accessible description
379 G_CONST_RETURN gchar*
380 atk_object_get_description (AtkObject *accessible)
382 AtkObjectClass *klass;
384 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
386 klass = ATK_OBJECT_GET_CLASS (accessible);
387 if (klass->get_description)
388 return (klass->get_description) (accessible);
394 * atk_object_get_parent:
395 * @accessible: an #AtkObject
397 * Gets the accessible parent of the accessible.
399 * Returns: a #AtkObject representing the accessible parent of the accessible
402 atk_object_get_parent (AtkObject *accessible)
404 AtkObjectClass *klass;
406 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
408 klass = ATK_OBJECT_GET_CLASS (accessible);
409 if (klass->get_parent)
410 return (klass->get_parent) (accessible);
416 * atk_object_get_n_accessible_children:
417 * @accessible: an #AtkObject
419 * Gets the number of accessible children of the accessible.
421 * Returns: an integer representing the number of accessible children
425 atk_object_get_n_accessible_children (AtkObject *accessible)
427 AtkObjectClass *klass;
429 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
431 klass = ATK_OBJECT_GET_CLASS (accessible);
432 if (klass->get_n_children)
433 return (klass->get_n_children) (accessible);
439 * atk_object_ref_accessible_child:
440 * @accessible: an #AtkObject
441 * @i: a gint representing the position of the child, starting from 0
443 * Gets a reference to the specified accessible child of the object.
444 * The accessible children are 0-based so the first accessible child is
445 * at index 0, the second at index 1 and so on.
447 * Returns: an #AtkObject representing the specified accessible child
451 atk_object_ref_accessible_child (AtkObject *accessible,
454 AtkObjectClass *klass;
456 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
458 klass = ATK_OBJECT_GET_CLASS (accessible);
459 if (klass->ref_child)
460 return (klass->ref_child) (accessible, i);
466 * atk_object_ref_relation_set:
467 * @accessible: an #AtkObject
469 * Gets the #AtkRelationSet associated with the object.
471 * Returns: an #AtkRelationSet representing the relation set of the object.
474 atk_object_ref_relation_set (AtkObject *accessible)
476 AtkObjectClass *klass;
478 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
480 klass = ATK_OBJECT_GET_CLASS (accessible);
481 if (klass->ref_relation_set)
482 return (klass->ref_relation_set) (accessible);
489 * @name: a character string describing the new role.
491 * Registers the role specified by @name.
493 * Returns: an #AtkRole for the new role.
496 atk_role_register (const gchar *name)
498 /* TODO: associate name with new type */
499 static guint type = ATK_ROLE_LAST_DEFINED;
504 * atk_object_get_role:
505 * @accessible: an #AtkObject
507 * Gets the role of the accessible.
509 * Returns: an #AtkRole which is the role of the accessible
512 atk_object_get_role (AtkObject *accessible)
514 AtkObjectClass *klass;
516 g_return_val_if_fail (ATK_IS_OBJECT (accessible), ATK_ROLE_UNKNOWN);
518 klass = ATK_OBJECT_GET_CLASS (accessible);
520 return (klass->get_role) (accessible);
522 return ATK_ROLE_UNKNOWN;
526 * atk_object_ref_state_set:
527 * @accessible: an #AtkObject
529 * Gets a reference to the state set of the accessible; the caller must
530 * unreference it when it is no longer needed.
532 * Returns: a reference to an #AtkStateSet which is the state
533 * set of the accessible
536 atk_object_ref_state_set (AtkObject *accessible)
538 AtkObjectClass *klass;
540 g_return_val_if_fail (ATK_IS_OBJECT (accessible), NULL);
542 klass = ATK_OBJECT_GET_CLASS (accessible);
543 if (klass->ref_state_set)
544 return (klass->ref_state_set) (accessible);
550 * atk_object_get_index_in_parent:
551 * @accessible: an #AtkObject
553 * Gets the 0-based index of this accessible in its parent; returns -1 if the
554 * accessible does not have an accessible parent.
556 * Returns: an integer which is the index of the accessible in its parent
559 atk_object_get_index_in_parent (AtkObject *accessible)
561 AtkObjectClass *klass;
563 g_return_val_if_fail (ATK_OBJECT (accessible), -1);
565 klass = ATK_OBJECT_GET_CLASS (accessible);
566 if (klass->get_index_in_parent)
567 return (klass->get_index_in_parent) (accessible);
573 * atk_object_set_name:
574 * @accessible: an #AtkObject
575 * @name: a character string to be set as the accessible name
577 * Sets the accessible name of the accessible.
580 atk_object_set_name (AtkObject *accessible,
583 AtkObjectClass *klass;
585 g_return_if_fail (ATK_IS_OBJECT (accessible));
586 g_return_if_fail (name != NULL);
588 klass = ATK_OBJECT_GET_CLASS (accessible);
591 (klass->set_name) (accessible, name);
592 g_object_notify (G_OBJECT (accessible), atk_object_name_property_name);
597 * atk_object_set_description:
598 * @accessible: an #AtkObject
599 * @description : a character string to be set as the accessible description
601 * Sets the accessible description of the accessible.
604 atk_object_set_description (AtkObject *accessible,
605 const gchar *description)
607 AtkObjectClass *klass;
609 g_return_if_fail (ATK_IS_OBJECT (accessible));
610 g_return_if_fail (description != NULL);
612 klass = ATK_OBJECT_GET_CLASS (accessible);
613 if (klass->set_description)
615 (klass->set_description) (accessible, description);
616 g_object_notify (G_OBJECT (accessible), atk_object_name_property_description);
621 * atk_object_set_parent:
622 * @accessible: an #AtkObject
623 * @parent : an #AtkObject to be set as the accessible parent
625 * Sets the accessible parent of the accessible.
628 atk_object_set_parent (AtkObject *accessible,
631 AtkObjectClass *klass;
633 g_return_if_fail (ATK_IS_OBJECT (accessible));
635 klass = ATK_OBJECT_GET_CLASS (accessible);
636 if (klass->set_parent)
638 (klass->set_parent) (accessible, parent);
639 g_object_notify (G_OBJECT (accessible), atk_object_name_property_parent);
644 * atk_object_set_role:
645 * @accessible: an #AtkObject
646 * @role : an #AtkRole to be set as the role
648 * Sets the role of the accessible.
651 atk_object_set_role (AtkObject *accessible,
654 AtkObjectClass *klass;
656 g_return_if_fail (ATK_IS_OBJECT (accessible));
658 klass = ATK_OBJECT_GET_CLASS (accessible);
661 (klass->set_role) (accessible, role);
662 g_object_notify (G_OBJECT (accessible), atk_object_name_property_role);
667 * atk_object_connect_property_change_handler:
668 * @accessible: an #AtkObject
669 * @handler : a function to be called when a property changes its value
671 * Specifies a function to be called when a property changes value.
673 * Returns: a #guint which is the handler id used in
674 * atk_object_remove_property_change_handler()
677 atk_object_connect_property_change_handler (AtkObject *accessible,
678 AtkPropertyChangeHandler *handler)
680 AtkObjectClass *klass;
682 g_return_val_if_fail (ATK_IS_OBJECT (accessible), 0);
683 g_return_val_if_fail ((handler != NULL), 0);
685 klass = ATK_OBJECT_GET_CLASS (accessible);
686 if (klass->connect_property_change_handler)
687 return (klass->connect_property_change_handler) (accessible, handler);
693 * atk_object_remove_property_change_handler:
694 * @accessible: an #AtkObject
695 * @handler_id : a guint which identifies the handler to be removed.
697 * Removes a property change handler.
700 atk_object_remove_property_change_handler (AtkObject *accessible,
703 AtkObjectClass *klass;
705 g_return_if_fail (ATK_IS_OBJECT (accessible));
707 klass = ATK_OBJECT_GET_CLASS (accessible);
708 if (klass->remove_property_change_handler)
709 (klass->remove_property_change_handler) (accessible, handler_id);
713 * atk_object_notify_state_change:
714 * @accessible: an #AtkObject
715 * @state: an #AtkState whose state is changed
716 * @value : a gboolean which indicates whether the state is being set on or off
718 * Emits a state-change signal for the specified state.
721 atk_object_notify_state_change (AtkObject *accessible,
725 g_signal_emit (accessible, atk_object_signals[STATE_CHANGE],
726 g_quark_from_string (atk_state_type_get_name (state)),
731 * atk_implementor_ref_accessible:
732 * @implementor: The #GObject instance which should implement #AtkImplementorIface
733 * if a non-null return value is required.
735 * Gets a reference to an object's #AtkObject implementation, if
736 * the object implements #AtkObjectIface
738 * Returns: a reference to an object's #AtkObject implementation
741 atk_implementor_ref_accessible (AtkImplementor *object)
743 AtkImplementorIface *iface;
744 AtkObject *accessible = NULL;
746 g_return_val_if_fail (ATK_IS_IMPLEMENTOR (object), NULL);
748 iface = ATK_IMPLEMENTOR_GET_IFACE (object);
751 accessible = iface->ref_accessible (object);
753 g_return_val_if_fail ((accessible != NULL), NULL);
758 static AtkRelationSet*
759 atk_object_real_ref_relation_set (AtkObject *accessible)
761 g_return_val_if_fail (accessible->relation_set, NULL);
762 g_object_ref (accessible->relation_set);
764 return accessible->relation_set;
768 atk_object_real_set_property (GObject *object,
773 AtkObject *accessible;
775 accessible = ATK_OBJECT (object);
780 atk_object_set_name (accessible, g_value_get_string (value));
782 case PROP_DESCRIPTION:
783 atk_object_set_description (accessible, g_value_get_string (value));
786 atk_object_set_role (accessible, g_value_get_int (value));
789 atk_object_set_parent (accessible, g_value_get_object (value));
792 if (ATK_IS_VALUE (accessible))
793 atk_value_set_current_value (ATK_VALUE (accessible), value);
801 atk_object_real_get_property (GObject *object,
806 AtkObject *accessible;
808 accessible = ATK_OBJECT (object);
813 g_value_set_string (value, atk_object_get_name (accessible));
815 case PROP_DESCRIPTION:
816 g_value_set_string (value, atk_object_get_description (accessible));
818 g_value_set_int (value, atk_object_get_role (accessible));
821 g_value_set_object (value, atk_object_get_parent (accessible));
824 if (ATK_IS_VALUE (accessible))
825 atk_value_get_current_value (ATK_VALUE (accessible), value);
828 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
834 atk_object_finalize (GObject *object)
836 AtkObject *accessible;
838 g_return_if_fail (ATK_IS_OBJECT (object));
840 accessible = ATK_OBJECT (object);
842 g_free (accessible->name);
843 g_free (accessible->description);
846 * Free memory allocated for relation set if it have been allocated.
848 if (accessible->relation_set)
849 g_object_unref (accessible->relation_set);
851 if (accessible->accessible_parent)
852 g_object_unref (accessible->accessible_parent);
854 G_OBJECT_CLASS (parent_class)->finalize (object);
857 static G_CONST_RETURN gchar*
858 atk_object_real_get_name (AtkObject *object)
863 static G_CONST_RETURN gchar*
864 atk_object_real_get_description (AtkObject *object)
866 return object->description;
870 atk_object_real_get_parent (AtkObject *object)
872 return object->accessible_parent;
876 atk_object_real_get_role (AtkObject *object)
882 atk_object_real_ref_state_set (AtkObject *accessible)
884 AtkStateSet *state_set;
887 state_set = atk_state_set_new ();
889 ap = atk_object_get_parent (accessible);
891 if (ATK_IS_SELECTION (ap))
895 atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
897 i = atk_object_get_index_in_parent (accessible);
899 if (atk_selection_is_child_selected(ATK_SELECTION (ap), i))
900 atk_state_set_add_state (state_set, ATK_STATE_SELECTED);
907 atk_object_real_set_name (AtkObject *object,
910 g_free (object->name);
911 object->name = g_strdup (name);
915 atk_object_real_set_description (AtkObject *object,
916 const gchar *description)
918 g_free (object->description);
919 object->description = g_strdup (description);
923 atk_object_real_set_parent (AtkObject *object,
926 if (object->accessible_parent)
927 g_object_unref (object->accessible_parent);
929 object->accessible_parent = parent;
930 if (object->accessible_parent)
931 g_object_ref (object->accessible_parent);
935 atk_object_real_set_role (AtkObject *object,
942 atk_object_real_connect_property_change_handler (AtkObject *obj,
943 AtkPropertyChangeHandler *handler)
945 return g_signal_connect_closure_by_id (obj,
946 atk_object_signals[PROPERTY_CHANGE],
949 G_CALLBACK (handler), NULL,
950 (GClosureNotify) NULL),
955 atk_object_real_remove_property_change_handler (AtkObject *obj,
958 g_signal_handler_disconnect (obj, handler_id);
962 * This function is a signal handler for notify signal which gets emitted
963 * when a property changes value.
965 * It constructs an AtkPropertyValues structure and emits a "property_changed"
966 * signal which causes the user specified AtkPropertyChangeHandler
970 atk_object_notify (GObject *obj,
973 AtkPropertyValues values = { 0, };
975 g_value_init (&values.new_value, pspec->value_type);
976 g_object_get_property (obj, pspec->name, &values.new_value);
977 values.property_name = pspec->name;
978 g_signal_emit (obj, atk_object_signals[PROPERTY_CHANGE],
979 g_quark_from_string (pspec->name),