Added atk tests
authorMike Gorse <mgorse@boston.site>
Mon, 26 May 2008 16:55:54 +0000 (12:55 -0400)
committerMike Gorse <mgorse@boston.site>
Mon, 26 May 2008 16:55:54 +0000 (12:55 -0400)
Various other changes

18 files changed:
atk-tests/AtkObject_parent_child.c [new file with mode: 0755]
atk-tests/AtkObject_parent_child.h [new file with mode: 0755]
atk-tests/Makefile [new file with mode: 0644]
atk-tests/MyAtkAction.c [new file with mode: 0755]
atk-tests/MyAtkAction.h [new file with mode: 0755]
atk-tests/MyAtkComponent.c [new file with mode: 0755]
atk-tests/MyAtkComponent.h [new file with mode: 0755]
atk-tests/MyAtkImplementor.c [new file with mode: 0755]
atk-tests/MyAtkImplementor.h [new file with mode: 0755]
atk-tests/hello.h [new file with mode: 0644]
atk-tests/main.c [new file with mode: 0644]
atk-tests/test-simple-child.c [new file with mode: 0755]
atk-tests/test-simple-child.h [new file with mode: 0755]
atk-tests/test-simple-table.c [new file with mode: 0755]
atk-tests/test-simple-table.h [new file with mode: 0755]
atk-tests/test-simple-text.c [new file with mode: 0755]
atk-tests/test-simple-text.h [new file with mode: 0755]
spi-common/keymasks.h [moved from atk-adaptor/keymasks.h with 100% similarity]

diff --git a/atk-tests/AtkObject_parent_child.c b/atk-tests/AtkObject_parent_child.c
new file mode 100755 (executable)
index 0000000..e07b6b5
--- /dev/null
@@ -0,0 +1,160 @@
+#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;
+}
diff --git a/atk-tests/AtkObject_parent_child.h b/atk-tests/AtkObject_parent_child.h
new file mode 100755 (executable)
index 0000000..cbaaecb
--- /dev/null
@@ -0,0 +1,31 @@
+#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*/
diff --git a/atk-tests/Makefile b/atk-tests/Makefile
new file mode 100644 (file)
index 0000000..fd80e72
--- /dev/null
@@ -0,0 +1,6 @@
+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
diff --git a/atk-tests/MyAtkAction.c b/atk-tests/MyAtkAction.c
new file mode 100755 (executable)
index 0000000..59a0a68
--- /dev/null
@@ -0,0 +1,219 @@
+#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;
+}
diff --git a/atk-tests/MyAtkAction.h b/atk-tests/MyAtkAction.h
new file mode 100755 (executable)
index 0000000..dc4da8b
--- /dev/null
@@ -0,0 +1,56 @@
+#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*/
diff --git a/atk-tests/MyAtkComponent.c b/atk-tests/MyAtkComponent.c
new file mode 100755 (executable)
index 0000000..1e5119d
--- /dev/null
@@ -0,0 +1,399 @@
+#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;    
+}
diff --git a/atk-tests/MyAtkComponent.h b/atk-tests/MyAtkComponent.h
new file mode 100755 (executable)
index 0000000..0d137a2
--- /dev/null
@@ -0,0 +1,43 @@
+#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*/
diff --git a/atk-tests/MyAtkImplementor.c b/atk-tests/MyAtkImplementor.c
new file mode 100755 (executable)
index 0000000..e317540
--- /dev/null
@@ -0,0 +1,70 @@
+#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;
+}
diff --git a/atk-tests/MyAtkImplementor.h b/atk-tests/MyAtkImplementor.h
new file mode 100755 (executable)
index 0000000..721aaa6
--- /dev/null
@@ -0,0 +1,29 @@
+#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*/
diff --git a/atk-tests/hello.h b/atk-tests/hello.h
new file mode 100644 (file)
index 0000000..7b74849
--- /dev/null
@@ -0,0 +1,30 @@
+#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 */
diff --git a/atk-tests/main.c b/atk-tests/main.c
new file mode 100644 (file)
index 0000000..73c3c8c
--- /dev/null
@@ -0,0 +1,189 @@
+#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;
+}
diff --git a/atk-tests/test-simple-child.c b/atk-tests/test-simple-child.c
new file mode 100755 (executable)
index 0000000..b7bd1ed
--- /dev/null
@@ -0,0 +1,92 @@
+/* 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;
+}
diff --git a/atk-tests/test-simple-child.h b/atk-tests/test-simple-child.h
new file mode 100755 (executable)
index 0000000..c03db0a
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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_*/
diff --git a/atk-tests/test-simple-table.c b/atk-tests/test-simple-table.c
new file mode 100755 (executable)
index 0000000..787f556
--- /dev/null
@@ -0,0 +1,913 @@
+/* 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;
+}
diff --git a/atk-tests/test-simple-table.h b/atk-tests/test-simple-table.h
new file mode 100755 (executable)
index 0000000..f29dac4
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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_*/
diff --git a/atk-tests/test-simple-text.c b/atk-tests/test-simple-text.c
new file mode 100755 (executable)
index 0000000..fe5f821
--- /dev/null
@@ -0,0 +1,98 @@
+/* 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;
+}
diff --git a/atk-tests/test-simple-text.h b/atk-tests/test-simple-text.h
new file mode 100755 (executable)
index 0000000..a456671
--- /dev/null
@@ -0,0 +1,36 @@
+/* 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_*/
similarity index 100%
rename from atk-adaptor/keymasks.h
rename to spi-common/keymasks.h