+++ /dev/null
-/*
- * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
- * Copyright 2001, 2002 Sun Microsystems Inc.,
- * Copyright 2001, 2002 Ximian, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _SPI_KEYMASKS_H_
-#define _SPI_KEYMASKS_H_
-
-#include <X11/Xlib.h>
-#include <glib/gmacros.h>
-
-G_BEGIN_DECLS
-
-typedef unsigned long SpiKeyMaskType;
-
-#define SPI_KEYMASK_ALT Mod1Mask
-#define SPI_KEYMASK_MOD1 Mod1Mask
-#define SPI_KEYMASK_MOD2 Mod2Mask
-#define SPI_KEYMASK_MOD3 Mod3Mask
-#define SPI_KEYMASK_MOD4 Mod4Mask
-#define SPI_KEYMASK_MOD5 Mod5Mask
-#define SPI_KEYMASK_BUTTON1 Button1Mask
-#define SPI_KEYMASK_BUTTON2 Button2Mask
-#define SPI_KEYMASK_BUTTON3 Button3Mask
-#define SPI_KEYMASK_BUTTON4 Button4Mask
-#define SPI_KEYMASK_BUTTON5 Button5Mask
-#define SPI_KEYMASK_CONTROL ControlMask
-#define SPI_KEYMASK_SHIFT ShiftMask
-#define SPI_KEYMASK_SHIFTLOCK LockMask
-#define SPI_KEYMASK_NUMLOCK (1<<14)
-#define SPI_KEYMASK_UNMODIFIED 0
-
-G_END_DECLS
-
-#endif
--- /dev/null
+#include "AtkObject_parent_child.h"
+
+//implementation
+static AtkObjectClass *atk_object_parent_class = NULL;
+//redefines 'set_parent' function, and defines functions, which absents in AtkObject
+
+static void my_parent_child_set_parent(AtkObject *accessible, AtkObject *parent);
+
+static gint my_parent_child_get_n_children(AtkObject *accessible);
+
+static AtkObject* my_parent_child_ref_child(AtkObject *accessible, gint i);
+
+static gint my_parent_child_get_index_in_parent(AtkObject *accessible);
+
+//function, needed in instance_finalize()
+static void my_unref1(gpointer data, gpointer user_data)
+{
+ g_object_unref(data);
+}
+//add/remove child to/from array of parent(for internal use)
+static void my_parent_child_add_child(MyParentChild* parent, MyParentChild* child)
+{
+ g_ptr_array_add(parent->children, child);
+ g_object_ref(child);
+
+ g_signal_emit_by_name(parent, "children-changed::add",
+ parent->children->len - 1, child);
+}
+static void my_parent_child_remove_child(MyParentChild* parent, MyParentChild* child)
+{
+ gint i;
+ for(i = parent->children->len - 1; i >= 0; i--)
+ {
+ if(g_ptr_array_index(parent->children, i) == child) break;
+ }
+ if(i < 0)return;
+
+ g_ptr_array_remove_index(parent->children, i);
+ g_object_unref(child);
+ g_signal_emit_by_name(parent, "children-changed::remove",
+ i, child);
+}
+
+static void my_parent_child_instance_init(GTypeInstance *obj, gpointer g_class)
+{
+ MyParentChild *self = (MyParentChild*)obj;
+
+ self->children = g_ptr_array_sized_new(10);
+}
+
+static void my_parent_child_instance_finalize(GObject *obj)
+{
+ MyParentChild *self = (MyParentChild*) obj;
+ //unrefs all children
+ g_ptr_array_foreach(self->children, my_unref1, NULL);
+ //then free array (without frees pointers)
+ g_ptr_array_free(self->children, FALSE);
+ //chain to parent class
+ G_OBJECT_CLASS(atk_object_parent_class)->finalize(obj);
+}
+
+void my_parent_child_class_init(gpointer g_class, gpointer g_class_data)
+{
+ AtkObjectClass *atkObjectClass = (AtkObjectClass*)g_class;
+
+ ((GObjectClass*)g_class)->finalize = my_parent_child_instance_finalize;
+ //set pointers to new functions in table of virtuals functions
+ atkObjectClass->set_parent = my_parent_child_set_parent;
+ atkObjectClass->get_n_children = my_parent_child_get_n_children;
+ atkObjectClass->ref_child = my_parent_child_ref_child;
+ atkObjectClass->get_index_in_parent = my_parent_child_get_index_in_parent;
+
+ atk_object_parent_class = g_type_class_peek_parent(g_class);
+}
+
+static void my_parent_child_set_parent(AtkObject *accessible, AtkObject *parent)
+{
+ //applicable only with corresponding type of parent
+ g_return_if_fail(parent == NULL || MY_IS_PARENT_CHILD(parent));
+
+ MyParentChild *self = MY_PARENT_CHILD(accessible);
+ AtkObject *parent_old = (atk_object_get_parent(accessible));
+
+ if(parent_old == parent)
+ {
+ //nothing to do because parent does not change
+ return;
+ }
+
+ //set field 'parent' in child using 'base-method'
+ atk_object_parent_class->set_parent(accessible, parent);
+
+ if(parent_old != NULL)
+ {
+ my_parent_child_remove_child((MyParentChild*)parent_old, self);
+ }
+ if(parent != NULL)
+ {
+ my_parent_child_add_child((MyParentChild*)parent, self);
+ }
+}
+
+static gint my_parent_child_get_n_children(AtkObject *accessible)
+{
+ return MY_PARENT_CHILD(accessible)->children->len;
+}
+
+static AtkObject* my_parent_child_ref_child(AtkObject *accessible, gint i)
+{
+ MyParentChild *self = MY_PARENT_CHILD(accessible);
+ if(i < 0 || i >= self->children->len)
+ {
+ printf("ref_child: Incorrect index of child.\n");
+ return NULL;
+ }
+
+ AtkObject* child = (AtkObject*)
+ g_ptr_array_index(self->children, i);
+
+ return (child == NULL) ? NULL : g_object_ref(child);
+}
+
+static gint my_parent_child_get_index_in_parent(AtkObject *accessible)
+{
+ AtkObject *parent = atk_object_get_parent(accessible);
+ if(parent == NULL) return -1;//no parent
+
+ MyParentChild *parent_my = MY_PARENT_CHILD(parent);
+
+ int i = parent_my->children->len;
+ for(; i>=0; i--)
+ {
+ if(g_ptr_array_index(parent_my->children,i) == accessible)
+ break;
+ }
+ if(i < 0)printf("Something wrong in parent-child strucutre.\n");
+ return i;//if error, i will be equal to -1
+}
+
+GType my_parent_child_get_type()
+{
+ static GType type = 0;
+ if(type == 0)
+ {
+ static const GTypeInfo typeInfo =
+ {
+ sizeof(MyParentChildClass),
+ NULL, //base_init
+ NULL, //base_finalize
+ my_parent_child_class_init, //class_init
+ NULL, //class_finalize
+ NULL, //class_data
+ sizeof(MyParentChild),
+ 0, //n_preallocs
+ my_parent_child_instance_init //instance_init
+ };
+ type = g_type_register_static(ATK_TYPE_OBJECT,"MyParentChild",&typeInfo,0);
+ }
+ return type;
+}
--- /dev/null
+#ifndef ATK_OBJECT_PARENT_CHILD_H
+#define ATK_OBJECT_PARENT_CHILD_H
+
+#include "atk/atk.h"
+
+//parent_child
+#define MY_TYPE_PARENT_CHILD (my_parent_child_get_type ())
+#define MY_PARENT_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_PARENT_CHILD, MyParentChild))
+#define MY_PARENT_CHILD_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MY_TYPE_PARENT_CHILD, MyParentChildClass))
+#define MY_IS_PARENT_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_PARENT_CHILD))
+#define MY_IS_PARENT_CHILD_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MY_TYPE_PARENT_CHILD))
+#define MY_PARENT_CHILD_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MY_TYPE_PARENT_CHILD, MyParentChildClass))
+
+typedef struct _MyParentChild MyParentChild;
+typedef struct _MyParentChildClass MyParentChildClass;
+
+struct _MyParentChild
+{
+ AtkObject parent;
+ //array of children
+ GPtrArray* children;
+};
+
+struct _MyParentChildClass
+{
+ AtkObjectClass parent;
+};
+
+GType my_parent_child_get_type();
+
+#endif /*ATK_OBJECT_PARENT_CHILD_H*/
--- /dev/null
+CFLAGS=-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/atk-1.0
+
+OBJS:=AtkObject_parent_child.o main.o MyAtkAction.o MyAtkComponent.o MyAtkImplementor.o test-simple-child.o test-simple-table.o test-simple-text.c
+
+atktest: $(OBJS)
+ $(CC) $(CFLAGS) -o$@ $^ -latk-1.0 -lglib-2.0
--- /dev/null
+#include "MyAtkAction.h"
+#include <stdio.h>
+#include <string.h>
+
+static GObjectClass *parent_class = NULL;
+//implementaion of the interface
+static gboolean my_atk_action_do_action(AtkAction *action, gint i)
+{
+ MyAtkAction *self = (MyAtkAction*)action;
+ gboolean result = (i>=0) && (i < self->n);
+ self->last_performed_action = result? i : -1;
+ return result;
+}
+static gint my_atk_action_get_n_actions(AtkAction *action)
+{
+ MyAtkAction *self = (MyAtkAction*)action;
+ return self->n;
+}
+static const gchar* my_atk_action_get_description(AtkAction *action, gint i)
+{
+ MyAtkAction *self = (MyAtkAction*)action;
+ if((i>=0) && (i<self->n))
+ {
+ return self->actions[i].description;
+ }
+ else
+ {
+ printf("get_description: Wrong index.\n");
+ return NULL;
+ }
+}
+static const gchar* my_atk_action_get_name(AtkAction *action, gint i)
+{
+ MyAtkAction *self = (MyAtkAction*)action;
+ if((i >= 0) && (i < self->n))
+ {
+ return self->actions[i].name;
+ }
+ else
+ {
+ printf("get_name: Wrong index.\n");
+ return NULL;
+ }
+}
+static const gchar* my_atk_action_get_localized_name(AtkAction *action, gint i)
+{
+ return my_atk_action_get_name(action,i);
+}
+
+static const gchar* my_atk_action_get_keybinding(AtkAction *action, gint i)
+{
+ MyAtkAction *self = (MyAtkAction*)action;
+ if((i >= 0) && (i < self->n))
+ {
+ gchar* keyb = self->actions[i].keybinding;
+ if(keyb == NULL || keybinding_note_define == NULL)
+ {
+ //anywhere(if action has keybinding or not) NULL will return
+ return NULL;
+ }
+ else
+ {
+ //verify, if string mean "no keybinding"
+ return strcmp(keyb, keybinding_note_define) != 0 ? keyb : NULL;
+ }
+ }
+ else
+ {
+ printf("get_keybinding: Wrong index.\n");
+ return NULL;
+ }
+}
+static gboolean my_atk_action_set_description(AtkAction *action, gint i, const gchar *desc)
+{
+ MyAtkAction *self = (MyAtkAction*)action;
+
+ if(!((i >= 0) && (i < self->n)) )
+ {
+ //index out of range, but this is not application error according documentation
+ return FALSE;
+ }
+ //index in correct range
+ if(self->actions[i].description == desc)
+ {
+ //self assignment - return immediately
+ return TRUE;
+ }
+ if(self->actions[i].description != NULL)
+ {
+ //free old value of description if it is not NULL
+ free(self->actions[i].description);
+ }
+ if(desc != NULL)
+ {
+ //dump new value of description if it is not NULL
+ self->actions[i].description = (gchar*)strdup((const char*)desc);
+ }
+ return TRUE;
+}
+//////////
+static void my_atk_action_instance_init(GTypeInstance *instance, gpointer g_class)
+{
+ int i;
+ MyAtkAction *self = (MyAtkAction*)instance;
+ self->n = DEFAULT_NUMBER_ACTIONS;
+ self->actions = g_new(struct OneAction, self->n);
+ if(self->actions == NULL)
+ {
+ self->n = 0;
+ return;
+ }
+ //init fields of action 0 with values which differ from others actions
+ self->actions[0].name = (gchar*)strdup(FIRST_ACTION_NAME);
+ self->actions[0].description = (gchar*)strdup(FIRST_ACTION_DESCRIPTION);
+ self->actions[0].keybinding = (gchar*)strdup(FIRST_ACTION_KEYBINDING);
+
+ for(i = 1; i < self->n; i++)
+ {
+ self->actions[i].name = (gchar*)strdup(DEFAULT_ACTION_NAME);
+ self->actions[i].description = (gchar*)strdup(DEFAULT_ACTION_DESCRIPTION);
+ self->actions[i].keybinding = (gchar*)strdup(DEFAULT_ACTION_KEYBINDING);
+ }
+ self->disposed = FALSE;
+ self->last_performed_action = -1;
+}
+
+static void
+my_atk_action_interface_init(gpointer g_iface, gpointer iface_data)
+{
+ AtkActionIface *klass = (AtkActionIface *)g_iface;
+
+ klass->do_action = my_atk_action_do_action;
+ klass->get_n_actions = my_atk_action_get_n_actions;
+ klass->get_description = my_atk_action_get_description;
+ klass->get_name = my_atk_action_get_name;
+ klass->get_localized_name = my_atk_action_get_localized_name;
+ klass->get_keybinding = my_atk_action_get_keybinding;
+ klass->set_description = my_atk_action_set_description;
+}
+
+static void
+my_atk_action_dispose(GObject *obj)
+{
+ MyAtkAction *self = (MyAtkAction*)obj;
+
+ if(self->disposed)
+ {
+ return;
+ }
+ self->disposed = TRUE;
+
+ G_OBJECT_CLASS(parent_class)->dispose(obj);
+}
+
+static void
+my_atk_action_finalize(GObject *obj)
+{
+ MyAtkAction *self = (MyAtkAction*)obj;
+ int i;
+
+ for(i = 0; i < self->n; i++)
+ {
+ struct OneAction oneAction = self->actions[i];
+ if(oneAction.name != NULL)
+ free(oneAction.name);
+ if(oneAction.description != NULL)
+ free(oneAction.description);
+ if(oneAction.keybinding != NULL)
+ free(oneAction.keybinding);
+ }
+ if(self->actions != NULL)
+ g_free(self->actions);
+
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+static void
+my_atk_action_class_init (gpointer g_class, gpointer g_class_data)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(g_class);
+ MyAtkActionClass *klass = MY_ATK_ACTION_CLASS (g_class);
+
+ gobject_class->dispose = my_atk_action_dispose;
+ gobject_class->finalize = my_atk_action_finalize;
+
+ parent_class = g_type_class_peek_parent(klass);
+}
+GType my_atk_action_get_type(void)
+{
+ static GType type = 0;
+ if(type == 0)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof (MyAtkActionClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ my_atk_action_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (MyAtkAction),
+ 0, /* n_preallocs */
+ my_atk_action_instance_init /* instance_init */
+ };
+
+ static const GInterfaceInfo iface_info =
+ {
+ (GInterfaceInitFunc) my_atk_action_interface_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "MyAtkAction",
+ &info, 0);
+ g_type_add_interface_static (type,
+ ATK_TYPE_ACTION,
+ &iface_info);
+ }
+ return type;
+}
--- /dev/null
+#ifndef MY_ATK_ACTION_H
+#define MY_ATK_ACTION_H
+//Object, which implement interface AtkAction(all functions)
+#include <glib.h>
+#include <glib-object.h>
+#include <atk/atk.h>
+
+//declarations
+#define MY_TYPE_ATK_ACTION (my_atk_action_get_type ())
+#define MY_ATK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_ATK_ACTION, MyAtkAction))
+#define MY_ATK_ACTION_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MY_TYPE_ATK_ACTION, MyAtkActionClass))
+#define MY_IS_ATK_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_ATK_ACTION))
+#define MY_IS_ATK_ACTION_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MY_TYPE_ATK_ACTION))
+#define MY_ATK_ACTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MY_TYPE_ATK_ACTION, MyAtkActionClass))
+
+static const gchar* keybinding_note_define = "none";
+
+#define FIRST_ACTION_NAME "Default action"
+#define FIRST_ACTION_DESCRIPTION "This action will be perfomed by default"
+#define FIRST_ACTION_KEYBINDING "12345"
+
+#define DEFAULT_NUMBER_ACTIONS 10
+#define DEFAULT_ACTION_NAME "Action"
+#define DEFAULT_ACTION_DESCRIPTION "Description of action"
+#define DEFAULT_ACTION_KEYBINDING keybinding_note_define
+
+
+//for external using
+#define LAST_PERFORMED_ACTION(myAtkAction) (MY_ATK_ACTION(myAtkAction)->last_performed_action)
+#define CLEAR_LAST_PERFOMED_ACTION(myAtkAction) (MY_ATK_ACTION(myAtkAction)->last_performed_action = -1
+
+typedef struct _MyAtkAction MyAtkAction;
+typedef struct _MyAtkActionClass MyAtkActionClass;
+
+struct _MyAtkAction
+{
+ GObject parent;
+
+ gboolean disposed;
+ struct OneAction
+ {
+ gchar *name;
+ gchar *description;
+ gchar *keybinding;
+ }*actions;
+ gint n;
+ gint last_performed_action;//this field is changed when perfoms action
+};
+
+struct _MyAtkActionClass
+{
+ GObjectClass parent;
+};
+GType my_atk_action_get_type(void);
+
+#endif /*MY_ATK_ACTION_H*/
--- /dev/null
+#include "MyAtkComponent.h"
+#include <stdio.h>
+
+//*************************implementation***********************
+static MyParentChildClass *component_parent_class = NULL;
+//current focus object
+static AtkComponent* focus_object = NULL;
+
+static guint focus_signal_id = 0;
+/*
+ * Because of implementation of AtkUtils, we need to ensure that list of focus_trackers
+ * is not empty. Otherwise function atk_focus_tracker_notify will not change focus.
+ */
+static guint focus_tracker_id = 0;
+static void my_event_listener(AtkObject* obj)
+{
+ //simply exist for register as focus_tracker
+}
+/*
+ * If this flag is TRUE, then focus cannot be changed until someone clears the flag
+ * via my_atk_component_set_modal(FALSE).
+ */
+static gboolean is_modal = FALSE;
+//for debug
+void print_extent(AtkRectangle *extent)
+{
+ printf("{%d,%d,%d,%d}", extent->x, extent->y, extent->width, extent->height);
+}
+//for internal use
+static void emit_bounds_changed(MyAtkComponent *component)
+{
+ static guint bounds_changed_id = 0;
+ if(bounds_changed_id == 0)
+ {
+ bounds_changed_id = g_signal_lookup("bounds-changed", ATK_TYPE_COMPONENT);
+ }
+ AtkRectangle *param = g_boxed_copy(ATK_TYPE_RECTANGLE, &(component->extent));
+ g_signal_emit(component, bounds_changed_id, 0, param);
+}
+static void change_focus(AtkComponent* component, gboolean is_gain)
+{
+ const gchar* state_name = atk_state_type_get_name(ATK_STATE_FOCUSED);
+
+ g_signal_emit_by_name(component, "focus-event", is_gain);
+ g_signal_emit_by_name(component, "state-change::focused",
+ state_name, is_gain);
+
+ AtkObject* parent = atk_object_get_parent((AtkObject*)component);
+ if(parent != NULL)
+ {
+ AtkStateSet* stateSet = atk_object_ref_state_set(parent);
+ if(atk_state_set_contains_state(stateSet, ATK_STATE_MANAGES_DESCENDANTS))
+ g_signal_emit_by_name(parent, "active-descendant-changed",
+ atk_get_focus_object());
+ g_object_unref(stateSet);
+ }
+}
+//implementation of virtual functions
+//******************ref_state_set(AtkObject)*****************************
+static AtkStateSet* my_atk_component_ref_state_set(AtkObject *object)
+{
+ MyAtkComponent *self = (MyAtkComponent*)object;
+
+ AtkStateSet* result = ((AtkObjectClass*)component_parent_class)->
+ ref_state_set(object);
+ if(self->is_manage_descendants)
+ atk_state_set_add_state(result, ATK_STATE_MANAGES_DESCENDANTS);
+ return result;
+}
+//******************get_size*******************
+static void my_atk_component_get_size(AtkComponent *component, gint *width, gint *height)
+{
+ g_return_if_fail(MY_IS_ATK_COMPONENT(component));
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ *width = self->extent.width;
+ *height = self->extent.height;
+}
+//*********************get_position*******************
+static void my_atk_component_get_position(AtkComponent *component, gint *x, gint *y, AtkCoordType coord_type)
+{
+ g_return_if_fail(MY_IS_ATK_COMPONENT(component));
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ *x = self->extent.x;
+ *y = self->extent.y;
+
+//**********************get_extents*******************
+}
+static void my_atk_component_get_extents(AtkComponent *component, gint *x, gint *y,
+ gint *width, gint *height, AtkCoordType coord_type)
+{
+ g_return_if_fail(MY_IS_ATK_COMPONENT(component));
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ *x = self->extent.x;
+ *y = self->extent.y;
+ *width = self->extent.width;
+ *height = self->extent.height;
+}
+
+//**************************set_size*******************
+static gboolean my_atk_component_set_size(AtkComponent *component, gint width, gint height)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), FALSE);
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ if(self->is_extent_may_changed)
+ {
+ self->extent.width = width;
+ self->extent.height = height;
+
+ emit_bounds_changed(self);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+//**************************set_position********************
+static gboolean my_atk_component_set_position(AtkComponent *component,
+ gint x, gint y, AtkCoordType coord_type)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), FALSE);
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ if(self->is_extent_may_changed)
+ {
+ self->extent.x = x;
+ self->extent.y = y;
+
+ emit_bounds_changed(self);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+//*************************************set_extents***************
+static gboolean my_atk_component_set_extents(AtkComponent *component,
+ gint x, gint y, gint width, gint height, AtkCoordType coord_type)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), FALSE);
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+
+ if(self->is_extent_may_changed)
+ {
+ self->extent.x = x;
+ self->extent.y = y;
+ self->extent.width = width;
+ self->extent.height = height;
+
+ emit_bounds_changed(self);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+//**************************get_layer****************
+static AtkLayer my_atk_component_get_layer(AtkComponent *component)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), ATK_LAYER_INVALID);
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ return self->layer;
+}
+//**************************get_mdi_zorder****************
+static gint my_atk_component_get_mdi_zorder(AtkComponent *component)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), G_MININT);
+
+ MyAtkComponent *self = MY_ATK_COMPONENT(component);
+ return self->zorder;
+}
+//***********************contains**********************
+static gboolean my_atk_component_contains(AtkComponent *component,
+ gint x, gint y, AtkCoordType coord_type)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), FALSE);
+ //for extract extent
+ gint x_tmp, y_tmp, width_tmp, height_tmp;
+ my_atk_component_get_extents(component, &x_tmp, &y_tmp, &width_tmp, &height_tmp, coord_type);
+
+ if( (x >= x_tmp) &&(y >= y_tmp) &&(x < x_tmp + width_tmp) && (y < y_tmp + height_tmp) )
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+//**********************ref_accessible_at_point***********************
+/*
+ * Retuns accessible child that implements AtkCOmponent and contains the given point.
+ */
+static AtkObject* my_atk_component_ref_accessible_at_point(AtkComponent* component,
+ gint x, gint y, AtkCoordType coord_type)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component), NULL);
+ gint i;
+
+ gint n_children = atk_object_get_n_accessible_children((AtkObject*)component);
+ for(i = 0; i < n_children; i++)
+ {
+ AtkObject *child = atk_object_ref_accessible_child((AtkObject*)component, i);
+ if(ATK_IS_COMPONENT(child)
+ && atk_component_contains((AtkComponent*)child, x, y, coord_type))
+ {
+ return child;
+ }
+ g_object_unref(child);
+ }
+ return NULL;
+}
+//*************************************grab_focus*********************************
+static gboolean my_atk_component_grab_focus(AtkComponent* component)
+{
+ if(component == focus_object)
+ {
+ //Already has focus
+ return TRUE;
+ }
+ if(is_modal)
+ {
+ //cannot grab focus
+ return FALSE;
+ }
+ AtkComponent *focus_object_old = focus_object;
+ focus_object = component;
+
+ atk_focus_tracker_notify((AtkObject*)component);
+
+ if(focus_object_old != NULL)
+ {
+ //signals for object which lost focus
+ change_focus(focus_object_old, FALSE);
+ }
+ if(component != NULL)
+ {
+ //signals for object which grab focus
+ change_focus(component, TRUE);
+ }
+ return TRUE;
+}
+//***********************my_atk_component_add_focus_handler*********************
+static guint my_atk_component_add_focus_handler(AtkComponent *component, AtkFocusHandler handler)
+{
+ g_return_val_if_fail(MY_IS_ATK_COMPONENT(component),0);
+ //verify whether handler already connect to object
+ gulong found_handler_id = g_signal_handler_find(component,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ focus_signal_id,
+ 0,
+ NULL,
+ (gpointer)handler,
+ NULL);
+ if(found_handler_id == 0)
+ {
+ //handler hasn't been connected yet
+ return g_signal_connect_closure_by_id(component,
+ focus_signal_id,
+ 0,
+ g_cclosure_new( (GCallback)handler,
+ NULL,
+ NULL),
+ NULL);
+ }
+ else/* found_handler_id != 0*/
+ {
+ //handler has already been connected
+ return 0;
+ }
+
+}
+//***********************my_atk_component_remove_focus_handler*********************
+static void my_atk_component_remove_focus_handler(AtkComponent *component, guint handler_id)
+{
+ g_signal_handler_disconnect(component, handler_id);
+}
+//***********************my_atk_component_set_modal(my function)***************
+void my_atk_component_set_modal(gboolean value)
+{
+ is_modal = value;
+}
+//******************my_atk_component_set_manage_descendants(my_function)*******
+void my_atk_component_set_manage_descendants(MyAtkComponent* component, gboolean value)
+{
+ if(component->is_manage_descendants == value)return;
+ component->is_manage_descendants = value;
+ g_signal_emit_by_name(component, "state-change::manages-descendants",
+ "manages-descendants", value);
+}
+//Others funtions
+static void my_atk_component_instance_init(GTypeInstance *obj, gpointer g_class)
+{
+ MyAtkComponent *self = (MyAtkComponent*)obj;
+ //set defaults values
+ self->extent.x = 0;
+ self->extent.y = 0;
+ self->extent.width = 10;
+ self->extent.height = 10;
+ self->is_extent_may_changed = TRUE;
+ self->layer = ATK_LAYER_INVALID;
+ self->zorder = -2147483648;
+}
+static void my_atk_component_instance_finalize(GObject* obj)
+{
+ MyAtkComponent* component = (MyAtkComponent*)obj;
+
+ if(((AtkObject*)component) == atk_get_focus_object())
+ {
+ atk_focus_tracker_notify(NULL);
+ }
+}
+
+static void my_atk_component_class_init(gpointer g_class, gpointer class_data)
+{
+ GObjectClass* g_object_class = (GObjectClass*)g_class;
+ AtkObjectClass* atkObject_class = (AtkObjectClass*)g_class;
+ //GObject virtual table
+ g_object_class->finalize = my_atk_component_instance_finalize;
+ //AtkObject virtual table
+ atkObject_class->ref_state_set = my_atk_component_ref_state_set;
+ //parent_class
+ component_parent_class = g_type_class_peek_parent(g_class);
+ //make focus_tracker's table not empty.
+ focus_tracker_id = atk_add_focus_tracker(my_event_listener);
+ //store "focus-event"-signal id
+ focus_signal_id = g_signal_lookup("focus-event",MY_TYPE_ATK_COMPONENT);
+}
+/*
+ * Though, according to the documentation, this function will never called for
+ * static-registred types.
+ * Base_init function doesn't suite for this work,
+ * because it will called in every derived classes.
+ */
+/*static void my_atk_component_class_finalize(gpointer g_class, gpointer class_data)
+{
+
+ if(focus_tracker_id != 0)
+ {
+ atk_remove_focus_tracker(focus_tracker_id);
+ focus_tracker_id = 0;
+ }
+}*/
+static void my_atk_component_interface_init(gpointer g_iface, gpointer iface_data)
+{
+ AtkComponentIface *klass = (AtkComponentIface*)g_iface;
+
+ klass->get_extents = my_atk_component_get_extents;
+ klass->get_position = my_atk_component_get_position;
+ klass->get_size = my_atk_component_get_size;
+
+ klass->set_extents = my_atk_component_set_extents;
+ klass->set_position = my_atk_component_set_position;
+ klass->set_size = my_atk_component_set_size;
+
+ klass->contains = my_atk_component_contains;
+ klass->ref_accessible_at_point = my_atk_component_ref_accessible_at_point;
+
+ klass->get_layer = my_atk_component_get_layer;
+ klass->get_mdi_zorder = my_atk_component_get_mdi_zorder;
+
+ klass->grab_focus = my_atk_component_grab_focus;
+ klass->add_focus_handler = my_atk_component_add_focus_handler;
+ klass->remove_focus_handler = my_atk_component_remove_focus_handler;
+}
+
+GType my_atk_component_get_type()
+{
+ static GType type = 0;
+ if(type == 0)
+ {
+ static const GTypeInfo typeInfo =
+ {
+ sizeof(MyAtkComponentClass),
+ NULL, //base_init
+ NULL, //base_finalize
+ my_atk_component_class_init, //class_init
+ NULL, //class_finalize
+ NULL, //class_data
+ sizeof(MyAtkComponent),
+ 0, //n_preallocs
+ my_atk_component_instance_init //instance_init
+ };
+
+ static const GInterfaceInfo iface_info =
+ {
+ my_atk_component_interface_init, /* interface_init*/
+ NULL, /* interface_finalize*/
+ NULL /* interface_data */
+ };
+ type = g_type_register_static(MY_TYPE_PARENT_CHILD, "MyAtkComponent", &typeInfo, 0);
+ g_type_add_interface_static(type,
+ ATK_TYPE_COMPONENT,
+ &iface_info);
+ }
+ return type;
+}
--- /dev/null
+#ifndef MY_ATK_COMPONENT_H
+#define MY_ATK_COMPONENT_H
+/*
+ * MyAtkComponent: derives AtkObject(with parent-child accessibilities)
+ * and implements AtkComponent.
+ */
+#include <atk/atk.h>
+#include <glib-object.h>
+#include <limits.h>
+
+#include "AtkObject_parent_child.h"
+
+#define MY_TYPE_ATK_COMPONENT (my_atk_component_get_type ())
+#define MY_ATK_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_ATK_COMPONENT, MyAtkComponent))
+#define MY_ATK_COMPONENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MY_TYPE_ATK_COMPONENT, MyAtkComponentClass))
+#define MY_IS_ATK_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_ATK_COMPONENT))
+#define MY_IS_ATK_COMPONENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MY_TYPE_ATK_COMPONENT))
+#define MY_ATK_COMPONENT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MY_TYPE_ATK_COMPONENT, MyAtkComponentClass))
+
+typedef struct _MyAtkComponent MyAtkComponent;
+typedef struct _MyAtkComponentClass MyAtkComponentClass;
+
+struct _MyAtkComponent
+{
+ MyParentChild parent;
+ //relative coordinates, which coincides with absolute ones
+ AtkRectangle extent;
+ //whether component may be relocated
+ gboolean is_extent_may_changed;
+ //for emit "active-descendant-changed" signal
+ gboolean is_manage_descendants;
+ //
+ AtkLayer layer;
+ gint zorder;
+};
+
+struct _MyAtkComponentClass
+{
+ MyParentChildClass parent;
+};
+
+GType my_atk_component_get_type();
+#endif /*MY_ATK_COMPONENT_H*/
--- /dev/null
+#include "MyAtkImplementor.h"
+
+//implementaion
+static GObjectClass *parent_class = NULL;
+
+static AtkObject* my_atk_implementor_ref_accessible(AtkImplementor *implementor)
+{
+ AtkObject *result = ((MyAtkImplementor*)implementor)->accessible;
+ g_object_ref((GObject*)result);
+ return result;
+}
+
+static void my_atk_implementor_instance_init(GTypeInstance *instance, gpointer g_class)
+{
+ MyAtkImplementor *self = (MyAtkImplementor*)instance;
+
+ self->accessible = ATK_OBJECT(g_object_new(ATK_TYPE_OBJECT,NULL));
+ self->is_disposed = FALSE;
+}
+
+static void my_atk_implementor_interface_init(gpointer g_iface,gpointer iface_data)
+{
+ AtkImplementorIface *iface = ((AtkImplementorIface*)g_iface);
+ iface->ref_accessible = my_atk_implementor_ref_accessible;
+}
+
+static void my_atk_implementor_dispose(GObject *obj)
+{
+ MyAtkImplementor *self = (MyAtkImplementor*)obj;
+ if(!self->is_disposed)
+ {
+ g_object_unref(self->accessible);
+ self->is_disposed = TRUE;
+ }
+ parent_class->dispose(obj);
+}
+
+static void my_atk_implementor_class_init(gpointer g_class,gpointer g_data)
+{
+ MyAtkImplementorClass *klass = MY_ATK_IMPLEMENTOR_CLASS(g_class);
+ parent_class = g_type_class_peek_parent(klass);
+}
+
+GType my_atk_implementor_get_type(void)
+{
+ static GType type = 0;
+ if(type == 0)
+ {
+ static const GTypeInfo typeinfo = {
+ sizeof(MyAtkImplementorClass),
+ NULL, /*base_init */
+ NULL, /*base_finalize */
+ my_atk_implementor_class_init,/*class_init*/
+ NULL, /*class_finalize*/
+ NULL,/*class_data*/
+ sizeof(MyAtkImplementor),
+ 0, /*n_prealloc*/
+ my_atk_implementor_instance_init/* instance_init*/
+ };
+ type = g_type_register_static(G_TYPE_OBJECT,"MyAtkImplementor",&typeinfo,0);
+ static const GInterfaceInfo interface_info =
+ {
+ my_atk_implementor_interface_init, /*interface_init*/
+ NULL, /*interface_finalize*/
+ NULL, /*interface_data*/
+ };
+ g_type_add_interface_static(type, ATK_TYPE_IMPLEMENTOR,&interface_info);
+ }
+ return type;
+}
--- /dev/null
+#ifndef MY_ATK_IMPLEMENTOR_H
+#define MY_ATK_IMPLEMENTOR_H
+
+#include <atk/atk.h>
+
+#define MY_TYPE_ATK_IMPLEMENTOR (my_atk_implementor_get_type ())
+#define MY_ATK_IMPLEMENTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_ATK_IMPLEMENTOR, MyAtkImplementor))
+#define MY_ATK_IMPLEMENTOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), MY_TYPE_ATK_IMPLEMENTOR, MyAtkImplementorClass))
+#define MY_IS_ATK_IMPLEMENTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_ATK_IMPLEMENTOR))
+#define MY_IS_ATK_IMPLEMENTOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MY_TYPE_ATK_IMPLEMENTOR))
+#define MY_ATK_IMPLEMENTOR_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), MY_TYPE_ATK_IMPLEMENTOR, MyAtkImplementorClass))
+
+
+typedef struct _MyAtkImplementor MyAtkImplementor;
+typedef struct _MyAtkImplementorClass MyAtkImplementorClass;
+
+struct _MyAtkImplementor
+{
+ GObject parent;
+ AtkObject *accessible;
+ gboolean is_disposed;
+};
+struct _MyAtkImplementorClass
+{
+ GObjectClass parent;
+};
+
+GType my_atk_implementor_get_type();
+#endif /*MY_ATK_IMPLEMETOR_H*/
--- /dev/null
+#ifndef TEST_HELLO_H
+#include "gmodule.h"
+#include <atk/atk.h>
+
+G_BEGIN_DECLS
+
+#define TEST_TYPE_HELLO (test_hello_get_type ())
+#define TEST_HELLO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TEST_TYPE_HELLO, test_hello))
+#define IS_TEST_HELLO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TEST_TYPE_HELLO))
+#define IS_TEST_HELLO_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TEST_TYPE_HELLO))
+#define TEST_HELLO_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TEST_TYPE_HELLO, AtkObjectClass))
+
+ /* forward declarations */
+typedef struct _test_helloClass test_helloClass;
+
+typedef struct test_hello test_hello;
+struct test_hello
+{
+ AtkObject parent;
+};
+
+struct _test_helloClass
+{
+ AtkObjectClass parent_class;
+};
+
+GType test_hello_get_type();
+
+G_END_DECLS
+#endif /* TEST_HELLO_H */
--- /dev/null
+#include "atk/atk.h"
+#include "hello.h"
+#include "test-simple-table.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+static AtkObject *root;
+static GList *children;
+
+gboolean quit(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ //g_signal_emit_by_name(root, "children-changed::remove", child);
+ tcsetattr(0, TCSAFLUSH, data);
+ exit(0);
+}
+
+
+// our parent class
+static AtkObjectClass *parent_class = NULL;
+
+/**************************************************************************/
+/**************************************************************************/
+
+#define GET_CLASS(instance) G_TYPE_INSTANCE_GET_CLASS (instance, AP_DOCVIEW_TYPE, ApDocViewClass)
+
+static gint test_hello_get_n_children(AtkObject * obj)
+{
+printf("get n children: %p\n", obj);
+ if (obj == root) return g_list_length(children);
+ return 0;
+}
+
+static AtkStateSet *test_hello_ref_state_set(AtkObject * accessible)
+{
+ AtkStateSet *state_set;
+
+ state_set = ATK_OBJECT_CLASS(parent_class)->ref_state_set(accessible);
+ //atk_state_set_remove_state(state_set, ATK_STATE_FOCUSABLE);
+
+ return state_set;
+}
+
+static void test_hello_real_initialize(AtkObject * obj, gpointer data)
+{
+ ATK_OBJECT_CLASS(parent_class)->initialize(obj, data);
+ printf("Initialize: %p\n", obj);
+}
+
+static void test_hello_finalize(AtkObject * obj)
+{
+ printf("Finalizing: %p\n", obj);
+}
+
+static AtkObject *test_hello_ref_child(AtkObject * obj, gint i)
+{
+ gpointer data;
+ printf("ref child: %p, index %d\n", obj, i);
+ if (obj != root) return NULL;
+ data = g_list_nth_data(children, i);
+ if (data) return ATK_OBJECT(data);
+ return NULL;
+}
+
+static void test_hello_class_init(test_helloClass * klass)
+{
+ AtkObjectClass *atk_class = ATK_OBJECT_CLASS(klass);
+
+ parent_class = (AtkObjectClass *) g_type_class_peek_parent(klass);
+ atk_class->ref_state_set = test_hello_ref_state_set;
+ atk_class->get_n_children = test_hello_get_n_children;
+ atk_class->ref_child = test_hello_ref_child;
+ atk_class->initialize = test_hello_real_initialize;
+}
+
+static gint test_hello_get_caret_offset(AtkText * text)
+{
+ test_hello *obj = TEST_HELLO(text);
+ return 0;
+}
+
+static void atk_text_interface_init (AtkTextIface * iface)
+{
+ g_return_if_fail (iface != NULL);
+ iface->get_caret_offset = test_hello_get_caret_offset;
+}
+
+GType test_hello_get_type(void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo tinfo = {
+ sizeof(test_helloClass),
+ (GBaseInitFunc) NULL, /* base init */
+ (GBaseFinalizeFunc) test_hello_finalize, /* base finalize */
+ (GClassInitFunc) test_hello_class_init, /* class init */
+ (GClassFinalizeFunc) NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof(test_hello), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_text_info = {
+ (GInterfaceInitFunc) atk_text_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+#if 0
+ /* Following code would use the factory to fetch the parent type
+ * based on the atk type associated with GTK_TYPE_WIDGET */
+ GType parent_type;
+ AtkObjectFactory *factory;
+
+ factory =
+ atk_registry_get_factory(atk_get_default_registry(),
+ GTK_TYPE_WIDGET);
+ parent_type = atk_object_factory_get_accessible_type(factory);
+#endif
+
+ type = g_type_register_static(atk_object_get_type(),
+ "test_hello", &tinfo, (GTypeFlags) 0);
+ g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info);
+ }
+ return type;
+}
+static AtkObject *get_root()
+{
+ return root;
+}
+
+static void add_child(AtkObject *child)
+{
+ if (!child) return;
+ children = g_list_append(children, child);
+ g_signal_emit_by_name(root, "children-changed::add", child);
+}
+
+main(int argc, char *argv[])
+{
+ AtkUtilClass *klass;
+ GMainLoop *mainloop;
+ GIOChannel *stdin_channel;
+ struct termios termios, rt;
+ GModule *bridge;
+ void (*gnome_accessibility_module_init)();
+ AtkObject *table;
+
+ g_type_init();
+ klass = g_type_class_ref(ATK_TYPE_UTIL);
+ klass->get_root = get_root;
+ g_type_class_unref(klass);
+ root = g_object_new(TEST_TYPE_HELLO, NULL);
+ table = ATK_OBJECT(g_object_new(TEST_TYPE_SIMPLE_TABLE, NULL));
+ add_child(table);
+ /* The below line isn't really right -- normally gtk will build the path */
+ bridge = g_module_open("/usr/lib/gtk-2.0/modules/libatk-bridge.so", G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
+ if (!bridge)
+ {
+ fprintf(stderr, "Couldn't load atk-bridge.so\n");
+ exit(1);
+ }
+ if (!g_module_symbol(bridge, "gnome_accessibility_module_init", (gpointer *)&gnome_accessibility_module_init))
+ {
+ fprintf(stderr, "Couldn't find gnome_accessibility_module_init\n"); exit(1);
+ }
+ (*gnome_accessibility_module_init)();
+ atk_object_set_name(root, "root object");
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ /* Make stdin "raw" so that we will see a key immediately */
+ tcgetattr(0, &termios);
+ rt = termios;
+ cfmakeraw(&rt);
+ tcsetattr(0, TCSAFLUSH, &rt);
+ /* Set a watch on stdin so that we'll know when a key is pressed */
+ stdin_channel = g_io_channel_unix_new(0);
+ g_io_add_watch(stdin_channel, G_IO_IN, quit, &termios);
+
+ g_main_loop_run (mainloop);
+ return 0;
+}
--- /dev/null
+/* This file contains both declaration and definition of the TestSimpleChild class
+ * derived from AtkObject. The TestSimpleChild instances can be used as children by
+ * the TestSimpleSelection and TestSimpleTable instances.
+ */
+
+#include "test-simple-child.h"
+
+GType
+test_simple_child_get_type (void);
+
+static GObjectClass *parent_class_simple_child = NULL;
+
+/******************************************************************/
+/* Implementation */
+/******************************************************************/
+static void
+simple_child_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+ TestSimpleChild *self = (TestSimpleChild *)instance;
+
+ self->disposed = FALSE;
+ self->id = -1; /* invalid ID value by default */
+}
+
+static void
+test_simple_child_dispose (GObject *obj)
+{
+ TestSimpleChild *self = (TestSimpleChild *)obj;
+
+ if (self->disposed)
+ {
+ return;
+ }
+
+ /* Make sure dispose does not run twice. */
+ self->disposed = TRUE;
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class_simple_child)->dispose (obj);
+}
+
+static void
+test_simple_child_finalize (GObject *obj)
+{
+ TestSimpleChild *self = (TestSimpleChild *)obj;
+ if (self)
+ {
+ /*free (self->pdata->descr);
+ g_free (self->pdata);*/
+ }
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class_simple_child)->finalize (obj);
+}
+
+static void
+test_simple_child_class_init (gpointer g_class, gpointer g_class_data)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
+ TestSimpleChildClass *klass = TEST_SIMPLE_CHILD_CLASS (g_class);
+
+ gobject_class->dispose = test_simple_child_dispose;
+ gobject_class->finalize = test_simple_child_finalize;
+
+ parent_class_simple_child = g_type_class_peek_parent (klass);
+}
+
+GType
+test_simple_child_get_type (void)
+{
+ static GType type = 0;
+ if (type == 0)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof (TestSimpleChildClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ test_simple_child_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TestSimpleChild),
+ 0, /* n_preallocs */
+ simple_child_instance_init /* instance_init */
+ };
+
+ type = g_type_register_static (ATK_TYPE_OBJECT,
+ "TestSimpleChildType",
+ &info, 0);
+ }
+ return type;
+}
--- /dev/null
+/* This file contains both declaration and definition of the TestSimpleChild class
+ * derived from AtkObject. The TestSimpleChild instances can be used as children by
+ * the TestSimpleSelection and TestSimpleTable instances.
+ */
+
+#ifndef TESTSIMPLECHILD_H_
+#define TESTSIMPLECHILD_H_
+#include <glib-object.h>
+#include <atk/atk.h>
+
+#define TEST_TYPE_SIMPLE_CHILD (test_simple_child_get_type ())
+#define TEST_SIMPLE_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_SIMPLE_CHILD, TestSimpleChild))
+#define TEST_SIMPLE_CHILD_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), TEST_TYPE_SIMPLE_CHILD, TestSimpleChildClass))
+#define TEST_IS_SIMPLE_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_SIMPLE_CHILD))
+#define TEST_IS_SIMPLE_CHILD_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), TEST_TYPE_SIMPLE_CHILD))
+#define TEST_SIMPLE_CHILD_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), TEST_TYPE_SIMPLE_CHILD, TestSimpleChildClass))
+
+typedef struct _TestSimpleChild TestSimpleChild;
+typedef struct _TestSimpleChildClass TestSimpleChildClass;
+
+struct _TestSimpleChild
+{
+ AtkObject parent;
+ gboolean disposed;
+ gint id; /* unique object ID */
+};
+
+struct _TestSimpleChildClass
+{
+ AtkObjectClass parent;
+};
+
+#endif /*TESTSIMPLECHILD_H_*/
--- /dev/null
+/* This file contains both declaration and definition of the TestSimpleTable,
+ * a GObject that pretends to implement the AtkTableIface interface (it
+ * registers appropriate interface), but provides no implementation for any of the
+ * methods of this interface (NULL-filled vftbl).
+ */
+
+#include "test-simple-table.h"
+
+#include <stdio.h>
+#include <string.h>
+
+GType
+test_simple_table_get_type (void);
+
+///////////////////////////////////////////////////////////////////////////
+// Helper functions and data
+///////////////////////////////////////////////////////////////////////////
+
+// row/column selection schemes
+gboolean ss_rows_none[NROWS] = {FALSE, FALSE, FALSE, FALSE};
+gboolean ss_rows_02[NROWS] = {TRUE, FALSE, TRUE, FALSE};
+
+gboolean ss_cols_none[NCOLS] = {FALSE, FALSE, FALSE, FALSE, FALSE};
+gboolean ss_cols_24[NCOLS] = {FALSE, FALSE, TRUE, FALSE, TRUE};
+
+// Select table rows or columns according to the specified selection scheme.
+// TRUE means 'selected', FALSE - 'not selected'.
+void
+test_simple_table_select_rows (TestSimpleTable* table, gboolean sel_scheme[])
+{
+ int i;
+ for (i = 0; i < NROWS; ++i)
+ {
+ table->row[i].selected = sel_scheme[i];
+ }
+}
+
+void
+test_simple_table_select_columns (TestSimpleTable* table, gboolean sel_scheme[])
+{
+ int i;
+ for (i = 0; i < NCOLS; ++i)
+ {
+ table->col[i].selected = sel_scheme[i];
+ }
+}
+
+// Reset row and column headers to their default values
+void
+test_simple_table_reset_headers (TestSimpleTable* table)
+{
+ int i, j;
+
+ // initialize row and column descriptors
+ for (i = 0; i < NROWS; ++i)
+ {
+ sprintf (TEST_SIMPLE_TEXT (table->row[i].hdr)->text, DEF_ROW_DESCR_TPL, i);
+ }
+
+ for (j = 0; j < NCOLS; ++j)
+ {
+ sprintf (TEST_SIMPLE_TEXT (table->col[j].hdr)->text, DEF_COL_DESCR_TPL, j);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Implementation
+///////////////////////////////////////////////////////////////////////////
+static GObjectClass *parent_class_simple_table = NULL;
+
+static AtkObject*
+test_simple_table_ref_at (AtkTable *table, gint row, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ if ((row >=0) && (row < self->nrows) &&
+ (column >= 0) && (column < self->ncols))
+ {
+ return ATK_OBJECT (self->tbl[row][column].elem);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static gint
+test_simple_table_get_index_at (AtkTable *table, gint row, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return -1;
+ }
+
+ if ((row >=0) && (row < self->nrows) &&
+ (column >= 0) && (column < self->ncols))
+ {
+ // non-child objects have ID=-1 by default.
+ return (self->tbl[row][column].elem->id);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static gint
+test_simple_table_get_column_at_index (AtkTable *table, gint index_)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return -1;
+ }
+
+ int i, j;
+ for (i = 0; i < self->nrows; ++i)
+ {
+ for (j = 0; j < self->ncols; ++j)
+ {
+ if (self->tbl[i][j].elem->id == index_)
+ {
+ return j;
+ }
+ }
+ }
+
+ return -1;
+}
+
+static gint
+test_simple_table_get_row_at_index (AtkTable *table, gint index_)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return -1;
+ }
+
+ if (index_ < 0)
+ {
+ return -1;
+ }
+
+ int i, j;
+ for (i = 0; i < self->nrows; ++i)
+ {
+ for (j = 0; j < self->ncols; ++j)
+ {
+ if (self->tbl[i][j].elem->id == index_)
+ {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+static gint
+test_simple_table_get_n_columns (AtkTable *table)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return 0;
+ }
+
+ return self->ncols;
+}
+
+static gint
+test_simple_table_get_n_rows (AtkTable *table)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return 0;
+ }
+
+ return self->nrows;
+}
+
+static gint
+test_simple_table_get_column_extent_at (AtkTable *table, gint row, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return 0;
+ }
+
+ if ((row >=0) && (row < self->nrows) &&
+ (column >= 0) && (column < self->ncols))
+ {
+ return (self->tbl[row][column].ext_col);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static gint
+test_simple_table_get_row_extent_at (AtkTable *table, gint row, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return 0;
+ }
+
+ if ((row >=0) && (row < self->nrows) &&
+ (column >= 0) && (column < self->ncols))
+ {
+ return (self->tbl[row][column].ext_row);
+ }
+ else
+ {
+ return 0;
+ }
+
+ return 0;
+}
+
+static AtkObject*
+test_simple_table_get_caption (AtkTable *table)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ return (self->caption);
+}
+
+static const gchar*
+test_simple_table_get_column_description (AtkTable *table, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ if ((column < 0) || (column >= self->ncols))
+ {
+ return NULL;
+ }
+
+ return TEST_SIMPLE_TEXT (self->col[column].hdr)->text;
+}
+
+static AtkObject*
+test_simple_table_get_column_header (AtkTable *table, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ if ((column < 0) || (column >= self->ncols))
+ {
+ return NULL;
+ }
+
+ return (self->col[column].hdr);
+}
+
+static const gchar*
+test_simple_table_get_row_description (AtkTable *table, gint row)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ if ((row < 0) || (row >= self->nrows))
+ {
+ return NULL;
+ }
+
+ return TEST_SIMPLE_TEXT (self->row[row].hdr)->text;
+}
+
+static AtkObject*
+test_simple_table_get_row_header (AtkTable *table, gint row)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ if ((row < 0) || (row >= self->nrows))
+ {
+ return NULL;
+ }
+
+ return (self->row[row].hdr);
+}
+
+static AtkObject*
+test_simple_table_get_summary (AtkTable *table)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return NULL;
+ }
+
+ return (self->summary);
+}
+
+static void
+test_simple_table_set_caption (AtkTable *table, AtkObject *caption)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed || !caption)
+ {
+ return;
+ }
+
+ // unref the old caption
+ g_object_unref (G_OBJECT (self->caption));
+
+ // and replace it with a new one
+ self->caption = caption;
+ g_object_ref (G_OBJECT (self->caption));
+ return;
+}
+
+static void
+test_simple_table_set_column_description (AtkTable *table, gint column, const gchar *description)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return;
+ }
+
+ if ((column < 0) || (column >= self->ncols) || !description)
+ {
+ return;
+ }
+
+ strncpy (TEST_SIMPLE_TEXT (self->col[column].hdr)->text, description, MAX_DESCR_LENGTH);
+ return;
+}
+
+static void
+test_simple_table_set_column_header (AtkTable *table, gint column, AtkObject *header)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return;
+ }
+
+ if ((column < 0) || (column >= self->ncols) || !header)
+ {
+ return;
+ }
+
+ // unref old header
+ g_object_unref (G_OBJECT (self->col[column].hdr));
+
+ // and replace it with a new one
+ g_object_ref (G_OBJECT (header));
+ self->col[column].hdr = header;
+ return;
+}
+
+static void
+test_simple_table_set_row_description (AtkTable *table, gint row, const gchar *description)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return;
+ }
+
+ if ((row < 0) || (row >= self->nrows) || !description)
+ {
+ return;
+ }
+
+ strncpy (TEST_SIMPLE_TEXT (self->row[row].hdr)->text, description, MAX_DESCR_LENGTH);
+ return;
+}
+
+static void
+test_simple_table_set_row_header (AtkTable *table, gint row, AtkObject *header)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return;
+ }
+
+ if ((row < 0) || (row >= self->nrows) || !header)
+ {
+ return;
+ }
+
+ // unref old header
+ g_object_unref (G_OBJECT (self->row[row].hdr));
+
+ // and replace it with a new one
+ g_object_ref (G_OBJECT (header));
+ self->row[row].hdr = header;
+
+ return;
+}
+
+static void
+test_simple_table_set_summary (AtkTable *table, AtkObject *accessible)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed || !accessible)
+ {
+ return;
+ }
+
+ // unref the old summary
+ g_object_unref (G_OBJECT (self->summary));
+
+ // and replace it with a new one
+ self->summary = accessible;
+ g_object_ref (G_OBJECT (self->summary));
+ return;
+}
+
+static gint
+test_simple_table_get_selected_columns (AtkTable *table, gint **selected)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed || !selected)
+ {
+ return 0;
+ }
+
+ // count the selected columns
+ int i;
+ int nsel = 0;
+ for (i = 0; i < self->ncols; ++i)
+ {
+ if (self->col[i].selected)
+ {
+ ++nsel;
+ }
+ }
+
+ if (nsel > 0)
+ {
+ // store the indexes of the selected columns
+ int pos = 0;
+ *selected = g_new (gint, nsel);
+ for (i = 0; i < self->ncols; ++i)
+ {
+ if (self->col[i].selected)
+ {
+ (*selected)[pos] = i;
+ ++pos;
+ }
+ } // end for i
+ }
+
+ return nsel;
+}
+
+static gint
+test_simple_table_get_selected_rows (AtkTable *table, gint **selected)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed || !selected)
+ {
+ return 0;
+ }
+
+ // count the selected rows
+ int i;
+ int nsel = 0;
+ for (i = 0; i < self->nrows; ++i)
+ {
+ if (self->row[i].selected)
+ {
+ ++nsel;
+ }
+ }
+
+ if (nsel > 0)
+ {
+ // store the indexes of the selected rows
+ int pos = 0;
+ *selected = g_new (gint, nsel);
+ for (i = 0; i < self->nrows; ++i)
+ {
+ if (self->row[i].selected)
+ {
+ (*selected)[pos] = i;
+ ++pos;
+ }
+ } // end for i
+ }
+
+ return nsel;
+}
+
+static gboolean
+test_simple_table_is_column_selected (AtkTable *table, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ if ((column < 0) || (column >= self->ncols))
+ {
+ return FALSE;
+ }
+
+ return self->col[column].selected;
+}
+
+static gboolean
+test_simple_table_is_row_selected (AtkTable *table, gint row)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ if ((row < 0) || (row >= self->nrows))
+ {
+ return FALSE;
+ }
+
+ return self->row[row].selected;
+}
+
+static gboolean
+test_simple_table_is_selected (AtkTable *table, gint row, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ if ((row < 0) || (row >= self->nrows) ||
+ (column < 0) || (column >= self->ncols))
+ {
+ return FALSE;
+ }
+
+ // In this implementation a cell is selected if and only if the
+ // corresponding row and column are both selected.
+
+ return (self->row[row].selected && self->col[column].selected);
+}
+
+static gboolean
+test_simple_table_add_row_selection (AtkTable *table, gint row)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ if ((row < 0) || (row >= self->nrows))
+ {
+ return FALSE;
+ }
+
+ gboolean was_selected = self->row[row].selected;
+ self->row[row].selected = TRUE;
+ return !was_selected;
+}
+
+static gboolean
+test_simple_table_remove_row_selection (AtkTable *table, gint row)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ gboolean was_selected = self->row[row].selected;
+ self->row[row].selected = FALSE;
+ return was_selected;
+}
+
+static gboolean
+test_simple_table_add_column_selection (AtkTable *table, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ if ((column < 0) || (column >= self->ncols))
+ {
+ return FALSE;
+ }
+
+ gboolean was_selected = self->col[column].selected;
+ self->col[column].selected = TRUE;
+ return !was_selected;
+}
+
+static gboolean
+test_simple_table_remove_column_selection (AtkTable *table, gint column)
+{
+ TestSimpleTable* self = (TestSimpleTable*)table;
+ if ((!self) || self->disposed)
+ {
+ return FALSE;
+ }
+
+ gboolean was_selected = self->col[column].selected;
+ self->col[column].selected = FALSE;
+ return was_selected;
+}
+
+// Signal emitters
+// "column-deleted"
+static void
+emit_column_deleted (TestSimpleTable* table, gint arg1, gint arg2)
+{
+ g_signal_emit_by_name ((gpointer)table, "column-deleted", arg1, arg2);
+ return;
+}
+
+// "column-inserted"
+static void
+emit_column_inserted (TestSimpleTable* table, gint arg1, gint arg2)
+{
+ g_signal_emit_by_name ((gpointer)table, "column-inserted", arg1, arg2);
+ return;
+}
+
+// "column-reordered"
+static void
+emit_column_reordered (TestSimpleTable* table)
+{
+ g_signal_emit_by_name ((gpointer)table, "column-reordered");
+ return;
+}
+
+// "model-changed"
+static void
+emit_model_changed (TestSimpleTable* table)
+{
+ g_signal_emit_by_name ((gpointer)table, "model-changed");
+ return;
+}
+
+// "row-deleted"
+static void
+emit_row_deleted (TestSimpleTable* table, gint arg1, gint arg2)
+{
+ g_signal_emit_by_name ((gpointer)table, "row-deleted", arg1, arg2);
+ return;
+}
+
+// "row-inserted"
+static void
+emit_row_inserted (TestSimpleTable* table, gint arg1, gint arg2)
+{
+ g_signal_emit_by_name ((gpointer)table, "row-inserted", arg1, arg2);
+ return;
+}
+
+// "row-reordered"
+static void
+emit_row_reordered (TestSimpleTable* table)
+{
+ g_signal_emit_by_name ((gpointer)table, "row-reordered");
+ return;
+}
+
+
+/******************************************************************/
+static void
+simple_table_interface_init (gpointer g_iface, gpointer iface_data)
+{
+ AtkTableIface *klass = (AtkTableIface *)g_iface;
+
+ /* set up overrides here */
+ klass-> ref_at =
+ (AtkObject* (*) (AtkTable *table, gint row, gint column)) test_simple_table_ref_at;
+ klass-> get_index_at =
+ (gint (*) (AtkTable *table, gint row, gint column)) test_simple_table_get_index_at;
+ klass-> get_column_at_index =
+ (gint (*) (AtkTable *table, gint index_)) test_simple_table_get_column_at_index;
+ klass-> get_row_at_index =
+ (gint (*) (AtkTable *table, gint index_)) test_simple_table_get_row_at_index;
+ klass-> get_n_columns =
+ (gint (*) (AtkTable *table)) test_simple_table_get_n_columns;
+ klass-> get_n_rows =
+ (gint (*) (AtkTable *table)) test_simple_table_get_n_rows;
+ klass-> get_column_extent_at =
+ (gint (*) (AtkTable *table, gint row, gint column)) test_simple_table_get_column_extent_at;
+ klass-> get_row_extent_at =
+ (gint (*) (AtkTable *table, gint row, gint column)) test_simple_table_get_row_extent_at;
+ klass-> get_caption =
+ (AtkObject* (*) (AtkTable *table)) test_simple_table_get_caption;
+ klass-> get_column_description =
+ (const gchar* (*) (AtkTable *table, gint column)) test_simple_table_get_column_description;
+ klass-> get_column_header =
+ (AtkObject* (*) (AtkTable *table, gint column)) test_simple_table_get_column_header;
+ klass-> get_row_description =
+ (const gchar* (*) (AtkTable *table, gint row)) test_simple_table_get_row_description;
+ klass-> get_row_header =
+ (AtkObject* (*) (AtkTable *table, gint row)) test_simple_table_get_row_header;
+ klass-> get_summary =
+ (AtkObject* (*) (AtkTable *table)) test_simple_table_get_summary;
+ klass-> set_caption =
+ (void (*) (AtkTable *table, AtkObject *caption)) test_simple_table_set_caption;
+ klass-> set_column_description =
+ (void (*) (AtkTable *table, gint column, const gchar *description)) test_simple_table_set_column_description;
+ klass-> set_column_header =
+ (void (*) (AtkTable *table, gint column, AtkObject *header)) test_simple_table_set_column_header;
+ klass-> set_row_description =
+ (void (*) (AtkTable *table, gint row, const gchar *description)) test_simple_table_set_row_description;
+ klass-> set_row_header =
+ (void (*) (AtkTable *table, gint row, AtkObject *header)) test_simple_table_set_row_header ;
+ klass-> set_summary =
+ (void (*) (AtkTable *table, AtkObject *accessible)) test_simple_table_set_summary ;
+ klass-> get_selected_columns =
+ (gint (*) (AtkTable *table, gint **selected)) test_simple_table_get_selected_columns;
+ klass-> get_selected_rows =
+ (gint (*) (AtkTable *table, gint **selected)) test_simple_table_get_selected_rows;
+ klass-> is_column_selected =
+ (gboolean (*) (AtkTable *table, gint column)) test_simple_table_is_column_selected;
+ klass-> is_row_selected =
+ (gboolean (*) (AtkTable *table, gint row)) test_simple_table_is_row_selected;
+ klass-> is_selected =
+ (gboolean (*) (AtkTable *table, gint row, gint column)) test_simple_table_is_selected;
+ klass-> add_row_selection =
+ (gboolean (*) (AtkTable *table, gint row)) test_simple_table_add_row_selection;
+ klass-> remove_row_selection =
+ (gboolean (*) (AtkTable *table, gint row)) test_simple_table_remove_row_selection;
+ klass-> add_column_selection =
+ (gboolean (*) (AtkTable *table, gint column)) test_simple_table_add_column_selection;
+ klass-> remove_column_selection =
+ (gboolean (*) (AtkTable *table, gint column)) test_simple_table_remove_column_selection;
+}
+
+static void
+simple_table_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+ TestSimpleTable *self = (TestSimpleTable *)instance;
+
+ self->disposed = FALSE;
+
+ self->nrows = NROWS;
+ self->ncols = NCOLS;
+
+ /* create & initialize child objects */
+ int i, j;
+ for (i = 0; i < NCHILDREN; ++i)
+ {
+ self->child[i] = TEST_SIMPLE_CHILD (g_object_new (TEST_TYPE_SIMPLE_CHILD, NULL));
+ self->child[i]->id = i;
+ }
+
+ self->not_a_child = TEST_SIMPLE_CHILD (g_object_new (TEST_TYPE_SIMPLE_CHILD, NULL));
+
+ // initialize table cells
+ for (i = 0; i < NROWS; ++i)
+ {
+ for (j = 0; j < NCOLS; ++j)
+ {
+ if (ids[i][j] >= 0)
+ {
+ self->tbl[i][j].elem = self->child[ids[i][j]];
+ }
+ else
+ {
+ self->tbl[i][j].elem = self->not_a_child;
+ }
+
+ self->tbl[i][j].ext_row = row_ext[i][j];
+ self->tbl[i][j].ext_col = col_ext[i][j];
+ } // end for j
+ } // end for i
+
+ self->caption = ATK_OBJECT (g_object_new (TEST_TYPE_SIMPLE_TEXT, NULL));
+ strncpy (TEST_SIMPLE_TEXT (self->caption)->text, DEF_CAPTION_TEXT, MAX_DESCR_LENGTH);
+
+ self->summary = ATK_OBJECT (g_object_new (TEST_TYPE_SIMPLE_TEXT, NULL));
+ strncpy (TEST_SIMPLE_TEXT (self->summary)->text, DEF_SUMMARY_TEXT, MAX_DESCR_LENGTH);
+
+ // initialize row and column descriptors
+ for (i = 0; i < NROWS; ++i)
+ {
+ self->row[i].hdr = ATK_OBJECT (g_object_new (TEST_TYPE_SIMPLE_TEXT, NULL));
+ self->row[i].selected = FALSE;
+ }
+
+ for (j = 0; j < NCOLS; ++j)
+ {
+ self->col[j].hdr = ATK_OBJECT (g_object_new (TEST_TYPE_SIMPLE_TEXT, NULL));
+ self->col[j].selected = FALSE;
+ }
+
+ test_simple_table_reset_headers(self);
+}
+
+static void
+test_simple_table_dispose (GObject *obj)
+{
+ TestSimpleTable *self = (TestSimpleTable *)obj;
+
+ if (self->disposed)
+ {
+ return;
+ }
+
+ /* Make sure dispose does not run twice. */
+ self->disposed = TRUE;
+
+ int i;
+ for (i = 0; i < NCHILDREN; ++i)
+ {
+ g_object_unref (G_OBJECT (self->child[i]));
+ }
+ g_object_unref (G_OBJECT (self->not_a_child));
+
+ for (i = 0; i < NROWS; ++i)
+ {
+ g_object_unref (G_OBJECT (self->row[i].hdr));
+ }
+
+ for (i = 0; i < NCOLS; ++i)
+ {
+ g_object_unref (G_OBJECT (self->col[i].hdr));
+ }
+
+ g_object_unref (G_OBJECT (self->caption));
+ g_object_unref (G_OBJECT (self->summary));
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class_simple_table)->dispose (obj);
+}
+
+static void
+test_simple_table_finalize (GObject *obj)
+{
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class_simple_table)->finalize (obj);
+}
+
+static void
+test_simple_table_class_init (gpointer g_class, gpointer g_class_data)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
+ TestSimpleTableClass *klass = TEST_SIMPLE_TABLE_CLASS (g_class);
+
+ gobject_class->dispose = test_simple_table_dispose;
+ gobject_class->finalize = test_simple_table_finalize;
+
+ parent_class_simple_table = g_type_class_peek_parent (klass);
+}
+
+GType
+test_simple_table_get_type (void)
+{
+ static GType type = 0;
+ if (type == 0)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof (TestSimpleTableClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ test_simple_table_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TestSimpleTable),
+ 0, /* n_preallocs */
+ simple_table_instance_init /* instance_init */
+ };
+
+ static const GInterfaceInfo iface_info =
+ {
+ (GInterfaceInitFunc) simple_table_interface_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+ type = g_type_register_static (ATK_TYPE_OBJECT,
+ "TestSimpleTableType",
+ &info, 0);
+ g_type_add_interface_static (type,
+ ATK_TYPE_TABLE,
+ &iface_info);
+ }
+ return type;
+}
--- /dev/null
+/* This file contains both declaration and definition of the TestSimpleTable,
+ * a GObject that pretends to implement the AtkTableIface interface (it
+ * registers appropriate interface), but provides no implementation for any of the
+ * methods of this interface (NULL-filled vftbl).
+ */
+
+#ifndef TESTSIMPLETABLE_H_
+#define TESTSIMPLETABLE_H_
+
+#include <glib-object.h>
+#include <atk/atk.h>
+
+#include <string.h>
+
+#include "test-simple-child.h"
+#include "test-simple-text.h"
+
+#define TEST_TYPE_SIMPLE_TABLE (test_simple_table_get_type ())
+#define TEST_SIMPLE_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_SIMPLE_TABLE, TestSimpleTable))
+#define TEST_SIMPLE_TABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), TEST_TYPE_SIMPLE_TABLE, TestSimpleTableClass))
+#define TEST_IS_SIMPLE_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_SIMPLE_TABLE))
+#define TEST_IS_SIMPLE_TABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), TEST_TYPE_SIMPLE_TABLE))
+#define TEST_SIMPLE_TABLE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), TEST_TYPE_SIMPLE_TABLE, TestSimpleTableClass))
+
+#define NROWS 4 /* row count */
+#define NCOLS 5 /* column count */
+
+static gint ids[NROWS][NCOLS] =
+ { {0, 1, 2, 2, 3},
+ {4, 5, 6, 7, 8},
+ {9, 9, 10, 11, 12},
+ {9, 9, 13, 14, -1} };
+
+static gint row_ext[NROWS][NCOLS] =
+ { {1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1},
+ {2, 2, 1, 1, 1},
+ {2, 2, 1, 1, 1} };
+
+static gint col_ext[NROWS][NCOLS] =
+ { {1, 1, 2, 2, 1},
+ {1, 1, 1, 1, 1},
+ {2, 2, 1, 1, 1},
+ {2, 2, 1, 1, 1} };
+
+#define NCHILDREN 16 /* child object count */
+
+// default string values
+#define DEF_CAPTION_TEXT "Default table caption"
+#define DEF_SUMMARY_TEXT "Default table summary"
+#define DEF_ROW_DESCR_TPL "Row No%d"
+#define DEF_COL_DESCR_TPL "Column No%d"
+
+// convenience typedefs
+typedef TestSimpleText TestSimpleHeader;
+typedef TestSimpleText TestSimpleSummary;
+//typedef TestSimpleText TestSimpleDescription;
+typedef TestSimpleText TestSimpleCaption;
+
+/* row and column headers */
+typedef struct
+{
+ AtkObject* hdr;
+ gboolean selected; /* TRUE if the row/column is selected, FALSE otherwise */
+} TestSimpleHeaderStruct;
+
+/* This struct represents a table cell */
+typedef struct
+{
+ TestSimpleChild* elem; /* the element */
+ guint ext_row; /* its row extent */
+ guint ext_col; /* its column extent */
+} TestSimpleCell;
+
+/* TestSimpleTable class */
+typedef struct _TestSimpleTable TestSimpleTable;
+typedef struct _TestSimpleTableClass TestSimpleTableClass;
+
+struct _TestSimpleTable
+{
+ AtkObject parent;
+ gboolean disposed;
+
+ /* Children of this object. */
+ TestSimpleChild* child[NCHILDREN];
+
+ /* This object is not a child of the table object. */
+ TestSimpleChild* not_a_child;
+
+ /* The table itself. */
+ TestSimpleCell tbl[NROWS][NCOLS];
+
+ /* Row and column descriptors */
+ TestSimpleHeaderStruct row[NROWS];
+ TestSimpleHeaderStruct col[NCOLS];
+
+ /* current number of rows and columns */
+ guint nrows;
+ guint ncols;
+
+ AtkObject* caption;
+
+ AtkObject* summary;
+};
+
+struct _TestSimpleTableClass
+{
+ AtkObjectClass parent;
+};
+
+#endif /*TESTSIMPLETABLE_H_*/
--- /dev/null
+/* This file contains both declaration and definition of the TestSimpleText class,
+ * a simple wrapper for a text string not longer than MAX_DESCR_LENGTH symbols.
+ */
+
+#include "test-simple-text.h"
+
+GType
+test_simple_text_get_type (void);
+
+static GObjectClass *parent_class_simple_text = NULL;
+
+/******************************************************************/
+/* Implementation */
+/******************************************************************/
+static void
+simple_text_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+ TestSimpleText *self = (TestSimpleText *)instance;
+
+ self->disposed = FALSE;
+ self->text = g_new (char, MAX_DESCR_LENGTH + 1);
+ self->text[0] = '\0';
+
+ //g_print ("\tCreate string\n");
+}
+
+static void
+test_simple_text_dispose (GObject *obj)
+{
+ TestSimpleText *self = (TestSimpleText *)obj;
+
+ if (self->disposed)
+ {
+ return;
+ }
+
+ /* Make sure dispose does not run twice. */
+ self->disposed = TRUE;
+
+ g_free (self->text);
+ self->text = NULL;
+ //g_print ("\tDelete string\n");
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class_simple_text)->dispose (obj);
+}
+
+static void
+test_simple_text_finalize (GObject *obj)
+{
+ TestSimpleText *self = (TestSimpleText *)obj;
+ if (self)
+ {
+ /*free (self->pdata->descr);
+ g_free (self->pdata);*/
+ }
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (parent_class_simple_text)->finalize (obj);
+}
+
+static void
+test_simple_text_class_init (gpointer g_class, gpointer g_class_data)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
+ TestSimpleTextClass *klass = TEST_SIMPLE_TEXT_CLASS (g_class);
+
+ gobject_class->dispose = test_simple_text_dispose;
+ gobject_class->finalize = test_simple_text_finalize;
+
+ parent_class_simple_text = g_type_class_peek_parent (klass);
+}
+
+GType
+test_simple_text_get_type (void)
+{
+ static GType type = 0;
+ if (type == 0)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof (TestSimpleTextClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ test_simple_text_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (TestSimpleText),
+ 0, /* n_preallocs */
+ simple_text_instance_init /* instance_init */
+ };
+
+ type = g_type_register_static (ATK_TYPE_OBJECT,
+ "TestSimpleTextType",
+ &info, 0);
+ }
+ return type;
+}
--- /dev/null
+/* This file contains both declaration and definition of the TestSimpleText class,
+ * a simple wrapper for a text string not longer than MAX_DESCR_LENGTH symbols.
+ */
+
+#ifndef TESTSIMPLETEXT_H_
+#define TESTSIMPLETEXT_H_
+#include <glib-object.h>
+#include <atk/atk.h>
+
+#define TEST_TYPE_SIMPLE_TEXT (test_simple_text_get_type ())
+#define TEST_SIMPLE_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_SIMPLE_TEXT, TestSimpleText))
+#define TEST_SIMPLE_TEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), TEST_TYPE_SIMPLE_TEXT, TestSimpleTextClass))
+#define TEST_IS_SIMPLE_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_SIMPLE_TEXT))
+#define TEST_IS_SIMPLE_TEXT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), TEST_TYPE_SIMPLE_TEXT))
+#define TEST_SIMPLE_TEXT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), TEST_TYPE_SIMPLE_TEXT, TestSimpleTextClass))
+
+/* Maximum length of the descriptive text allowed. */
+#define MAX_DESCR_LENGTH 1023
+
+typedef struct _TestSimpleText TestSimpleText;
+typedef struct _TestSimpleTextClass TestSimpleTextClass;
+
+struct _TestSimpleText
+{
+ AtkObject parent;
+ gboolean disposed;
+
+ gchar* text;
+};
+
+struct _TestSimpleTextClass
+{
+ AtkObjectClass parent;
+};
+
+#endif /*TESTSIMPLETEXT_H_*/
--- /dev/null
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _SPI_KEYMASKS_H_
+#define _SPI_KEYMASKS_H_
+
+#include <X11/Xlib.h>
+#include <glib/gmacros.h>
+
+G_BEGIN_DECLS
+
+typedef unsigned long SpiKeyMaskType;
+
+#define SPI_KEYMASK_ALT Mod1Mask
+#define SPI_KEYMASK_MOD1 Mod1Mask
+#define SPI_KEYMASK_MOD2 Mod2Mask
+#define SPI_KEYMASK_MOD3 Mod3Mask
+#define SPI_KEYMASK_MOD4 Mod4Mask
+#define SPI_KEYMASK_MOD5 Mod5Mask
+#define SPI_KEYMASK_BUTTON1 Button1Mask
+#define SPI_KEYMASK_BUTTON2 Button2Mask
+#define SPI_KEYMASK_BUTTON3 Button3Mask
+#define SPI_KEYMASK_BUTTON4 Button4Mask
+#define SPI_KEYMASK_BUTTON5 Button5Mask
+#define SPI_KEYMASK_CONTROL ControlMask
+#define SPI_KEYMASK_SHIFT ShiftMask
+#define SPI_KEYMASK_SHIFTLOCK LockMask
+#define SPI_KEYMASK_NUMLOCK (1<<14)
+#define SPI_KEYMASK_UNMODIFIED 0
+
+G_END_DECLS
+
+#endif