From 4a674680808b73499b947cf95d36012eef5fb394 Mon Sep 17 00:00:00 2001 From: Mike Gorse Date: Mon, 26 May 2008 12:55:54 -0400 Subject: [PATCH] Added atk tests Various other changes --- atk-tests/AtkObject_parent_child.c | 160 ++++++ atk-tests/AtkObject_parent_child.h | 31 ++ atk-tests/Makefile | 6 + atk-tests/MyAtkAction.c | 219 ++++++++ atk-tests/MyAtkAction.h | 56 ++ atk-tests/MyAtkComponent.c | 399 ++++++++++++++ atk-tests/MyAtkComponent.h | 43 ++ atk-tests/MyAtkImplementor.c | 70 +++ atk-tests/MyAtkImplementor.h | 29 ++ atk-tests/hello.h | 30 ++ atk-tests/main.c | 189 +++++++ atk-tests/test-simple-child.c | 92 ++++ atk-tests/test-simple-child.h | 33 ++ atk-tests/test-simple-table.c | 913 +++++++++++++++++++++++++++++++++ atk-tests/test-simple-table.h | 111 ++++ atk-tests/test-simple-text.c | 98 ++++ atk-tests/test-simple-text.h | 36 ++ {atk-adaptor => spi-common}/keymasks.h | 0 18 files changed, 2515 insertions(+) create mode 100755 atk-tests/AtkObject_parent_child.c create mode 100755 atk-tests/AtkObject_parent_child.h create mode 100644 atk-tests/Makefile create mode 100755 atk-tests/MyAtkAction.c create mode 100755 atk-tests/MyAtkAction.h create mode 100755 atk-tests/MyAtkComponent.c create mode 100755 atk-tests/MyAtkComponent.h create mode 100755 atk-tests/MyAtkImplementor.c create mode 100755 atk-tests/MyAtkImplementor.h create mode 100644 atk-tests/hello.h create mode 100644 atk-tests/main.c create mode 100755 atk-tests/test-simple-child.c create mode 100755 atk-tests/test-simple-child.h create mode 100755 atk-tests/test-simple-table.c create mode 100755 atk-tests/test-simple-table.h create mode 100755 atk-tests/test-simple-text.c create mode 100755 atk-tests/test-simple-text.h rename {atk-adaptor => spi-common}/keymasks.h (100%) diff --git a/atk-tests/AtkObject_parent_child.c b/atk-tests/AtkObject_parent_child.c new file mode 100755 index 0000000..e07b6b5 --- /dev/null +++ b/atk-tests/AtkObject_parent_child.c @@ -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 index 0000000..cbaaecb --- /dev/null +++ b/atk-tests/AtkObject_parent_child.h @@ -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 index 0000000..fd80e72 --- /dev/null +++ b/atk-tests/Makefile @@ -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 index 0000000..59a0a68 --- /dev/null +++ b/atk-tests/MyAtkAction.c @@ -0,0 +1,219 @@ +#include "MyAtkAction.h" +#include +#include + +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) && (in)) + { + 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 index 0000000..dc4da8b --- /dev/null +++ b/atk-tests/MyAtkAction.h @@ -0,0 +1,56 @@ +#ifndef MY_ATK_ACTION_H +#define MY_ATK_ACTION_H +//Object, which implement interface AtkAction(all functions) +#include +#include +#include + +//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 index 0000000..1e5119d --- /dev/null +++ b/atk-tests/MyAtkComponent.c @@ -0,0 +1,399 @@ +#include "MyAtkComponent.h" +#include + +//*************************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 index 0000000..0d137a2 --- /dev/null +++ b/atk-tests/MyAtkComponent.h @@ -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 +#include +#include + +#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 index 0000000..e317540 --- /dev/null +++ b/atk-tests/MyAtkImplementor.c @@ -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 index 0000000..721aaa6 --- /dev/null +++ b/atk-tests/MyAtkImplementor.h @@ -0,0 +1,29 @@ +#ifndef MY_ATK_IMPLEMENTOR_H +#define MY_ATK_IMPLEMENTOR_H + +#include + +#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 index 0000000..7b74849 --- /dev/null +++ b/atk-tests/hello.h @@ -0,0 +1,30 @@ +#ifndef TEST_HELLO_H +#include "gmodule.h" +#include + +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 index 0000000..73c3c8c --- /dev/null +++ b/atk-tests/main.c @@ -0,0 +1,189 @@ +#include "atk/atk.h" +#include "hello.h" +#include "test-simple-table.h" +#include +#include +#include +#include +#include + +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 index 0000000..b7bd1ed --- /dev/null +++ b/atk-tests/test-simple-child.c @@ -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 index 0000000..c03db0a --- /dev/null +++ b/atk-tests/test-simple-child.h @@ -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 +#include + +#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 index 0000000..787f556 --- /dev/null +++ b/atk-tests/test-simple-table.c @@ -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 +#include + +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 index 0000000..f29dac4 --- /dev/null +++ b/atk-tests/test-simple-table.h @@ -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 +#include + +#include + +#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 index 0000000..fe5f821 --- /dev/null +++ b/atk-tests/test-simple-text.c @@ -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 index 0000000..a456671 --- /dev/null +++ b/atk-tests/test-simple-text.h @@ -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 +#include + +#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_*/ diff --git a/atk-adaptor/keymasks.h b/spi-common/keymasks.h similarity index 100% rename from atk-adaptor/keymasks.h rename to spi-common/keymasks.h -- 2.7.4