From c0f753d108b7a2ad23dbf5a5b596f80175442927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Mon, 14 Jun 2010 13:38:25 +0200 Subject: [PATCH 01/16] Add Cally The Clutter Accessibility Library is an implementation of the ATK, the Accessibility Toolkit, which exposes Clutter actors to accessibility tools. This allows not only writing accessible user interfaces, but also allows testing and verification frameworks based on A11Y technologies to inspect and test a Clutter scene graph. http://bugzilla.clutter-project.org/show_bug.cgi?id=2097 Signed-off-by: Emmanuele Bassi --- clutter/Makefile.am | 10 +- clutter/cally/Makefile.am | 79 ++ clutter/cally/cally-actor-private.h | 35 + clutter/cally/cally-actor.c | 1491 +++++++++++++++++++++++++++ clutter/cally/cally-actor.h | 108 ++ clutter/cally/cally-clone.c | 105 ++ clutter/cally/cally-clone.h | 63 ++ clutter/cally/cally-factory.h | 91 ++ clutter/cally/cally-group.c | 138 +++ clutter/cally/cally-group.h | 65 ++ clutter/cally/cally-rectangle.c | 102 ++ clutter/cally/cally-rectangle.h | 63 ++ clutter/cally/cally-root.c | 273 +++++ clutter/cally/cally-root.h | 64 ++ clutter/cally/cally-stage.c | 258 +++++ clutter/cally/cally-stage.h | 62 ++ clutter/cally/cally-text.c | 1255 ++++++++++++++++++++++ clutter/cally/cally-text.h | 63 ++ clutter/cally/cally-texture.c | 103 ++ clutter/cally/cally-texture.h | 63 ++ clutter/cally/cally-util.c | 557 ++++++++++ clutter/cally/cally-util.h | 61 ++ clutter/cally/cally.pc.in | 18 + configure.ac | 2 + 24 files changed, 5126 insertions(+), 3 deletions(-) create mode 100644 clutter/cally/Makefile.am create mode 100644 clutter/cally/cally-actor-private.h create mode 100644 clutter/cally/cally-actor.c create mode 100644 clutter/cally/cally-actor.h create mode 100644 clutter/cally/cally-clone.c create mode 100644 clutter/cally/cally-clone.h create mode 100644 clutter/cally/cally-factory.h create mode 100644 clutter/cally/cally-group.c create mode 100644 clutter/cally/cally-group.h create mode 100644 clutter/cally/cally-rectangle.c create mode 100644 clutter/cally/cally-rectangle.h create mode 100644 clutter/cally/cally-root.c create mode 100644 clutter/cally/cally-root.h create mode 100644 clutter/cally/cally-stage.c create mode 100644 clutter/cally/cally-stage.h create mode 100644 clutter/cally/cally-text.c create mode 100644 clutter/cally/cally-text.h create mode 100644 clutter/cally/cally-texture.c create mode 100644 clutter/cally/cally-texture.h create mode 100644 clutter/cally/cally-util.c create mode 100644 clutter/cally/cally-util.h create mode 100644 clutter/cally/cally.pc.in diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 75017804d..cc204b2ac 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/build/autotools/Makefile.am.silent NULL = -SUBDIRS = cogl $(CLUTTER_WINSYS_BASE) $(CLUTTER_WINSYS) +SUBDIRS = cogl $(CLUTTER_WINSYS_BASE) $(CLUTTER_WINSYS) cally if LOCAL_JSON_GLIB SUBDIRS += json @@ -12,7 +12,7 @@ clutter_json_libadd = $(top_builddir)/clutter/json/libclutter-json.la clutter_json_gir = ClutterJson-@CLUTTER_API_VERSION@.gir endif -DIST_SUBDIRS = glx egl cogl json osx x11 win32 fruity +DIST_SUBDIRS = glx egl cogl json osx x11 win32 fruity cally # common definitions CLEANFILES = @@ -39,6 +39,7 @@ endif # SUPPORT_WIN32 INCLUDES = \ -I$(top_srcdir) \ + -I$(top_srcdir)/clutter/cally \ -I$(top_srcdir)/clutter/cogl \ -I$(top_srcdir)/clutter/cogl/pango \ -I$(top_srcdir)/clutter \ @@ -260,13 +261,16 @@ source_h_priv = \ libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_LIBADD = \ $(CLUTTER_LIBS) \ + $(top_builddir)/clutter/cally/libcally.la \ $(top_builddir)/clutter/cogl/cogl/libclutter-cogl.la \ $(top_builddir)/clutter/cogl/pango/libcoglpango.la \ $(top_builddir)/clutter/$(CLUTTER_WINSYS)/libclutter-$(CLUTTER_WINSYS).la \ $(clutter_json_libadd) \ $(CLUTTER_WINSYS_BASE_LIB) + libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_DEPENDENCIES = \ + $(top_builddir)/clutter/cally/libcally.la \ $(top_builddir)/clutter/cogl/cogl/libclutter-cogl.la \ $(top_builddir)/clutter/cogl/pango/libcoglpango.la \ $(top_builddir)/clutter/$(CLUTTER_WINSYS)/libclutter-$(CLUTTER_WINSYS).la \ @@ -289,7 +293,7 @@ libclutter_@CLUTTER_SONAME_INFIX@_@CLUTTER_API_VERSION@_la_LDFLAGS = \ $(CLUTTER_LT_LDFLAGS) \ $(GCOV_LDFLAGS) \ -export-dynamic \ - -export-symbols-regex "^(clutter|cogl|json).*" \ + -export-symbols-regex "^(clutter|cogl|cally|json).*" \ -rpath $(libdir) \ $(win32_resources_ldflag) \ $(NULL) diff --git a/clutter/cally/Makefile.am b/clutter/cally/Makefile.am new file mode 100644 index 000000000..75cec6a2b --- /dev/null +++ b/clutter/cally/Makefile.am @@ -0,0 +1,79 @@ +include $(top_srcdir)/build/autotools/Makefile.am.silent + +EXTRA_DIST = +CLEANFILES = +DISTCLEANFILES = + +# pkg-config ================================================================== +pc_files = \ + cally-$(CLUTTER_API_VERSION).pc + +cally-$(CLUTTER_API_VERSION).pc: cally.pc + $(QUIET_GEN)cp -f $< $(@F) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = $(pc_files) + +EXTRA_DIST += cally.pc.in +CLEANFILES += $(pc_files) + +noinst_LTLIBRARIES = libcally.la + +cally_h_sources = cally.h \ + cally-actor.h \ + cally-factory.h \ + cally-group.h \ + cally-rectangle.h \ + cally-root.h \ + cally-stage.h \ + cally-text.h \ + cally-texture.h \ + cally-clone.h \ + cally-util.h + +cally_private_h_sources = cally-actor-private.h + +cally_c_sources = cally.c \ + cally-actor.c \ + cally-group.c \ + cally-rectangle.c \ + cally-root.c \ + cally-stage.c \ + cally-text.c \ + cally-texture.c \ + cally-clone.c \ + cally-util.c + +libcally_la_SOURCES = \ + $(cally_private_h_sources) \ + $(cally_h_sources) \ + $(cally_c_sources) + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/clutter \ + -I$(top_srcdir)/clutter/cally \ + -I$(top_srcdir)/clutter/cogl + +AM_CPPFLAGS = \ + -DG_LOG_DOMAIN=\"Cally\" \ + -DCLUTTER_COMPILATION \ + -DVERSION=\"$(VERSION)\" \ + $(CLUTTER_DEBUG_CFLAGS) + +AM_CFLAGS = \ + $(CLUTTER_CFLAGS) \ + $(MAINTAINER_CFLAGS) + + +libcallydir=$(includedir)/clutter-@CLUTTER_API_VERSION@/cally + +# In opposit to GAIL, CALLY exports all the headers. It will very +# unlikely in any real final clutter-based application to use only raw +# CALLY. In fact, after HAIL experience, probably export GAIL +# interfaces would be a good idea +libcally_HEADERS = \ + $(cally_h_sources) + +libcally_la_LIBADD = \ + $(CLUTTER_LIBS) \ No newline at end of file diff --git a/clutter/cally/cally-actor-private.h b/clutter/cally/cally-actor-private.h new file mode 100644 index 000000000..b9c0d0b46 --- /dev/null +++ b/clutter/cally/cally-actor-private.h @@ -0,0 +1,35 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __CALLY_ACTOR_PRIVATE_H__ +#define __CALLY_ACTOR_PRIVATE_H__ + +#include "cally-actor.h" + +/* + * Auxiliar define, in order to get the clutter actor from the AtkObject using + * AtkGObject methods + * + */ +#define CALLY_GET_CLUTTER_ACTOR(cally_object) \ + (CLUTTER_ACTOR (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (cally_object)))) + +#endif /* __CALLY_ACTOR_PRIVATE_H__ */ diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c new file mode 100644 index 000000000..b8a86de2f --- /dev/null +++ b/clutter/cally/cally-actor.c @@ -0,0 +1,1491 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Some parts are based on GailWidget, GailContaineer, GailCell from GAIL + * GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:cally-actor + * @short_description: Implementation of the ATK interfaces for #ClutterActor + * @see_also: #ClutterActor + * + * #CallyActor implements the required ATK interfaces of #ClutterActor + * exposing the common elements on each ClutterActor (position, extents, etc). + */ + +/** + * + * IMPLEMENTATION NOTES: + * + * #### + * + * Focus: clutter hasn't got the focus concept in the same way that GTK, but it + * has a key focus managed by the stage. Basically any actor can be focused using + * clutter_stage_set_key_focus. So, we will use this approach: all actors are + * focusable, and we get the currently focused using clutter_stage_get_key_focus + * This affects focus related stateset and some atk_componenet focus methods (like + * grab focus) + * + * #### + * + * #ClutterContainer : cally_actor implements some of his methods based on + * #ClutterContainer interface, although there are the posibility to not + * implement it. Could be strange to do that but: + * * Some methods (like get_n_children and ref_child) are easily implemented using + * this interface so a general implementation can be done + * * #ClutterContainer is a popular interface, so several classes will implement + * that. + * * So we can implement a a11y class similar to GailContainer for each clutter + * object implementing that, and their clutter subclasses will have a proper + * a11y class, but not if they are parallel classes (ie: #ClutterGroup, + * #TinyFrame, #TinyScrollView) + * * So, on all this objects, will be required to reimplement again some methods + * on the objects. + * * A auxiliar object (a kind of a11y specific #ClutterContainer implementation) + * could be used to implement this methods in only a place, anyway, this will + * require some code on each concrete class to manage it. + * * So this implementation is based in that is better to manage a interface + * on the top abstract object, instead that C&P some code, with the minor + * problem that we need to check if we are implementing or not the interface. + * + * This methods can be reimplemented, in concrete cases that we can get ways more + * efficient to implement that. Take a look to #CallyGroup as a example of this. + * + * Anyway, there are several examples of behaviour changes depending of the current + * type of the object you are granting access. + * + * TODO,FIXME: check if an option would be to use a dynamic type, as + * it has been done on the webkit a11y implementation: + * See: https://bugs.webkit.org/show_bug.cgi?id=21546 + * + * ### + * + * #AtkAction implementation. As ClutterActor has signals for "press" + * and "release", and most of the general Clutter objects are being + * used as buttons, it has sense to implement #AtkAction on + * #CallyActor, so this actions were added in this level. + * + * So we should search a way to extend #AtkAction on subclasses, to + * add actions. The direct solution would be just extend it normally, + * but we also should have the option to remove actions if required. + * + * So it was used the solution implemented in GailCell: maintain a + * list of actions, and add a _add_action and _remove_action public + * methods. + * + * This is another reason to not isolate CALLY as GAIL (although the + * current idea is to not do that). + * + */ + +#include "config.h" + +#include +#include + +#ifdef HAVE_CLUTTER_X11 +#include +#endif + +#include + +#include "cally-actor.h" +#include "cally-actor-private.h" + +typedef struct _CallyActorActionInfo CallyActorActionInfo; + +/** + * CallyActorActionInfo: + * @name: name of the action + * @description: description of the action + * @keybinding: keybinding related to the action + * @do_action_func: callback + * + * Utility structure to maintain the different actions added to the + * #CallyActor + */ +struct _CallyActorActionInfo +{ + gchar *name; + gchar *description; + gchar *keybinding; + CallyActionFunc do_action_func; +}; + +static void cally_actor_class_init (CallyActorClass *klass); +static void cally_actor_init (CallyActor *cally_actor); +static void cally_actor_initialize (AtkObject *obj, + gpointer data); +static void cally_actor_finalize (GObject *obj); + +/* AtkObject.h */ +static AtkObject* cally_actor_get_parent (AtkObject *obj); +static gint cally_actor_get_index_in_parent (AtkObject *obj); +static AtkStateSet* cally_actor_ref_state_set (AtkObject *obj); +static G_CONST_RETURN gchar* cally_actor_get_name (AtkObject *obj); +static gint cally_actor_get_n_children (AtkObject *obj); +static AtkObject* cally_actor_ref_child (AtkObject *obj, + gint i); +static gboolean _cally_actor_all_parents_visible (ClutterActor *actor); + +/* ClutterContainer */ +static gint cally_actor_add_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data); +static gint cally_actor_remove_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data); +static gint cally_actor_real_add_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data); +static gint cally_actor_real_remove_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data); + +/* AtkComponent.h */ +static void cally_actor_component_interface_init (AtkComponentIface *iface); +static void cally_actor_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type); +static gint cally_actor_get_mdi_zorder (AtkComponent *component); +static gboolean cally_actor_grab_focus (AtkComponent *component); +static guint cally_actor_add_focus_handler (AtkComponent *component, + AtkFocusHandler handler); +static void cally_actor_remove_focus_handler (AtkComponent *component, + guint handler_id); +static void cally_actor_focus_event (AtkObject *obj, + gboolean focus_in); +static gboolean _is_actor_on_screen (ClutterActor *actor); +static void _get_top_level_origin (ClutterActor *actor, + gint *x, + gint *y); + +/* AtkAction.h */ +static void cally_actor_action_interface_init (AtkActionIface *iface); +static gboolean cally_actor_action_do_action (AtkAction *action, + gint i); +static gboolean idle_do_action (gpointer data); +static gint cally_actor_action_get_n_actions (AtkAction *action); +static G_CONST_RETURN gchar* cally_actor_action_get_description (AtkAction *action, + gint i); +static G_CONST_RETURN gchar* cally_actor_action_get_keybinding (AtkAction *action, + gint i); +static G_CONST_RETURN gchar* cally_actor_action_get_name (AtkAction *action, + gint i); +static gboolean cally_actor_action_set_description (AtkAction *action, + gint i, + const gchar *desc); +static void _cally_actor_press_action (CallyActor *cally_actor); +static void _cally_actor_release_action (CallyActor *cally_actor); +static void _cally_actor_click_action (CallyActor *cally_actor); +static void _cally_actor_destroy_action_info (gpointer action_info, + gpointer user_data); +static void _cally_actor_clean_action_list (CallyActor *cally_actor); + +static CallyActorActionInfo* _cally_actor_get_action_info (CallyActor *cally_actor, + gint index); +/* Misc functions */ +static void cally_actor_notify_clutter (GObject *obj, + GParamSpec *pspec); +static void cally_actor_real_notify_clutter (GObject *obj, + GParamSpec *pspec); +static gboolean cally_actor_focus_clutter (ClutterActor *actor, + gpointer data); +static gboolean cally_actor_real_focus_clutter (ClutterActor *actor, + gpointer data); + +G_DEFINE_TYPE_WITH_CODE (CallyActor, + cally_actor, + ATK_TYPE_GOBJECT_ACCESSIBLE, + G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, + cally_actor_component_interface_init) + G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, + cally_actor_action_interface_init)); + +#define CALLY_ACTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CALLY_TYPE_ACTOR, CallyActorPrivate)) + + +struct _CallyActorPrivate +{ + GQueue *action_queue; + guint action_idle_handler; + GList *action_list; + + GList *children; +}; + + +AtkObject* +cally_actor_new (ClutterActor *actor) +{ + gpointer object; + AtkObject *atk_object; + + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); + + object = g_object_new (CALLY_TYPE_ACTOR, NULL); + + atk_object = ATK_OBJECT (object); + atk_object_initialize (atk_object, actor); + + return atk_object; +} + +static void +cally_actor_initialize (AtkObject *obj, + gpointer data) +{ + CallyActor *self = NULL; + CallyActorPrivate *priv = NULL; + ClutterActor *actor = NULL; + guint handler_id; + + ATK_OBJECT_CLASS (cally_actor_parent_class)->initialize (obj, data); + + self = CALLY_ACTOR(obj); + priv = self->priv; + actor = CLUTTER_ACTOR (data); + + g_signal_connect_after (actor, + "key-focus-in", + G_CALLBACK (cally_actor_focus_clutter), + GINT_TO_POINTER (TRUE)); + g_signal_connect_after (actor, + "key-focus-out", + G_CALLBACK (cally_actor_focus_clutter), + GINT_TO_POINTER (FALSE)); + g_signal_connect (actor, + "notify", + G_CALLBACK (cally_actor_notify_clutter), + NULL); + atk_component_add_focus_handler (ATK_COMPONENT (self), + cally_actor_focus_event); + + g_object_set_data (G_OBJECT (obj), "atk-component-layer", + GINT_TO_POINTER (ATK_LAYER_MDI)); + + /* add basic actions */ + cally_actor_add_action (self, "press", NULL, NULL, + _cally_actor_press_action); + + cally_actor_add_action (self, "release", NULL, NULL, + _cally_actor_release_action); + + cally_actor_add_action (self, "click", NULL, NULL, + _cally_actor_click_action); + + /* Depends if the object implement ClutterContainer */ + if (CLUTTER_IS_CONTAINER(actor)) + { + priv->children = clutter_container_get_children (CLUTTER_CONTAINER (actor)); + + /* + * We store the handler ids for these signals in case some objects + * need to remove these handlers. + */ + handler_id = g_signal_connect (actor, + "actor-added", + G_CALLBACK (cally_actor_add_actor), + obj); + g_object_set_data (G_OBJECT (obj), "cally-add-handler-id", + GUINT_TO_POINTER (handler_id)); + handler_id = g_signal_connect (actor, + "actor-removed", + G_CALLBACK (cally_actor_remove_actor), + obj); + g_object_set_data (G_OBJECT (obj), "cally-remove-handler-id", + GUINT_TO_POINTER (handler_id)); + + obj->role = ATK_ROLE_PANEL; /* typically objects implementing ClutterContainer + interface would be a panel */ + } + else + { + priv->children = NULL; + obj->role = ATK_ROLE_UNKNOWN; + } +} + +static void +cally_actor_class_init (CallyActorClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + klass->focus_clutter = cally_actor_real_focus_clutter; + klass->notify_clutter = cally_actor_real_notify_clutter; + klass->add_actor = cally_actor_real_add_actor; + klass->remove_actor = cally_actor_real_remove_actor; + + /* GObject */ + gobject_class->finalize = cally_actor_finalize; + + /* AtkObject */ + class->get_name = cally_actor_get_name; + class->get_parent = cally_actor_get_parent; + class->get_index_in_parent = cally_actor_get_index_in_parent; + class->ref_state_set = cally_actor_ref_state_set; + class->initialize = cally_actor_initialize; + class->get_n_children = cally_actor_get_n_children; + class->ref_child = cally_actor_ref_child; + + g_type_class_add_private (gobject_class, sizeof (CallyActorPrivate)); +} + +static void +cally_actor_init (CallyActor *cally_actor) +{ + CallyActorPrivate *priv = CALLY_ACTOR_GET_PRIVATE (cally_actor); + + cally_actor->priv = priv; + + priv->action_queue = NULL; + priv->action_idle_handler = 0; + + priv->action_list = NULL; + + priv->children = NULL; +} + + +static void +cally_actor_finalize (GObject *obj) +{ + CallyActor *cally_actor = NULL; + CallyActorPrivate *priv = NULL; + + cally_actor = CALLY_ACTOR (obj); + priv = cally_actor->priv; + + _cally_actor_clean_action_list (cally_actor); + + if (priv->action_idle_handler) + { + g_source_remove (priv->action_idle_handler); + priv->action_idle_handler = 0; + } + + if (priv->action_queue) + { + g_queue_free (priv->action_queue); + } + + if (priv->children) + { + g_list_free (priv->children); + priv->children = NULL; + } + + G_OBJECT_CLASS (cally_actor_parent_class)->finalize (obj); +} + +/* AtkObject */ + +static G_CONST_RETURN gchar* +cally_actor_get_name (AtkObject *obj) +{ + G_CONST_RETURN gchar* name = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); + + name = ATK_OBJECT_CLASS (cally_actor_parent_class)->get_name (obj); + if (name == NULL) + { + CallyActor *cally_actor = NULL; + ClutterActor *actor = NULL; + + cally_actor = CALLY_ACTOR (obj); + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + if (actor == NULL) /* State is defunct */ + name = NULL; + else + name = clutter_actor_get_name (actor); + } + return name; +} + +static AtkObject * +cally_actor_get_parent (AtkObject *obj) +{ + ClutterActor *parent_actor = NULL; + AtkObject *parent = NULL; + ClutterActor *actor = NULL; + CallyActor *cally_actor = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); + + /* Check if we have and assigned parent */ + if (obj->accessible_parent) + return obj->accessible_parent; + + /* Try to get it from the clutter parent */ + cally_actor = CALLY_ACTOR (obj); + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + if (actor == NULL) /* Object is defunct */ + return NULL; + + parent_actor = clutter_actor_get_parent (actor); + if (parent_actor == NULL) + return NULL; + + parent = clutter_actor_get_accessible (parent_actor); + + /* FIXME: I need to review the clutter-embed, to check if in this case I + * should get the widget accessible + */ + + return parent; +} + +static gint +cally_actor_get_index_in_parent (AtkObject *obj) +{ + CallyActor *cally_actor = NULL; + ClutterActor *actor = NULL; + ClutterActor *parent_actor = NULL; + GList *children = NULL; + gint index = -1; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), -1); + + if (obj->accessible_parent) + { + gint n_children, i; + gboolean found = FALSE; + + n_children = atk_object_get_n_accessible_children (obj->accessible_parent); + for (i = 0; i < n_children; i++) + { + AtkObject *child; + + child = atk_object_ref_accessible_child (obj->accessible_parent, i); + if (child == obj) + found = TRUE; + + g_object_unref (child); + if (found) + return i; + } + return -1; + } + + cally_actor = CALLY_ACTOR (obj); + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + if (actor == NULL) /* Object is defunct */ + return -1; + + parent_actor = clutter_actor_get_parent(actor); + if ((parent_actor == NULL)||(!CLUTTER_IS_CONTAINER(parent_actor))) + return -1; + + children = clutter_container_get_children(CLUTTER_CONTAINER(parent_actor)); + + index = g_list_index (children, actor); + g_list_free (children); + + return index; +} + +static AtkStateSet* +cally_actor_ref_state_set (AtkObject *obj) +{ + ClutterActor *actor = NULL; + AtkStateSet *state_set = NULL; + ClutterStage *stage = NULL; + ClutterActor *focus_actor = NULL; + CallyActor *cally_actor = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); + cally_actor = CALLY_ACTOR (obj); + + state_set = ATK_OBJECT_CLASS (cally_actor_parent_class)->ref_state_set (obj); + + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + + if (actor == NULL) /* Object is defunct */ + { + atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT); + } + else + { + if (CLUTTER_ACTOR_IS_REACTIVE (actor)) + { + atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE); + atk_state_set_add_state (state_set, ATK_STATE_ENABLED); + } + + if (CLUTTER_ACTOR_IS_VISIBLE (actor)) + { + atk_state_set_add_state (state_set, ATK_STATE_VISIBLE); + + if (_is_actor_on_screen (actor) && + _cally_actor_all_parents_visible (actor)) + atk_state_set_add_state (state_set, ATK_STATE_SHOWING); + } + + /* See focus section on implementation notes */ + atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE); + + stage = CLUTTER_STAGE (clutter_actor_get_stage (actor)); + /* If for any reason this actor doesn't have a stage + associated, we try the default one as fallback */ + if (stage == NULL) + stage = CLUTTER_STAGE (clutter_stage_get_default ()); + + focus_actor = clutter_stage_get_key_focus (stage); + if (focus_actor == actor) + atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); + } + + return state_set; +} + +static gint +cally_actor_get_n_children (AtkObject *obj) +{ + ClutterActor *actor = NULL; + CallyActorPrivate *priv = NULL; + GList *children = NULL; + gint num = 0; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), 0); + + priv = CALLY_ACTOR (obj)->priv; + actor = CALLY_GET_CLUTTER_ACTOR (obj); + + if (actor == NULL) /* State is defunct */ + return 0; + + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); + + if (CLUTTER_IS_CONTAINER (actor)) + { + children = clutter_container_get_children (CLUTTER_CONTAINER (actor)); + num = g_list_length (children); + + g_list_free (children); + } + else + { + num = 0; + } + + return num; +} + +static AtkObject* +cally_actor_ref_child (AtkObject *obj, + gint i) +{ + ClutterActor *actor = NULL; + ClutterActor *child = NULL; + CallyActorPrivate *priv = NULL; + GList *children = NULL; + AtkObject *result = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); + + priv = CALLY_ACTOR (obj)->priv; + actor = CALLY_GET_CLUTTER_ACTOR (obj); + + if (actor == NULL) /* State is defunct */ + { + return NULL; + } + + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); + + if (CLUTTER_IS_CONTAINER (actor)) + { + children = clutter_container_get_children (CLUTTER_CONTAINER (actor)); + child = g_list_nth_data (children, i); + + result = clutter_actor_get_accessible (child); + + g_object_ref (result); + g_list_free (children); + } + else + { + result = NULL; + } + + return result; +} + +/* ClutterContainer */ +static gint +cally_actor_add_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data) +{ + CallyActor *cally_actor = CALLY_ACTOR (data); + CallyActorClass *klass = NULL; + + klass = CALLY_ACTOR_GET_CLASS (cally_actor); + + if (klass->add_actor) + return klass->add_actor (container, actor, data); + else + return 1; +} + +static gint +cally_actor_remove_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data) +{ + CallyActor *cally_actor = CALLY_ACTOR (data); + CallyActorClass *klass = NULL; + + klass = CALLY_ACTOR_GET_CLASS (cally_actor); + + if (klass->remove_actor) + return klass->remove_actor (container, actor, data); + else + return 1; +} + + +static gint +cally_actor_real_add_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data) +{ + AtkObject *atk_parent = ATK_OBJECT (data); + AtkObject *atk_child = clutter_actor_get_accessible (actor); + CallyActor *cally_actor = CALLY_ACTOR (atk_parent); + CallyActorPrivate *priv = cally_actor->priv; + gint index; + + g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), 0); + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); + + g_object_notify (G_OBJECT (atk_child), "accessible_parent"); + + g_list_free (priv->children); + + priv->children = + clutter_container_get_children (CLUTTER_CONTAINER(container)); + + index = g_list_index (priv->children, actor); + g_signal_emit_by_name (atk_parent, "children_changed::add", + index, atk_child, NULL); + + return 1; +} + +static gint +cally_actor_real_remove_actor (ClutterActor *container, + ClutterActor *actor, + gpointer data) +{ + AtkPropertyValues values = { NULL }; + AtkObject* atk_parent = NULL; + AtkObject *atk_child = NULL; + CallyActorPrivate *priv = NULL; + gint index; + + g_return_val_if_fail (CLUTTER_IS_CONTAINER (container), 0); + g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), 0); + + atk_parent = ATK_OBJECT (data); + atk_child = clutter_actor_get_accessible (actor); + + if (atk_child) + { + g_value_init (&values.old_value, G_TYPE_POINTER); + g_value_set_pointer (&values.old_value, atk_parent); + + values.property_name = "accessible-parent"; + + g_object_ref (atk_child); + g_signal_emit_by_name (atk_child, + "property_change::accessible-parent", &values, NULL); + g_object_unref (atk_child); + } + + priv = CALLY_ACTOR (atk_parent)->priv; + index = g_list_index (priv->children, actor); + g_list_free (priv->children); + priv->children = clutter_container_get_children (CLUTTER_CONTAINER(container)); + + if (index >= 0 && index <= g_list_length (priv->children)) + g_signal_emit_by_name (atk_parent, "children_changed::remove", + index, atk_child, NULL); + + return 1; +} + +/* AtkComponent implementation */ +static void +cally_actor_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = cally_actor_get_extents; + iface->get_mdi_zorder = cally_actor_get_mdi_zorder; + + /* focus management */ + iface->grab_focus = cally_actor_grab_focus; + iface->add_focus_handler = cally_actor_add_focus_handler; + iface->remove_focus_handler = cally_actor_remove_focus_handler; +} + +static void +cally_actor_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type) +{ + CallyActor *cally_actor = NULL; + ClutterActor *actor = NULL; + gint top_level_x, top_level_y; + gfloat f_width, f_height; + ClutterVertex verts[4]; + + g_return_if_fail (CALLY_IS_ACTOR (component)); + + cally_actor = CALLY_ACTOR (component); + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + + if (actor == NULL) /* actor is defunct */ + return; + + clutter_actor_get_abs_allocation_vertices (actor, verts); + clutter_actor_get_transformed_size (actor, &f_width, &f_height); + + *x = verts[0].x; + *y = verts[0].y; + *width = ceilf (f_width); + *height = ceilf (f_height); + + /* In the ATK_XY_WINDOW case, we consider the stage as the + * "top-level-window" + * + * http://library.gnome.org/devel/atk/stable/AtkUtil.html#AtkCoordType + */ + + if (coord_type == ATK_XY_SCREEN) + { + _get_top_level_origin (actor, &top_level_x, &top_level_y); + + *x += top_level_x; + *y += top_level_y; + } + + return; +} + +static gint +cally_actor_get_mdi_zorder (AtkComponent *component) +{ + CallyActor *cally_actor = NULL; + ClutterActor *actor = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (component), G_MININT); + + cally_actor = CALLY_ACTOR(component); + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + + return clutter_actor_get_depth (actor); +} + +static gboolean +cally_actor_grab_focus (AtkComponent *component) +{ + ClutterActor *actor = NULL; + ClutterActor *stage = NULL; + CallyActor *cally_actor = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (component), FALSE); + + /* See focus section on implementation notes */ + cally_actor = CALLY_ACTOR(component); + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + stage = clutter_actor_get_stage (actor); + + clutter_stage_set_key_focus (CLUTTER_STAGE (stage), + actor); + + return TRUE; +} + +/* + * These methods are basically taken from gail, as I don't see any + * reason to modify it. It makes me wonder why it is really required + * to be implemented in the toolkit + */ +static guint +cally_actor_add_focus_handler (AtkComponent *component, + AtkFocusHandler handler) +{ + GSignalMatchType match_type; + gulong ret; + guint signal_id; + + match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC; + signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT); + + ret = g_signal_handler_find (component, match_type, signal_id, 0, NULL, + (gpointer) handler, NULL); + if (!ret) + { + return g_signal_connect_closure_by_id (component, + signal_id, 0, + g_cclosure_new (G_CALLBACK (handler), NULL, + (GClosureNotify) NULL), + FALSE); + } + else + { + return 0; + } +} + +static void +cally_actor_remove_focus_handler (AtkComponent *component, + guint handler_id) +{ + g_signal_handler_disconnect (component, handler_id); +} + +/* This method should check if the actor is currently on screen */ +static gboolean +_is_actor_on_screen (ClutterActor *actor) +{ + /* FIXME: FILL ME!! + * You could get some ideas from clutter_actor_is_on_stage, a private clutter + * function (note: it doesn't exists in the last versions of clutter) + * A occlusion check could be a good idea too + */ + + return TRUE; +} + +/** + * + * This gets the top level origin, it is, the position of the stage in + * the global screen. You can see it as the absolute display position + * of the stage. + * + * FIXME: only the case with x11 is implemented, other backends are + * required + * + **/ +static void +_get_top_level_origin (ClutterActor *actor, + gint *x, + gint *y) +{ + /* default values */ + *x = 0; + *y = 0; + +#ifdef HAVE_CLUTTER_X11 + ClutterActor *stage = NULL; + Display *display = NULL; + Window root_window; + Window stage_window; + Window child; + gint return_val = 0; + + stage = clutter_actor_get_stage (actor); + + display = clutter_x11_get_default_display (); /* FIXME: what happens if you use another + display with clutter_backend_x11_set_display ?*/ + root_window = clutter_x11_get_root_window (); + stage_window = clutter_x11_get_stage_window (CLUTTER_STAGE (stage)); + + return_val = XTranslateCoordinates (display, stage_window, root_window, + 0, 0, x, y, + &child); + + if (!return_val) + g_warning ("[x11] We were not able to get proper absolute position of the stage"); +#else + static gboolean yet_warned = FALSE; + + if (!yet_warned) + { + yet_warned = TRUE; + + g_warning ("Using a clutter backend not supported. " + "atk_component_get_extents using ATK_XY_SCREEN could return a wrong screen position"); + } + +#endif +} + +/* AtkAction implementation */ +static void +cally_actor_action_interface_init (AtkActionIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->do_action = cally_actor_action_do_action; + iface->get_n_actions = cally_actor_action_get_n_actions; + iface->get_description = cally_actor_action_get_description; + iface->get_keybinding = cally_actor_action_get_keybinding; + iface->get_name = cally_actor_action_get_name; + iface->set_description = cally_actor_action_set_description; +} + +static gboolean +cally_actor_action_do_action (AtkAction *action, + gint index) +{ + ClutterActor *actor = NULL; + CallyActor *cally_actor = NULL; + AtkStateSet *set = NULL; + CallyActorPrivate *priv = NULL; + CallyActorActionInfo *info = NULL; + + cally_actor = CALLY_ACTOR (action); + priv = cally_actor->priv; + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + + set = atk_object_ref_state_set (ATK_OBJECT (cally_actor)); + + if (atk_state_set_contains_state (set, ATK_STATE_DEFUNCT)) + return FALSE; + + if (!atk_state_set_contains_state (set, ATK_STATE_SENSITIVE) || + !atk_state_set_contains_state (set, ATK_STATE_SHOWING)) + return FALSE; + + g_object_unref (set); + + info = _cally_actor_get_action_info (cally_actor, index); + + if (info == NULL) + return FALSE; + + if (info->do_action_func == NULL) + return FALSE; + + if (!priv->action_queue) + priv->action_queue = g_queue_new (); + + g_queue_push_head (priv->action_queue, info); + + if (!priv->action_idle_handler) + priv->action_idle_handler = g_idle_add (idle_do_action, cally_actor); + + return TRUE; +} + +static gboolean +idle_do_action (gpointer data) +{ + CallyActor *cally_actor = NULL; + CallyActorPrivate *priv = NULL; + ClutterActor *actor = NULL; + + cally_actor = CALLY_ACTOR (data); + priv = cally_actor->priv; + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + priv->action_idle_handler = 0; + + if (actor == NULL) /* state is defunct*/ + return FALSE; + + while (!g_queue_is_empty (priv->action_queue)) + { + CallyActorActionInfo *info = NULL; + + info = (CallyActorActionInfo *) g_queue_pop_head (priv->action_queue); + + info->do_action_func (cally_actor); + } + + return FALSE; +} + +static gint +cally_actor_action_get_n_actions (AtkAction *action) +{ + CallyActor *cally_actor = NULL; + CallyActorPrivate *priv = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (action), 0); + + cally_actor = CALLY_ACTOR (action); + priv = cally_actor->priv; + + return g_list_length (priv->action_list); +} + +static G_CONST_RETURN gchar* +cally_actor_action_get_name (AtkAction *action, + gint i) +{ + CallyActor *cally_actor = NULL; + CallyActorActionInfo *info = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (action), NULL); + cally_actor = CALLY_ACTOR (action); + info = _cally_actor_get_action_info (cally_actor, i); + + if (info == NULL) + return NULL; + + return info->name; +} + +static G_CONST_RETURN gchar* +cally_actor_action_get_description (AtkAction *action, + gint i) +{ + CallyActor *cally_actor = NULL; + CallyActorActionInfo *info = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (action), NULL); + cally_actor = CALLY_ACTOR (action); + info = _cally_actor_get_action_info (cally_actor, i); + + if (info == NULL) + return NULL; + + return info->description; +} + +static gboolean +cally_actor_action_set_description (AtkAction *action, + gint i, + const gchar *desc) +{ + CallyActor *cally_actor = NULL; + CallyActorActionInfo *info = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (action), FALSE); + cally_actor = CALLY_ACTOR (action); + info = _cally_actor_get_action_info (cally_actor, i); + + if (info == NULL) + return FALSE; + + g_free (info->description); + info->description = g_strdup (desc); + + return TRUE; +} + +static G_CONST_RETURN gchar* +cally_actor_action_get_keybinding (AtkAction *action, + gint i) +{ + CallyActor *cally_actor = NULL; + CallyActorActionInfo *info = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (action), NULL); + cally_actor = CALLY_ACTOR (action); + info = _cally_actor_get_action_info (cally_actor, i); + + if (info == NULL) + return NULL; + + return info->keybinding; +} + +/* Misc functions */ + +/** + * Checks if the parent actor, and his parent, etc is all visible + * Used to check the showing property + * + * FIXME: the same functionality is implemented on clutter since version 0.8.4 + * by clutter_actor_get_paint_visibility, so we should change this function + * if a clutter version update is made + **/ +static gboolean +_cally_actor_all_parents_visible (ClutterActor *actor) +{ + ClutterActor *iter_parent = NULL; + gboolean result = TRUE; + ClutterActor *stage = NULL; + + stage = clutter_actor_get_stage (actor); + + for (iter_parent = clutter_actor_get_parent(actor); iter_parent; + iter_parent = clutter_actor_get_parent(iter_parent)) + { + if (!CLUTTER_ACTOR_IS_VISIBLE (iter_parent)) + { + /* stage parent */ + if (iter_parent != stage) + result = FALSE; + else + result = TRUE; + + break; + } + } + + return result; +} + +/* + * This function is a signal handler for key_focus_in and + * key_focus_out signal which gets emitted on a ClutterActor + */ +static gboolean +cally_actor_focus_clutter (ClutterActor *actor, + gpointer data) +{ + CallyActor *cally_actor = NULL; + CallyActorClass *klass = NULL; + + cally_actor = CALLY_ACTOR (clutter_actor_get_accessible (actor)); + klass = CALLY_ACTOR_GET_CLASS (cally_actor); + if (klass->focus_clutter) + return klass->focus_clutter (actor, data); + else + return FALSE; +} + +static gboolean +cally_actor_real_focus_clutter (ClutterActor *actor, + gpointer data) +{ + CallyActor *cally_actor = NULL; + gboolean return_val = FALSE; + gboolean in = FALSE; + + in = GPOINTER_TO_INT (data); + cally_actor = CALLY_ACTOR (clutter_actor_get_accessible (actor)); + + g_signal_emit_by_name (cally_actor, "focus_event", in, &return_val); + atk_focus_tracker_notify (ATK_OBJECT (cally_actor)); + + return FALSE; +} + +/* + * This function is a signal handler for notify signal which gets emitted + * when a property changes value on the ClutterActor associated with the object. + * + * It calls a function for the CallyActor type + */ +static void +cally_actor_notify_clutter (GObject *obj, + GParamSpec *pspec) +{ + CallyActor *cally_actor = NULL; + CallyActorClass *klass = NULL; + + cally_actor = CALLY_ACTOR (clutter_actor_get_accessible (CLUTTER_ACTOR (obj))); + klass = CALLY_ACTOR_GET_CLASS (cally_actor); + + if (klass->notify_clutter) + klass->notify_clutter (obj, pspec); +} + +/* + * This function is a signal handler for notify signal which gets emitted + * when a property changes value on the ClutterActor associated with a CallyActor + * + * It constructs an AtkPropertyValues structure and emits a "property_changed" + * signal which causes the user specified AtkPropertyChangeHandler + * to be called. + */ +static void +cally_actor_real_notify_clutter (GObject *obj, + GParamSpec *pspec) +{ + ClutterActor* actor = CLUTTER_ACTOR (obj); + AtkObject* atk_obj = clutter_actor_get_accessible (CLUTTER_ACTOR(obj)); + AtkState state; + gboolean value; + + if (strcmp (pspec->name, "visible") == 0) + { + state = ATK_STATE_VISIBLE; + value = CLUTTER_ACTOR_IS_VISIBLE (actor); + } + else if (strcmp (pspec->name, "reactive") == 0) + { + state = ATK_STATE_SENSITIVE; + value = CLUTTER_ACTOR_IS_REACTIVE (actor); + } + else + return; + + atk_object_notify_state_change (atk_obj, state, value); +} + +static void +cally_actor_focus_event (AtkObject *obj, + gboolean focus_in) +{ + atk_object_notify_state_change (obj, ATK_STATE_FOCUSED, focus_in); +} + + +static void +_cally_actor_clean_action_list (CallyActor *cally_actor) +{ + CallyActorPrivate *priv = NULL; + + priv = cally_actor->priv; + + if (priv->action_list) + { + g_list_foreach (priv->action_list, + (GFunc) _cally_actor_destroy_action_info, + NULL); + g_list_free (priv->action_list); + priv->action_list = NULL; + } +} + +static CallyActorActionInfo * +_cally_actor_get_action_info (CallyActor *cally_actor, + gint index) +{ + CallyActorPrivate *priv = NULL; + GList *node = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), NULL); + + priv = cally_actor->priv; + + if (priv->action_list == NULL) + return NULL; + + node = g_list_nth (priv->action_list, index); + + if (node == NULL) + return NULL; + + return (CallyActorActionInfo *)(node->data); +} + +static void +_cally_actor_click_action (CallyActor *cally_actor) +{ + ClutterEvent tmp_event; + ClutterActor *stage = NULL; + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + stage = clutter_actor_get_stage (actor); + + /* press */ + tmp_event.button.type = CLUTTER_BUTTON_PRESS; + tmp_event.button.time = CLUTTER_CURRENT_TIME; + tmp_event.button.stage = CLUTTER_STAGE (stage); + tmp_event.button.source = actor; + tmp_event.button.button = 1; + + clutter_actor_event (actor, &tmp_event, FALSE); + + /* release */ + tmp_event.button.type = CLUTTER_BUTTON_RELEASE; + + clutter_actor_event (actor, &tmp_event, FALSE); +} + +static void +_cally_actor_press_action (CallyActor *cally_actor) +{ + ClutterEvent tmp_event; + ClutterActor *stage = NULL; + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + stage = clutter_actor_get_stage (actor); + + tmp_event.button.type = CLUTTER_BUTTON_PRESS; + tmp_event.button.time = CLUTTER_CURRENT_TIME; + tmp_event.button.stage = CLUTTER_STAGE (stage); + tmp_event.button.source = actor; + tmp_event.button.button = 1; + + clutter_actor_event (actor, &tmp_event, FALSE); +} + +static void +_cally_actor_release_action (CallyActor *cally_actor) +{ + ClutterEvent tmp_event; + ClutterActor *stage = NULL; + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + stage = clutter_actor_get_stage (actor); + + tmp_event.button.type = CLUTTER_BUTTON_RELEASE; + tmp_event.button.time = CLUTTER_CURRENT_TIME; + tmp_event.button.stage = CLUTTER_STAGE (stage); + tmp_event.button.source = actor; + tmp_event.button.button = 1; + + clutter_actor_event (actor, &tmp_event, FALSE); +} + +/** + * cally_actor_add_action: + * @action_name: the action name + * @action_description: the action description + * @action_keybinding: the action keybinding + * @action_func: the callback of the action, to be executed with do_action + * + * Adds a new action to be accessed with the AtkAction interface. + * + * Return value: added action id, or 0 if failure + * + * Since: 1.2 + */ +guint +cally_actor_add_action (CallyActor *cally_actor, + const gchar *action_name, + const gchar *action_description, + const gchar *action_keybinding, + CallyActionFunc action_func) +{ + CallyActorActionInfo *info = NULL; + CallyActorPrivate *priv = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), -1); + g_return_val_if_fail (action_func != NULL, -1); + + priv = cally_actor->priv; + + info = g_new (CallyActorActionInfo, 1); + + if (action_name != NULL) + info->name = g_strdup (action_name); + else + info->name = NULL; + + if (action_description != NULL) + info->description = g_strdup (action_description); + else + info->description = NULL; + + if (action_keybinding != NULL) + info->keybinding = g_strdup (action_keybinding); + else + info->keybinding = NULL; + + info->do_action_func = action_func; + + priv->action_list = g_list_append (priv->action_list, (gpointer) info); + + return g_list_length (priv->action_list); +} + +/** + * cally_actor_remove_action: + * @action_id: the action id + * + * Removes a action, using the @action_id returned by cally_actor_add_action + * + * Return value: TRUE if the operation was succesful, FALSE otherwise + * + * Since: 1.2 + */ +gboolean +cally_actor_remove_action (CallyActor *cally_actor, + gint action_id) +{ + GList *list_node = NULL; + CallyActorPrivate *priv = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), FALSE); + priv = cally_actor->priv; + + list_node = g_list_nth (priv->action_list, action_id - 1); + + if (!list_node) + return FALSE; + + _cally_actor_destroy_action_info (list_node->data, NULL); + + priv->action_list = g_list_remove_link (priv->action_list, list_node); + + return TRUE; +} + +/** + * cally_actor_remove_action: + * @action_name: the name of the action + * + * Removes a action, using the @action_name used when the action was added + * with cally_actor_add_action + * + * Return value: TRUE if the operation was succesful, FALSE otherwise + * + * Since: 1.2 + */ +gboolean +cally_actor_remove_action_by_name (CallyActor *cally_actor, + const gchar *action_name) +{ + GList *node = NULL; + gboolean action_found = FALSE; + CallyActorPrivate *priv = NULL; + + g_return_val_if_fail (CALLY_IS_ACTOR (cally_actor), FALSE); + priv = CALLY_ACTOR (cally_actor)->priv; + + for (node = priv->action_list; node && !action_found; + node = node->next) + { + if (!g_strcasecmp (((CallyActorActionInfo *)(node->data))->name, action_name)) + { + action_found = TRUE; + break; + } + } + if (!action_found) + return FALSE; + + _cally_actor_destroy_action_info (node->data, NULL); + priv->action_list = g_list_remove_link (priv->action_list, node); + + return TRUE; +} + + +static void +_cally_actor_destroy_action_info (gpointer action_info, + gpointer user_data) +{ + CallyActorActionInfo *info = (CallyActorActionInfo *)action_info; + + g_assert (info != NULL); + + g_free (info->name); + g_free (info->description); + g_free (info->keybinding); + + g_free (info); +} diff --git a/clutter/cally/cally-actor.h b/clutter/cally/cally-actor.h new file mode 100644 index 000000000..707845903 --- /dev/null +++ b/clutter/cally/cally-actor.h @@ -0,0 +1,108 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Some parts are based on GailWidget from GAIL + * GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_ACTOR_H__ +#define __CALLY_ACTOR_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CALLY_TYPE_ACTOR (cally_actor_get_type ()) +#define CALLY_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_ACTOR, CallyActor)) +#define CALLY_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_ACTOR, CallyActorClass)) +#define CALLY_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_ACTOR)) +#define CALLY_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_ACTOR)) +#define CALLY_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_ACTOR, CallyActorClass)) + +typedef struct _CallyActor CallyActor; +typedef struct _CallyActorClass CallyActorClass; +typedef struct _CallyActorPrivate CallyActorPrivate; + +/** + * CallyActionFunc: + * @cally_actor: a #CallyActor + * + * Action func, to be used on AtkAction implementation as a individual + * action + */ +typedef void (*CallyActionFunc) (CallyActor *cally_actor); + +struct _CallyActor +{ + AtkGObjectAccessible parent; + + /* < private > */ + CallyActorPrivate *priv; +}; + +struct _CallyActorClass +{ + AtkGObjectAccessibleClass parent_class; + + /* Signal handler for notify signal on Clutter Actor */ + void (*notify_clutter) (GObject *object, + GParamSpec *pspec); + + /* + * Signal handler for key_focus_in and key_focus_out on Clutter Actor + */ + gboolean (*focus_clutter) (ClutterActor *actor, + gpointer data); + + gint (*add_actor) (ClutterActor *container, + ClutterActor *actor, + gpointer data); + + gint (*remove_actor) (ClutterActor *container, + ClutterActor *actor, + gpointer data); + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + + +GType cally_actor_get_type (void); + +AtkObject* cally_actor_new (ClutterActor *actor); +guint cally_actor_add_action (CallyActor *cally_actor, + const gchar *action_name, + const gchar *action_description, + const gchar *action_keybinding, + CallyActionFunc action_func); + +gboolean cally_actor_remove_action (CallyActor *cally_actor, + gint action_id); + +gboolean cally_actor_remove_action_by_name (CallyActor *cally_actor, + const gchar *action_name); + + +G_END_DECLS + +#endif /* __CALLY_ACTOR_H__ */ diff --git a/clutter/cally/cally-clone.c b/clutter/cally/cally-clone.c new file mode 100644 index 000000000..0bde12053 --- /dev/null +++ b/clutter/cally/cally-clone.c @@ -0,0 +1,105 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2010 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:callyclutterclone + * @short_description: Implementation of the ATK interfaces for a #ClutterClone + * @see_also: #ClutterClone + * + * #CallyClutterClone implements the required ATK interfaces of #ClutterClone + * + * In particular it sets a proper role for the clone, as just a image, + * as it is the sanest and simplest approach. + * + * Check http://lists.o-hand.com/clutter/3797.html for more information + */ + +#include "cally-clone.h" +#include "cally-actor-private.h" + +#define CALLY_CLONE_DEFAULT_DESCRIPTION "ClutterClone accessibility object" + +static void cally_clone_class_init (CallyCloneClass *klass); +static void cally_clone_init (CallyClone *clone); + +/* AtkObject */ +static void cally_clone_real_initialize (AtkObject *obj, + gpointer data); +static G_CONST_RETURN gchar *cally_clone_get_description (AtkObject *obj); + + +G_DEFINE_TYPE (CallyClone, cally_clone, CALLY_TYPE_ACTOR) + +static void +cally_clone_class_init (CallyCloneClass *klass) +{ +/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + class->initialize = cally_clone_real_initialize; + class->get_description = cally_clone_get_description; +} + +static void +cally_clone_init (CallyClone *clone) +{ + /* nothing to do yet */ +} + +AtkObject* +cally_clone_new (ClutterActor *actor) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + + g_return_val_if_fail (CLUTTER_IS_CLONE (actor), NULL); + + object = g_object_new (CALLY_TYPE_CLONE, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, actor); + + return accessible; +} + +static void +cally_clone_real_initialize (AtkObject *obj, + gpointer data) +{ + ATK_OBJECT_CLASS (cally_clone_parent_class)->initialize (obj, data); + + obj->role = ATK_ROLE_IMAGE; +} + +static G_CONST_RETURN gchar * +cally_clone_get_description (AtkObject *obj) +{ + G_CONST_RETURN gchar *description = NULL; + + g_return_val_if_fail (CALLY_IS_CLONE (obj), NULL); + + description = ATK_OBJECT_CLASS (cally_clone_parent_class)->get_description (obj); + if (description == NULL) + description = CALLY_CLONE_DEFAULT_DESCRIPTION; + + return description; +} diff --git a/clutter/cally/cally-clone.h b/clutter/cally/cally-clone.h new file mode 100644 index 000000000..7b63dbeae --- /dev/null +++ b/clutter/cally/cally-clone.h @@ -0,0 +1,63 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2010 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_CLONE_H__ +#define __CALLY_CLONE_H__ + +#include "cally-actor.h" + +G_BEGIN_DECLS + +#define CALLY_TYPE_CLONE (cally_clone_get_type ()) +#define CALLY_CLONE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_CLONE, CallyClone)) +#define CALLY_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_CLONE, CallyCloneClass)) +#define CALLY_IS_CLONE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_CLONE)) +#define CALLY_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_CLONE)) +#define CALLY_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_CLONE, CallyCloneClass)) + + +typedef struct _CallyClone CallyClone; +typedef struct _CallyCloneClass CallyCloneClass; +typedef struct _CallyClonePrivate CallyClonePrivate; + +struct _CallyClone +{ + CallyActor parent; + + /* < private > */ + CallyClonePrivate *priv; +}; + +struct _CallyCloneClass +{ + CallyActorClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_clone_get_type (void); +AtkObject *cally_clone_new (ClutterActor *actor); + +G_END_DECLS + +#endif /* __CALLY_CLONE_H__ */ diff --git a/clutter/cally/cally-factory.h b/clutter/cally/cally-factory.h new file mode 100644 index 000000000..37e0219c2 --- /dev/null +++ b/clutter/cally/cally-factory.h @@ -0,0 +1,91 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Based on gailfactory.h from GAIL + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _CALLY_FACTORY_H__ +#define _CALLY_FACTORY_H__ + +#include +#include + +#define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \ + \ +static GType \ +type_as_function ## _factory_get_accessible_type (void) \ +{ \ + return type; \ +} \ + \ +static AtkObject* \ +type_as_function ## _factory_create_accessible (GObject *obj) \ +{ \ + ClutterActor *actor; \ + AtkObject *accessible; \ + \ + g_return_val_if_fail (CLUTTER_ACTOR (obj), NULL); \ + \ + actor = CLUTTER_ACTOR (obj); \ + \ + accessible = opt_create_accessible (actor); \ + \ + return accessible; \ +} \ + \ +static void \ +type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass) \ +{ \ + klass->create_accessible = type_as_function ## _factory_create_accessible; \ + klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\ +} \ + \ +static GType \ +type_as_function ## _factory_get_type (void) \ +{ \ + static GType t = 0; \ + \ + if (!t) \ + { \ + char *name; \ + static const GTypeInfo tinfo = \ + { \ + sizeof (AtkObjectFactoryClass), \ + NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init, \ + NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL \ + }; \ + \ + name = g_strconcat (g_type_name (type), "Factory", NULL); \ + t = g_type_register_static ( \ + ATK_TYPE_OBJECT_FACTORY, name, &tinfo, 0); \ + g_free (name); \ + } \ + \ + return t; \ +} + +#define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \ + atk_registry_set_factory_type (atk_get_default_registry (), \ + widget_type, \ + type_as_function ## _factory_get_type ()) + +#endif /* _CALLY_FACTORY_H__ */ diff --git a/clutter/cally/cally-group.c b/clutter/cally/cally-group.c new file mode 100644 index 000000000..ddcd9f81d --- /dev/null +++ b/clutter/cally/cally-group.c @@ -0,0 +1,138 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Based on GailContainer from GAIL + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:callycluttergroup + * @short_description: Implementation of the ATK interfaces for a #ClutterGroup + * @see_also: #ClutterGroup + * + * #CallyClutterGroup implements the required ATK interfaces of #ClutterGroup + * In particular it exposes: + * + * Each of the Clutter actors contained in the Clutter Group. + * + */ + +#include "cally-group.h" +#include "cally-actor-private.h" + +static void cally_group_class_init (CallyGroupClass *klass); +static void cally_group_init (CallyGroup *group); +static gint cally_group_get_n_children (AtkObject *obj); +static AtkObject* cally_group_ref_child (AtkObject *obj, + gint i); +static void cally_group_real_initialize (AtkObject *obj, + gpointer data); + +G_DEFINE_TYPE (CallyGroup, cally_group, CALLY_TYPE_ACTOR) + +static void +cally_group_class_init (CallyGroupClass *klass) +{ +/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + class->get_n_children = cally_group_get_n_children; + class->ref_child = cally_group_ref_child; + class->initialize = cally_group_real_initialize; +} + +static void +cally_group_init (CallyGroup *group) +{ + /* nothing to do yet */ +} + +AtkObject* +cally_group_new (ClutterActor *actor) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + + g_return_val_if_fail (CLUTTER_IS_GROUP (actor), NULL); + + object = g_object_new (CALLY_TYPE_GROUP, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, actor); + + return accessible; +} + +static gint +cally_group_get_n_children (AtkObject *obj) +{ + ClutterActor *actor = NULL; + gint count = 0; + + g_return_val_if_fail (CALLY_IS_GROUP (obj), count); + + actor = CALLY_GET_CLUTTER_ACTOR (obj); + + if (actor == NULL) /* defunct */ + return 0; + + g_return_val_if_fail (CLUTTER_IS_GROUP(actor), count); + + count = clutter_group_get_n_children (CLUTTER_GROUP (actor)); + + return count; +} + +static AtkObject* +cally_group_ref_child (AtkObject *obj, + gint i) +{ + AtkObject *accessible = NULL; + ClutterActor *actor = NULL; + ClutterActor *child = NULL; + + g_return_val_if_fail (CALLY_IS_GROUP (obj), NULL); + g_return_val_if_fail ((i >= 0), NULL); + + actor = CALLY_GET_CLUTTER_ACTOR (obj); + + g_return_val_if_fail (CLUTTER_IS_GROUP(actor), NULL); + child = clutter_group_get_nth_child (CLUTTER_GROUP(actor), i); + + if (!child) + return NULL; + + accessible = clutter_actor_get_accessible (child); + + if (accessible != NULL) + g_object_ref (accessible); + + return accessible; +} + +static void +cally_group_real_initialize (AtkObject *obj, + gpointer data) +{ + ATK_OBJECT_CLASS (cally_group_parent_class)->initialize (obj, data); + + obj->role = ATK_ROLE_PANEL; +} diff --git a/clutter/cally/cally-group.h b/clutter/cally/cally-group.h new file mode 100644 index 000000000..86920030d --- /dev/null +++ b/clutter/cally/cally-group.h @@ -0,0 +1,65 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Based on GailContainer from GAIL + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_GROUP_H__ +#define __CALLY_GROUP_H__ + +#include "cally-actor.h" + +G_BEGIN_DECLS + +#define CALLY_TYPE_GROUP (cally_group_get_type ()) +#define CALLY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_GROUP, CallyGroup)) +#define CALLY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_GROUP, CallyGroupClass)) +#define CALLY_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_GROUP)) +#define CALLY_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_GROUP)) +#define CALLY_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_GROUP, CallyGroupClass)) + +typedef struct _CallyGroup CallyGroup; +typedef struct _CallyGroupClass CallyGroupClass; +typedef struct _CallyGroupPrivate CallyGroupPrivate; + +struct _CallyGroup +{ + CallyActor parent; + + /* < private > */ + CallyGroupPrivate *priv; +}; + +struct _CallyGroupClass +{ + CallyActorClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_group_get_type (void); +AtkObject* cally_group_new (ClutterActor *actor); + +G_END_DECLS + +#endif /* __CALLY_GROUP_H__ */ diff --git a/clutter/cally/cally-rectangle.c b/clutter/cally/cally-rectangle.c new file mode 100644 index 000000000..934beb996 --- /dev/null +++ b/clutter/cally/cally-rectangle.c @@ -0,0 +1,102 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:callyclutterrectangle + * @short_description: Implementation of the ATK interfaces for a #ClutterRectangle + * @see_also: #ClutterRectangle + * + * #CallyClutterRectangle implements the required ATK interfaces of #ClutterRectangle + * + * In particular it sets a proper role for the rectangle. + */ + +#include "cally-rectangle.h" +#include "cally-actor-private.h" + +#define CALLY_RECTANGLE_DEFAULT_DESCRIPTION "A rectangle" + +static void cally_rectangle_class_init (CallyRectangleClass *klass); +static void cally_rectangle_init (CallyRectangle *rectangle); + +/* AtkObject */ +static void cally_rectangle_real_initialize (AtkObject *obj, + gpointer data); +static G_CONST_RETURN gchar *cally_rectangle_get_description (AtkObject *obj); + + +G_DEFINE_TYPE (CallyRectangle, cally_rectangle, CALLY_TYPE_ACTOR) + +static void +cally_rectangle_class_init (CallyRectangleClass *klass) +{ +/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + class->initialize = cally_rectangle_real_initialize; + class->get_description = cally_rectangle_get_description; +} + +static void +cally_rectangle_init (CallyRectangle *rectangle) +{ + /* nothing to do yet */ +} + +AtkObject* +cally_rectangle_new (ClutterActor *actor) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + + g_return_val_if_fail (CLUTTER_IS_RECTANGLE (actor), NULL); + + object = g_object_new (CALLY_TYPE_RECTANGLE, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, actor); + + return accessible; +} + +static void +cally_rectangle_real_initialize (AtkObject *obj, + gpointer data) +{ + ATK_OBJECT_CLASS (cally_rectangle_parent_class)->initialize (obj, data); + + obj->role = ATK_ROLE_IMAGE; +} + +static G_CONST_RETURN gchar * +cally_rectangle_get_description (AtkObject *obj) +{ + G_CONST_RETURN gchar *description = NULL; + + g_return_val_if_fail (CALLY_IS_RECTANGLE (obj), NULL); + + description = ATK_OBJECT_CLASS (cally_rectangle_parent_class)->get_description (obj); + if (description == NULL) + description = CALLY_RECTANGLE_DEFAULT_DESCRIPTION; + + return description; +} diff --git a/clutter/cally/cally-rectangle.h b/clutter/cally/cally-rectangle.h new file mode 100644 index 000000000..b2230c311 --- /dev/null +++ b/clutter/cally/cally-rectangle.h @@ -0,0 +1,63 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_RECTANGLE_H__ +#define __CALLY_RECTANGLE_H__ + +#include "cally-actor.h" + +G_BEGIN_DECLS + +#define CALLY_TYPE_RECTANGLE (cally_rectangle_get_type ()) +#define CALLY_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_RECTANGLE, CallyRectangle)) +#define CALLY_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_RECTANGLE, CallyRectangleClass)) +#define CALLY_IS_RECTANGLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_RECTANGLE)) +#define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE)) +#define CALLY_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass)) + + +typedef struct _CallyRectangle CallyRectangle; +typedef struct _CallyRectangleClass CallyRectangleClass; +typedef struct _CallyRectanglePrivate CallyRectanglePrivate; + +struct _CallyRectangle +{ + CallyActor parent; + + /* < private > */ + CallyRectanglePrivate *priv; +}; + +struct _CallyRectangleClass +{ + CallyActorClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_rectangle_get_type (void); +AtkObject* cally_rectangle_new (ClutterActor *actor); + +G_END_DECLS + +#endif /* __CALLY_RECTANGLE_H__ */ diff --git a/clutter/cally/cally-root.c b/clutter/cally/cally-root.c new file mode 100644 index 000000000..b7897534a --- /dev/null +++ b/clutter/cally/cally-root.c @@ -0,0 +1,273 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:callyroot + * @short_description: Root object for the CALLY toolkit + * @see_also: #ClutterStage + * + * #CallyRoot is the root object of the accessibility tree-like + * hierarchy, exposing the application level. + * + * Somewhat equivalent to GailTopLevel. We consider that this class + * expose the a11y information of the ClutterStageManager, as the + * children of this object are the different ClutterStage managed (so + * the GObject used in the atk_object_initialize is the + * ClutterStageManager). + * + */ + +#include +#include "cally-root.h" + +/* GObject */ +static void cally_root_class_init (CallyRootClass *klass); +static void cally_root_init (CallyRoot *root); +static void cally_root_finalize (GObject *object); + +/* AtkObject.h */ +static void cally_root_initialize (AtkObject *accessible, + gpointer data); +static gint cally_root_get_n_children (AtkObject *obj); +static AtkObject *cally_root_ref_child (AtkObject *obj, + gint i); +static AtkObject *cally_root_get_parent (AtkObject *obj); + +/* Private */ +static void cally_util_stage_added_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data); +static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data); + +#define CALLY_ROOT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CALLY_TYPE_ROOT, CallyRootPrivate)) + +G_DEFINE_TYPE (CallyRoot, cally_root, ATK_TYPE_GOBJECT_ACCESSIBLE) + +struct _CallyRootPrivate +{ +/* We save the CallyStage objects. Other option could save the stage + * list, and then just get the a11y object on the ref_child, etc. But + * the ref_child is more common that the init and the stage-add, + * stage-remove, so we avoid getting the accessible object + * constantly + */ + GSList *stage_list; + + /* signals id */ + guint stage_added_id; + guint stage_removed_id; +}; + +static void +cally_root_class_init (CallyRootClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + gobject_class->finalize = cally_root_finalize; + + /* AtkObject */ + class->get_n_children = cally_root_get_n_children; + class->ref_child = cally_root_ref_child; + class->get_parent = cally_root_get_parent; + class->initialize = cally_root_initialize; + + g_type_class_add_private (gobject_class, sizeof (CallyRootPrivate)); +} + +static void +cally_root_init (CallyRoot *root) +{ + root->priv = CALLY_ROOT_GET_PRIVATE (root); + + root->priv->stage_list = NULL; + root->priv->stage_added_id = 0; + root->priv->stage_removed_id = 0; +} + +AtkObject* +cally_root_new (void) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + ClutterStageManager *stage_manager = NULL; + + object = g_object_new (CALLY_TYPE_ROOT, NULL); + + accessible = ATK_OBJECT (object); + stage_manager = clutter_stage_manager_get_default (); + + atk_object_initialize (accessible, stage_manager); + + return accessible; +} + +static void +cally_root_finalize (GObject *object) +{ + CallyRoot *root = CALLY_ROOT (object); + GObject *stage_manager = NULL; + + g_return_if_fail (CALLY_IS_ROOT (object)); + + if (root->priv->stage_list) + { + g_slist_free (root->priv->stage_list); + root->priv->stage_list = NULL; + } + + stage_manager = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (root)); + + g_signal_handler_disconnect (stage_manager, + root->priv->stage_added_id); + + g_signal_handler_disconnect (stage_manager, + root->priv->stage_added_id); + + G_OBJECT_CLASS (cally_root_parent_class)->finalize (object); +} + +/* AtkObject.h */ +static void +cally_root_initialize (AtkObject *accessible, + gpointer data) +{ + ClutterStageManager *stage_manager = NULL; + const GSList *iter = NULL; + const GSList *stage_list = NULL; + ClutterStage *clutter_stage = NULL; + AtkObject *cally_stage = NULL; + CallyRoot *root = NULL; + + accessible->role = ATK_ROLE_APPLICATION; + accessible->name = g_get_prgname(); + accessible->accessible_parent = NULL; + + /* children initialization */ + root = CALLY_ROOT (accessible); + stage_manager = CLUTTER_STAGE_MANAGER (data); + stage_list = clutter_stage_manager_peek_stages (stage_manager); + + for (iter = stage_list; iter != NULL; iter = g_slist_next (iter)) + { + clutter_stage = CLUTTER_STAGE (iter->data); + cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (clutter_stage)); + + root->priv->stage_list = g_slist_append (root->priv->stage_list, + cally_stage); + } + + root->priv->stage_added_id = + g_signal_connect (G_OBJECT (stage_manager), "stage-added", + G_CALLBACK (cally_util_stage_added_cb), root); + + root->priv->stage_removed_id = + g_signal_connect (G_OBJECT (stage_manager), "stage-removed", + G_CALLBACK (cally_util_stage_removed_cb), root); + + ATK_OBJECT_CLASS (cally_root_parent_class)->initialize (accessible, data); +} + + +static gint +cally_root_get_n_children (AtkObject *obj) +{ + CallyRoot *root = CALLY_ROOT (obj); + + return g_slist_length (root->priv->stage_list); +} + +static AtkObject* +cally_root_ref_child (AtkObject *obj, + gint i) +{ + CallyRoot *cally_root = NULL; + GSList *stage_list = NULL; + gint num = 0; + AtkObject *item = NULL; + + cally_root = CALLY_ROOT (obj); + stage_list = cally_root->priv->stage_list; + num = g_slist_length (stage_list); + + g_return_val_if_fail ((i < num)&&(i >= 0), NULL); + + item = g_slist_nth_data (stage_list, i); + if (!item) + { + return NULL; + } + + g_object_ref (item); + + return item; +} + +static AtkObject* +cally_root_get_parent (AtkObject *obj) +{ + return NULL; +} + +/* -------------------------------- PRIVATE --------------------------------- */ + +static void +cally_util_stage_added_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data) +{ + CallyRoot *root = CALLY_ROOT (data); + AtkObject *cally_stage = NULL; + gint index = -1; + + cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); + + root->priv->stage_list = g_slist_append (root->priv->stage_list, + cally_stage); + + index = g_slist_index (root->priv->stage_list, cally_stage); + g_signal_emit_by_name (root, "children_changed::add", + index, cally_stage, NULL); +} + +static void +cally_util_stage_removed_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data) +{ + CallyRoot *root = CALLY_ROOT (data); + AtkObject *cally_stage = NULL; + gint index = -1; + + cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); + + index = g_slist_index (root->priv->stage_list, cally_stage); + + root->priv->stage_list = g_slist_remove (root->priv->stage_list, + cally_stage); + + index = g_slist_index (root->priv->stage_list, cally_stage); + g_signal_emit_by_name (root, "children_changed::remove", + index, cally_stage, NULL); +} diff --git a/clutter/cally/cally-root.h b/clutter/cally/cally-root.h new file mode 100644 index 000000000..540a74282 --- /dev/null +++ b/clutter/cally/cally-root.h @@ -0,0 +1,64 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_ROOT_H__ +#define __CALLY_ROOT_H__ + +#include + +G_BEGIN_DECLS + +#define CALLY_TYPE_ROOT (cally_root_get_type ()) +#define CALLY_ROOT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_ROOT, CallyRoot)) +#define CALLY_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_ROOT, CallyRootClass)) +#define CALLY_IS_ROOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_ROOT)) +#define CALLY_IS_ROOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_ROOT)) +#define CALLY_ROOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_ROOT, CallyRootClass)) + +typedef struct _CallyRoot CallyRoot; +typedef struct _CallyRootClass CallyRootClass; +typedef struct _CallyRootPrivate CallyRootPrivate; + +struct _CallyRoot +{ + AtkGObjectAccessible parent; + + /* < private > */ + CallyRootPrivate *priv; +}; + +struct _CallyRootClass +{ + AtkGObjectAccessibleClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + + +GType cally_root_get_type (void); +AtkObject *cally_root_new (void); + + +G_END_DECLS + +#endif /* __CALLY_ROOT_H__ */ diff --git a/clutter/cally/cally-stage.c b/clutter/cally/cally-stage.c new file mode 100644 index 000000000..57f037be4 --- /dev/null +++ b/clutter/cally/cally-stage.c @@ -0,0 +1,258 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:callystage + * @short_description: Implementation of the ATK interfaces for a #ClutterStage + * @see_also: #ClutterStage + * + * #CallyStage implements the required ATK interfaces of #ClutterStage + * + */ + +#include "cally-stage.h" +#include "cally-actor-private.h" + +enum { + ACTIVATE, + CREATE, + DEACTIVATE, + DESTROY, + LAST_SIGNAL +}; + +static guint cally_stage_signals [LAST_SIGNAL] = { 0, }; + +static void cally_stage_class_init (CallyStageClass *klass); +static void cally_stage_init (CallyStage *stage); + +/* AtkObject.h */ +static G_CONST_RETURN gchar *cally_stage_get_name (AtkObject *obj); +static G_CONST_RETURN gchar *cally_stage_get_description (AtkObject *obj); +static void cally_stage_real_initialize (AtkObject *obj, + gpointer data); +static AtkStateSet* cally_stage_ref_state_set (AtkObject *obj); + +/* Auxiliar */ +static void cally_stage_activate_cb (ClutterStage *stage, + gpointer data); +static void cally_stage_deactivate_cb (ClutterStage *stage, + gpointer data); + + +#define CALLY_STAGE_DEFAULT_NAME "Stage" +#define CALLY_STAGE_DEFAULT_DESCRIPTION "Top level 'window' on which child actors are placed and manipulated" + +G_DEFINE_TYPE (CallyStage, cally_stage, CALLY_TYPE_GROUP); + +#define CALLY_STAGE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CALLY_TYPE_STAGE, CallyStagePrivate)) + +struct _CallyStagePrivate +{ + gboolean active; +}; + +static void +cally_stage_class_init (CallyStageClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); +/* CallyActorClass *cally_class = CALLY_ACTOR_CLASS (klass); */ + + /* AtkObject */ + class->get_name = cally_stage_get_name; + class->get_description = cally_stage_get_description; + class->initialize = cally_stage_real_initialize; + class->ref_state_set = cally_stage_ref_state_set; + + g_type_class_add_private (gobject_class, sizeof (CallyStagePrivate)); + + cally_stage_signals [ACTIVATE] = + g_signal_new ("activate", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, /* default signal handler */ + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + cally_stage_signals [CREATE] = + g_signal_new ("create", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, /* default signal handler */ + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + cally_stage_signals [DEACTIVATE] = + g_signal_new ("deactivate", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, /* default signal handler */ + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + cally_stage_signals [DESTROY] = + g_signal_new ("destroy", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, /* default signal handler */ + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +cally_stage_init (CallyStage *cally_stage) +{ + CallyStagePrivate *priv = CALLY_STAGE_GET_PRIVATE (cally_stage); + + cally_stage->priv = priv; + + priv->active = FALSE; +} + +AtkObject* +cally_stage_new (ClutterActor *actor) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + + g_return_val_if_fail (CLUTTER_IS_STAGE (actor), NULL); + + object = g_object_new (CALLY_TYPE_STAGE, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, actor); + + return accessible; +} + +/* AtkObject.h */ +static G_CONST_RETURN gchar * +cally_stage_get_name (AtkObject *obj) +{ + G_CONST_RETURN gchar *name = NULL; + + g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL); + + /* parent name */ + name = ATK_OBJECT_CLASS (cally_stage_parent_class)->get_name (obj); + + if (name == NULL) + name = CALLY_STAGE_DEFAULT_NAME; + + return name; +} + +static G_CONST_RETURN gchar * +cally_stage_get_description (AtkObject *obj) +{ + G_CONST_RETURN gchar *description = NULL; + + g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL); + + /* parent description */ + description = ATK_OBJECT_CLASS (cally_stage_parent_class)->get_description (obj); + + if (description == NULL) + description = CALLY_STAGE_DEFAULT_DESCRIPTION; + + return description; +} + +static void +cally_stage_real_initialize (AtkObject *obj, + gpointer data) +{ + ClutterStage *stage = NULL; + + g_return_if_fail (CALLY_IS_STAGE (obj)); + + ATK_OBJECT_CLASS (cally_stage_parent_class)->initialize (obj, data); + + stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (obj)); + + g_signal_connect (stage, "activate", G_CALLBACK (cally_stage_activate_cb), obj); + g_signal_connect (stage, "deactivate", G_CALLBACK (cally_stage_deactivate_cb), obj); + + obj->role = ATK_ROLE_CANVAS; +} + +static AtkStateSet* +cally_stage_ref_state_set (AtkObject *obj) +{ + CallyStage *cally_stage = NULL; + AtkStateSet *state_set = NULL; + ClutterStage *stage = NULL; + + g_return_val_if_fail (CALLY_IS_STAGE (obj), NULL); + cally_stage = CALLY_STAGE (obj); + + state_set = ATK_OBJECT_CLASS (cally_stage_parent_class)->ref_state_set (obj); + stage = CLUTTER_STAGE (CALLY_GET_CLUTTER_ACTOR (cally_stage)); + + if (stage == NULL) + return state_set; + + if (cally_stage->priv->active) + atk_state_set_add_state (state_set, ATK_STATE_ACTIVE); + + return state_set; +} + +/* Auxiliar */ +static void +cally_stage_activate_cb (ClutterStage *stage, + gpointer data) +{ + CallyStage *cally_stage = NULL; + + g_return_if_fail (CALLY_IS_STAGE (data)); + + cally_stage = CALLY_STAGE (data); + + cally_stage->priv->active = TRUE; + + atk_object_notify_state_change (ATK_OBJECT (cally_stage), + ATK_STATE_ACTIVE, TRUE); + + g_signal_emit (cally_stage, cally_stage_signals [ACTIVATE], 0); +} + +static void +cally_stage_deactivate_cb (ClutterStage *stage, + gpointer data) +{ + CallyStage *cally_stage = NULL; + + g_return_if_fail (CALLY_IS_STAGE (data)); + + cally_stage = CALLY_STAGE (data); + + cally_stage->priv->active = FALSE; + + atk_object_notify_state_change (ATK_OBJECT (cally_stage), + ATK_STATE_ACTIVE, FALSE); + + g_signal_emit (cally_stage, cally_stage_signals [DEACTIVATE], 0); +} diff --git a/clutter/cally/cally-stage.h b/clutter/cally/cally-stage.h new file mode 100644 index 000000000..e95c08eed --- /dev/null +++ b/clutter/cally/cally-stage.h @@ -0,0 +1,62 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_STAGE_H__ +#define __CALLY_STAGE_H__ + +#include "cally-group.h" + +G_BEGIN_DECLS + +#define CALLY_TYPE_STAGE (cally_stage_get_type ()) +#define CALLY_STAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_STAGE, CallyStage)) +#define CALLY_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_STAGE, CallyStageClass)) +#define CALLY_IS_STAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_STAGE)) +#define CALLY_IS_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_STAGE)) +#define CALLY_STAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_STAGE, CallyStageClass)) + +typedef struct _CallyStage CallyStage; +typedef struct _CallyStageClass CallyStageClass; +typedef struct _CallyStagePrivate CallyStagePrivate; + +struct _CallyStage +{ + CallyGroup parent; + + /* < private > */ + CallyStagePrivate *priv; +}; + +struct _CallyStageClass +{ + CallyGroupClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_stage_get_type (void); +AtkObject *cally_stage_new (ClutterActor *actor); + +G_END_DECLS + +#endif /* __CALLY_STAGE_H__ */ diff --git a/clutter/cally/cally-text.c b/clutter/cally/cally-text.c new file mode 100644 index 000000000..bd55d299c --- /dev/null +++ b/clutter/cally/cally-text.c @@ -0,0 +1,1255 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Some parts are based on GailLabel, GailEntry, GailTextView from GAIL + * GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:cally-text + * @short_description: Implementation of the ATK interfaces for a #ClutterText + * @see_also: #ClutterText + * + * #CallyClutterText implements the required ATK interfaces of + * #ClutterText, #AtkText and #AtkEditableText + * + * + */ + +/** + * IMPLEMENTATION NOTES: + * + * * AtkText: There are still some methods not implemented yet: + * atk_text_get_default_attributes + * atk_text_get_character_extents + * atk_text_get_offset_at_point + * + * See details on bug CB#1733 + * + * * AtkEditableText: some methods will not be implemented + * + * * atk_editable_text_set_run_attributes: ClutterText has some + * properties equivalent to the AtkAttributte, but it doesn't + * allow you to define it by + * + * * atk_editable_text_copy: Clutter has no Clipboard support + * + * * atk_editable_text_paste: Clutter has no Clipboard support + * + * * atk_editable_text_cut: Clutter has no Clipboard support. In + * this case, as cut is basically a copy&delete combination, + * we could have implemented it using the delete, but IMHO, + * it would be weird to cut a text, get the text removed and + * then not be able to paste the text + * + * See details on bug CB#1734 + */ + +#include "cally-text.h" +#include "cally-actor-private.h" + +static void cally_text_class_init (CallyTextClass *klass); +static void cally_text_init (CallyText *cally_text); +static void cally_text_finalize (GObject *obj); + +/* AtkObject */ +static void cally_text_real_initialize (AtkObject *obj, + gpointer data); +static G_CONST_RETURN gchar * cally_text_get_name (AtkObject *obj); +static AtkStateSet* cally_text_ref_state_set (AtkObject *obj); + +/* atkaction */ + +static void _cally_text_activate_action (CallyActor *cally_actor); +static void _check_activate_action (CallyText *cally_text, + ClutterText *clutter_text); + +/* AtkText */ +static void cally_text_text_interface_init (AtkTextIface *iface); +static gchar* cally_text_get_text (AtkText *text, + gint start_offset, + gint end_offset); +static gunichar cally_text_get_character_at_offset (AtkText *text, + gint offset); +static gchar* cally_text_get_text_before_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset); +static gchar* cally_text_get_text_at_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset); +static gchar* cally_text_get_text_after_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset); +static gint cally_text_get_caret_offset (AtkText *text); +static gboolean cally_text_set_caret_offset (AtkText *text, + gint offset); +static gint cally_text_get_character_count (AtkText *text); +static gint cally_text_get_n_selections (AtkText *text); +static gchar* cally_text_get_selection (AtkText *text, + gint selection_num, + gint *start_offset, + gint *end_offset); +static gboolean cally_text_add_selection (AtkText *text, + gint start_offset, + gint end_offset); +static gboolean cally_text_remove_selection (AtkText *text, + gint selection_num); +static gboolean cally_text_set_selection (AtkText *text, + gint selection_num, + gint start_offset, + gint end_offset); +static AtkAttributeSet* cally_text_get_run_attributes (AtkText *text, + gint offset, + gint *start_offset, + gint *end_offset); +static void _cally_text_get_selection_bounds (ClutterText *clutter_text, + gint *start_offset, + gint *end_offset); +static void _cally_text_text_changed_cb (ClutterText *clutter_text, + gpointer data); +static void _cally_text_insert_text_cb (ClutterText *clutter_text, + gchar *new_text, + gint new_text_length, + gint *position, + gpointer data); +static void _cally_text_delete_text_cb (ClutterText *clutter_text, + gint start_pos, + gint end_pos, + gpointer data); +static gboolean _idle_notify_insert (gpointer data); +static void _notify_insert (CallyText *cally_text); +static void _notify_delete (CallyText *cally_text); + +/* AtkEditableText */ +static void cally_text_editable_text_interface_init (AtkEditableTextIface *iface); +static void cally_text_set_text_contents (AtkEditableText *text, + const gchar *string); +static void cally_text_insert_text (AtkEditableText *text, + const gchar *string, + gint length, + gint *position); +static void cally_text_delete_text (AtkEditableText *text, + gint start_pos, + gint end_pos); + +/* CallyActor */ +static void cally_text_notify_clutter (GObject *obj, + GParamSpec *pspec); + +static gboolean _check_for_selection_change (CallyText *cally_text, + ClutterText *clutter_text); + +/* Misc functions */ +static AtkAttributeSet* _cally_misc_add_attribute (AtkAttributeSet *attrib_set, + AtkTextAttribute attr, + gchar *value); + +static AtkAttributeSet* _cally_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set, + PangoLayout *layout, + gchar *text, + gint offset, + gint *start_offset, + gint *end_offset); + +G_DEFINE_TYPE_WITH_CODE (CallyText, + cally_text, + CALLY_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, + cally_text_text_interface_init) + G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, + cally_text_editable_text_interface_init)); + +#define CALLY_TEXT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CALLY_TYPE_TEXT, CallyTextPrivate)) + +struct _CallyTextPrivate +{ + /* Cached ClutterText values*/ + gint cursor_position; + gint selection_bound; + + /* text_changed::insert stuff */ + gchar *signal_name_insert; + gint position_insert; + gint length_insert; + guint insert_idle_handler; + + /* text_changed::delete stuff */ + gchar *signal_name_delete; + gint position_delete; + gint length_delete; + + /* action */ + guint activate_action_id; +}; + +static void +cally_text_class_init (CallyTextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + CallyActorClass *cally_class = CALLY_ACTOR_CLASS (klass); + + gobject_class->finalize = cally_text_finalize; + + class->initialize = cally_text_real_initialize; + class->get_name = cally_text_get_name; + class->ref_state_set = cally_text_ref_state_set; + + cally_class->notify_clutter = cally_text_notify_clutter; + + g_type_class_add_private (gobject_class, sizeof (CallyTextPrivate)); +} + +static void +cally_text_init (CallyText *cally_text) +{ + CallyTextPrivate *priv = CALLY_TEXT_GET_PRIVATE (cally_text); + + cally_text->priv = priv; + + priv->cursor_position = 0; + priv->selection_bound = 0; + + priv->signal_name_insert = NULL; + priv->position_insert = -1; + priv->length_insert = -1; + priv->insert_idle_handler = 0; + + priv->signal_name_delete = NULL; + priv->position_delete = -1; + priv->length_delete = -1; + + priv->activate_action_id = 0; +} + +static void +cally_text_finalize (GObject *obj) +{ + CallyText *cally_text = CALLY_TEXT (obj); + +/* g_object_unref (cally_text->priv->textutil); */ +/* cally_text->priv->textutil = NULL; */ + + if (cally_text->priv->insert_idle_handler) + { + g_source_remove (cally_text->priv->insert_idle_handler); + cally_text->priv->insert_idle_handler = 0; + } + + G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); +} + +AtkObject* +cally_text_new (ClutterActor *actor) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + + g_return_val_if_fail (CLUTTER_IS_TEXT (actor), NULL); + + object = g_object_new (CALLY_TYPE_TEXT, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, actor); + + return accessible; +} + +/* atkobject.h */ + +static void +cally_text_real_initialize(AtkObject *obj, + gpointer data) +{ + ClutterText *clutter_text = NULL; + CallyText *cally_text = NULL; + + ATK_OBJECT_CLASS (cally_text_parent_class)->initialize (obj, data); + + g_return_if_fail (CLUTTER_TEXT (data)); + + cally_text = CALLY_TEXT (obj); + clutter_text = CLUTTER_TEXT (data); + + cally_text->priv->cursor_position = clutter_text_get_cursor_position (clutter_text); + cally_text->priv->selection_bound = clutter_text_get_selection_bound (clutter_text); + + g_signal_connect (clutter_text, "text-changed", + G_CALLBACK (_cally_text_text_changed_cb), + cally_text); + g_signal_connect (clutter_text, "insert-text", + G_CALLBACK (_cally_text_insert_text_cb), + cally_text); + g_signal_connect (clutter_text, "delete-text", + G_CALLBACK (_cally_text_delete_text_cb), + cally_text); + + _check_activate_action (cally_text, clutter_text); + + obj->role = ATK_ROLE_TEXT; +} + +static G_CONST_RETURN gchar * +cally_text_get_name (AtkObject *obj) +{ + G_CONST_RETURN gchar *name; + + g_return_val_if_fail (CALLY_IS_ACTOR (obj), NULL); + + name = ATK_OBJECT_CLASS (cally_text_parent_class)->get_name (obj); + if (name == NULL) + { + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (obj); + + if (actor == NULL) /* State is defunct */ + name = NULL; + else + name = clutter_text_get_text (CLUTTER_TEXT (actor)); + } + + return name; +} + +static AtkStateSet* +cally_text_ref_state_set (AtkObject *obj) +{ + AtkStateSet *result = NULL; + ClutterActor *actor = NULL; + + result = ATK_OBJECT_CLASS (cally_text_parent_class)->ref_state_set (obj); + + actor = CALLY_GET_CLUTTER_ACTOR (obj); + + if (actor == NULL) + return result; + + if (clutter_text_get_editable (CLUTTER_TEXT (actor))) + atk_state_set_add_state (result, ATK_STATE_EDITABLE); + + if (clutter_text_get_selectable (CLUTTER_TEXT (actor))) + atk_state_set_add_state (result, ATK_STATE_SELECTABLE_TEXT); + + return result; +} + + +/***** atktext.h ******/ + +static void +cally_text_text_interface_init (AtkTextIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_text = cally_text_get_text; + iface->get_character_at_offset = cally_text_get_character_at_offset; + iface->get_text_before_offset = cally_text_get_text_before_offset; + iface->get_text_at_offset = cally_text_get_text_at_offset; + iface->get_text_after_offset = cally_text_get_text_after_offset; + iface->get_character_count = cally_text_get_character_count; + iface->get_caret_offset = cally_text_get_caret_offset; + iface->set_caret_offset = cally_text_set_caret_offset; + iface->get_n_selections = cally_text_get_n_selections; + iface->get_selection = cally_text_get_selection; + iface->add_selection = cally_text_add_selection; + iface->remove_selection = cally_text_remove_selection; + iface->set_selection = cally_text_set_selection; + iface->get_run_attributes = cally_text_get_run_attributes; +/* iface->get_default_attributes = cally_text_get_default_attributes; */ +/* iface->get_character_extents = */ +/* iface->get_offset_at_point = */ + +} + +static gchar* +cally_text_get_text (AtkText *text, + gint start_offset, + gint end_offset) +{ + ClutterActor *actor = NULL; + + g_return_val_if_fail (CALLY_IS_TEXT (text), NULL); + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* Object is defunct */ + return NULL; + + return clutter_text_get_chars (CLUTTER_TEXT (actor), + start_offset, end_offset); +} + +static gunichar +cally_text_get_character_at_offset (AtkText *text, + gint offset) +{ + ClutterActor *actor = NULL; + CallyText *cally_text = NULL; + gchar *string = NULL; + gchar *index = NULL; + gunichar unichar; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return '\0'; + + cally_text = CALLY_TEXT (text); + string = clutter_text_get_chars (CLUTTER_TEXT (actor), 0, -1); + if (offset >= g_utf8_strlen (string, -1)) + { + unichar = '\0'; + } + else + { + index = g_utf8_offset_to_pointer (string, offset); + + unichar = g_utf8_get_char(index); + } + + g_free(string); + + return unichar; +} + +static gchar* +cally_text_get_text_before_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + ClutterActor *actor = NULL; + ClutterText *clutter_text = NULL; + CallyText *cally_text = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return NULL; + + clutter_text = CLUTTER_TEXT (actor); + cally_text = CALLY_TEXT (text); + +/* return gail_text_util_get_text (cally_text->priv->textutil, */ +/* clutter_text_get_layout (clutter_text), */ +/* GAIL_BEFORE_OFFSET, boundary_type, */ +/* offset, start_offset, end_offset); */ + return NULL; +} + +static gchar* +cally_text_get_text_at_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + ClutterActor *actor = NULL; + ClutterText *clutter_text = NULL; + CallyText *cally_text = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return NULL; + + clutter_text = CLUTTER_TEXT (actor); + cally_text = CALLY_TEXT (text); + +/* return gail_text_util_get_text (cally_text->priv->textutil, */ +/* clutter_text_get_layout (clutter_text), GAIL_AT_OFFSET, */ +/* boundary_type, offset, start_offset, end_offset); */ + return NULL; +} + +static gchar* +cally_text_get_text_after_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + ClutterActor *actor = NULL; + ClutterText *clutter_text = NULL; + CallyText *cally_text = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return NULL; + + clutter_text = CLUTTER_TEXT (actor); + cally_text = CALLY_TEXT (text); + +/* return gail_text_util_get_text (cally_text->priv->textutil, */ +/* clutter_text_get_layout (clutter_text), GAIL_AFTER_OFFSET, */ +/* boundary_type, offset, start_offset, end_offset); */ + return NULL; +} + +static gint +cally_text_get_caret_offset (AtkText *text) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return -1; + + return clutter_text_get_cursor_position (CLUTTER_TEXT (actor)); +} + +static gboolean +cally_text_set_caret_offset (AtkText *text, + gint offset) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return FALSE; + + clutter_text_set_cursor_position (CLUTTER_TEXT (actor), offset); + + /* like in gailentry, we suppose that this always works, as clutter text + doesn't return anything */ + return TRUE; +} + +static gint +cally_text_get_character_count (AtkText *text) +{ + ClutterActor *actor = NULL; + ClutterText *clutter_text = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return 0; + + clutter_text = CLUTTER_TEXT (actor); + return g_utf8_strlen (clutter_text_get_text (clutter_text), -1); +} + +static gint +cally_text_get_n_selections (AtkText *text) +{ + ClutterActor *actor = NULL; + gint selection_bound = -1; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return 0; + + if (!clutter_text_get_selectable (CLUTTER_TEXT (actor))) + return 0; + + selection_bound = clutter_text_get_selection_bound (CLUTTER_TEXT (actor)); + + if (selection_bound > 0) + return 1; + else + return 0; +} + +static gchar* +cally_text_get_selection (AtkText *text, + gint selection_num, + gint *start_offset, + gint *end_offset) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return NULL; + + /* As in gailentry, only let the user get the selection if one is set, and if + * the selection_num is 0. + */ + if (selection_num != 0) + return NULL; + + _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), start_offset, end_offset); + + if (*start_offset != *end_offset) + return clutter_text_get_selection (CLUTTER_TEXT (actor)); + else + return NULL; +} + +/* ClutterText only allows one selection. So this method will set the selection + if no selection exists, but as in gailentry, it will not change the current + selection */ +static gboolean +cally_text_add_selection (AtkText *text, + gint start_offset, + gint end_offset) +{ + ClutterActor *actor; + gint select_start, select_end; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return FALSE; + + _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), + &select_start, &select_end); + + /* Like in gailentry, if there is already a selection, then don't allow another + * to be added, since ClutterText only supports one selected region. + */ + if (select_start == select_end) + { + clutter_text_set_selection (CLUTTER_TEXT (actor), + start_offset, end_offset); + + return TRUE; + } + else + return FALSE; +} + + +static gboolean +cally_text_remove_selection (AtkText *text, + gint selection_num) +{ + ClutterActor *actor = NULL; + gint caret_pos = -1; + gint select_start = -1; + gint select_end = -1; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return FALSE; + + /* only one selection is allowed */ + if (selection_num != 0) + return FALSE; + + _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), + &select_start, &select_end); + + if (select_start != select_end) + { + /* Setting the start & end of the selected region to the caret position + * turns off the selection. + */ + caret_pos = clutter_text_get_cursor_position (CLUTTER_TEXT (actor)); + clutter_text_set_selection (CLUTTER_TEXT (actor), + caret_pos, caret_pos); + return TRUE; + } + else + return FALSE; +} + +static gboolean +cally_text_set_selection (AtkText *text, + gint selection_num, + gint start_offset, + gint end_offset) +{ + ClutterActor *actor = NULL; + gint select_start = -1; + gint select_end = -1; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return FALSE; + + /* Like in gailentry, only let the user move the selection if one is set, + * and if the selection_num is 0 + */ + if (selection_num != 0) + return FALSE; + + _cally_text_get_selection_bounds (CLUTTER_TEXT (actor), + &select_start, &select_end); + + if (select_start != select_end) + { + clutter_text_set_selection (CLUTTER_TEXT (actor), + start_offset, end_offset); + return TRUE; + } + else + return FALSE; +} + +static AtkAttributeSet* +cally_text_get_run_attributes (AtkText *text, + gint offset, + gint *start_offset, + gint *end_offset) +{ + ClutterActor *actor = NULL; + ClutterText *clutter_text = NULL; + AtkAttributeSet *at_set = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return NULL; + + /* Clutter don't have any reference to the direction*/ + + clutter_text = CLUTTER_TEXT (actor); + + at_set = _cally_misc_layout_get_run_attributes (at_set, + clutter_text_get_layout (clutter_text), + (gchar*)clutter_text_get_text (clutter_text), + offset, + start_offset, + end_offset); + + return at_set; +} + +/******** Auxiliar private methods ******/ + +/* ClutterText only maintains the current cursor position and a extra selection + bound, but this could be before or after the cursor. This method returns + the start and end positions in a proper order (so start<=end). This is + similar to the function gtk_editable_get_selection_bounds */ +static void +_cally_text_get_selection_bounds (ClutterText *clutter_text, + gint *start_offset, + gint *end_offset) +{ + gint pos = -1; + gint selection_bound = -1; + + pos = clutter_text_get_cursor_position (clutter_text); + selection_bound = clutter_text_get_selection_bound (clutter_text); + + if (pos < selection_bound) + { + *start_offset = pos; + *end_offset = selection_bound; + } + else + { + *start_offset = selection_bound; + *end_offset = pos; + } +} + +static void +_cally_text_text_changed_cb (ClutterText *clutter_text, + gpointer data) +{ + CallyText *cally_text = NULL; + + g_return_if_fail (CALLY_IS_TEXT (data)); + + cally_text = CALLY_TEXT (data); +} + +static void +_cally_text_delete_text_cb (ClutterText *clutter_text, + gint start_pos, + gint end_pos, + gpointer data) +{ + CallyText *cally_text = NULL; + + g_return_if_fail (CALLY_IS_TEXT (data)); + + /* Ignore zero lengh deletions */ + if (end_pos - start_pos == 0) + return; + + cally_text = CALLY_TEXT (data); + + if (!cally_text->priv->signal_name_delete) + { + cally_text->priv->signal_name_delete = "text_changed::delete"; + cally_text->priv->position_delete = start_pos; + cally_text->priv->length_delete = end_pos - start_pos; + } + + _notify_delete (cally_text); +} + +static void +_cally_text_insert_text_cb (ClutterText *clutter_text, + gchar *new_text, + gint new_text_length, + gint *position, + gpointer data) +{ + CallyText *cally_text = NULL; + + g_return_if_fail (CALLY_IS_TEXT (data)); + + cally_text = CALLY_TEXT (data); + + if (!cally_text->priv->signal_name_insert) + { + cally_text->priv->signal_name_insert = "text_changed::insert"; + cally_text->priv->position_insert = *position; + cally_text->priv->length_insert = g_utf8_strlen (new_text, new_text_length); + } + + /* + * The signal will be emitted when the cursor position is updated, + * or in an idle handler if it not updated. + */ + if (cally_text->priv->insert_idle_handler == 0) + cally_text->priv->insert_idle_handler = clutter_threads_add_idle (_idle_notify_insert, + cally_text); +} + +/***** atkeditabletext.h ******/ + +static void +cally_text_editable_text_interface_init (AtkEditableTextIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->set_text_contents = cally_text_set_text_contents; + iface->insert_text = cally_text_insert_text; + iface->delete_text = cally_text_delete_text; + + /* Not implemented, see IMPLEMENTATION NOTES*/ + iface->set_run_attributes = NULL; + iface->copy_text = NULL; + iface->cut_text = NULL; + iface->paste_text = NULL; +} + +static void +cally_text_set_text_contents (AtkEditableText *text, + const gchar *string) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) + return; + + if (!clutter_text_get_editable (CLUTTER_TEXT (actor))) + return; + + clutter_text_set_text (CLUTTER_TEXT (actor), + string); +} + + +static void +cally_text_insert_text (AtkEditableText *text, + const gchar *string, + gint length, + gint *position) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) + return; + + if (!clutter_text_get_editable (CLUTTER_TEXT (actor))) + return; + + if (length < 0) + length = g_utf8_strlen (string, -1); + + clutter_text_insert_text (CLUTTER_TEXT (actor), + string, *position); + + /* we suppose that the text insertion will be succesful, + clutter-text doesn't warn about it. A option would be search for + the text, but it seems not really required */ + *position += length; +} + +static void cally_text_delete_text (AtkEditableText *text, + gint start_pos, + gint end_pos) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) + return; + + if (!clutter_text_get_editable (CLUTTER_TEXT (actor))) + return; + + clutter_text_delete_text (CLUTTER_TEXT (actor), + start_pos, end_pos); +} + +/* CallyActor */ +static void +cally_text_notify_clutter (GObject *obj, + GParamSpec *pspec) +{ + ClutterText *clutter_text = NULL; + CallyText *cally_text = NULL; + AtkObject *atk_obj = NULL; + + clutter_text = CLUTTER_TEXT (obj); + atk_obj = clutter_actor_get_accessible (CLUTTER_ACTOR (obj)); + cally_text = CALLY_TEXT (atk_obj); + + if (g_strcmp0 (pspec->name, "position") == 0) + { + /* the selection can change also for the cursor position */ + if (_check_for_selection_change (cally_text, clutter_text)) + g_signal_emit_by_name (atk_obj, "text_selection_changed"); + + g_signal_emit_by_name (atk_obj, "text_caret_moved", + clutter_text_get_cursor_position (clutter_text)); + } + else if (g_strcmp0 (pspec->name, "selection-bound") == 0) + { + if (_check_for_selection_change (cally_text, clutter_text)) + g_signal_emit_by_name (atk_obj, "text_selection_changed"); + } + else if (g_strcmp0 (pspec->name, "editable") == 0) + { + atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, + clutter_text_get_editable (clutter_text)); + } + else if (g_strcmp0 (pspec->name, "activatable") == 0) + { + _check_activate_action (cally_text, clutter_text); + } + else + { + CALLY_ACTOR_CLASS (cally_text_parent_class)->notify_clutter (obj, pspec); + } +} + +static gboolean +_check_for_selection_change (CallyText *cally_text, + ClutterText *clutter_text) +{ + gboolean ret_val = FALSE; + gint clutter_pos = -1; + gint clutter_bound = -1; + + clutter_pos = clutter_text_get_cursor_position (clutter_text); + clutter_bound = clutter_text_get_selection_bound (clutter_text); + + if (clutter_pos != clutter_bound) + { + if (clutter_pos != cally_text->priv->cursor_position || + clutter_bound != cally_text->priv->selection_bound) + /* + * This check is here as this function can be called for + * notification of selection_bound and current_pos. The + * values of current_pos and selection_bound may be the same + * for both notifications and we only want to generate one + * text_selection_changed signal. + */ + ret_val = TRUE; + } + else + { + /* We had a selection */ + ret_val = (cally_text->priv->cursor_position != cally_text->priv->selection_bound); + } + + cally_text->priv->cursor_position = clutter_pos; + cally_text->priv->selection_bound = clutter_bound; + + return ret_val; +} + +static gboolean +_idle_notify_insert (gpointer data) +{ + CallyText *cally_text = NULL; + + cally_text = CALLY_TEXT (data); + cally_text->priv->insert_idle_handler = 0; + + _notify_insert (cally_text); + + return FALSE; +} + +static void +_notify_insert (CallyText *cally_text) +{ + if (cally_text->priv->signal_name_insert) + { + g_signal_emit_by_name (cally_text, + cally_text->priv->signal_name_insert, + cally_text->priv->position_insert, + cally_text->priv->length_insert); + cally_text->priv->signal_name_insert = NULL; + } +} + +static void +_notify_delete (CallyText *cally_text) +{ + if (cally_text->priv->signal_name_delete) + { + g_signal_emit_by_name (cally_text, + cally_text->priv->signal_name_delete, + cally_text->priv->position_delete, + cally_text->priv->length_delete); + cally_text->priv->signal_name_delete = NULL; + } +} +/* atkaction */ + +static void +_cally_text_activate_action (CallyActor *cally_actor) +{ + ClutterActor *actor = NULL; + + actor = CALLY_GET_CLUTTER_ACTOR (cally_actor); + + clutter_text_activate (CLUTTER_TEXT (actor)); +} + +static void +_check_activate_action (CallyText *cally_text, + ClutterText *clutter_text) +{ + + if (clutter_text_get_activatable (clutter_text)) + { + if (cally_text->priv->activate_action_id != 0) + return; + + cally_text->priv->activate_action_id = cally_actor_add_action (CALLY_ACTOR (cally_text), + "activate", NULL, NULL, + _cally_text_activate_action); + } + else + { + if (cally_text->priv->activate_action_id == 0) + return; + + if (cally_actor_remove_action (CALLY_ACTOR (cally_text), + cally_text->priv->activate_action_id)) + { + cally_text->priv->activate_action_id = 0; + } + } +} + +/* GailTextUtil/GailMisc reimplementation methods */ + +/** + * _cally_misc_add_attribute: + * + * Reimplementation of gail_misc_layout_get_run_attributes (check this + * function for more documentation). + * + * Returns: A pointer to the new #AtkAttributeSet. + **/ +static AtkAttributeSet* +_cally_misc_add_attribute (AtkAttributeSet *attrib_set, + AtkTextAttribute attr, + gchar *value) +{ + AtkAttributeSet *return_set; + AtkAttribute *at = g_malloc (sizeof (AtkAttribute)); + at->name = g_strdup (atk_text_attribute_get_name (attr)); + at->value = value; + return_set = g_slist_prepend(attrib_set, at); + return return_set; +} + +/** + * _cally_misc_layout_get_run_attributes: + * + * Reimplementation of gail_misc_layout_get_run_attributes (check this + * function for more documentation). + * + * Returns: A pointer to the #AtkAttributeSet. + **/ +static AtkAttributeSet* +_cally_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set, + PangoLayout *layout, + gchar *text, + gint offset, + gint *start_offset, + gint *end_offset) +{ + PangoAttrIterator *iter; + PangoAttrList *attr; + PangoAttrString *pango_string; + PangoAttrInt *pango_int; + PangoAttrColor *pango_color; + PangoAttrLanguage *pango_lang; + PangoAttrFloat *pango_float; + gint index, start_index, end_index; + gboolean is_next = TRUE; + gchar *value = NULL; + glong len; + + len = g_utf8_strlen (text, -1); + /* Grab the attributes of the PangoLayout, if any */ + if ((attr = pango_layout_get_attributes (layout)) == NULL) + { + *start_offset = 0; + *end_offset = len; + return attrib_set; + } + iter = pango_attr_list_get_iterator (attr); + /* Get invariant range offsets */ + /* If offset out of range, set offset in range */ + if (offset > len) + offset = len; + else if (offset < 0) + offset = 0; + + index = g_utf8_offset_to_pointer (text, offset) - text; + pango_attr_iterator_range (iter, &start_index, &end_index); + while (is_next) + { + if (index >= start_index && index < end_index) + { + *start_offset = g_utf8_pointer_to_offset (text, + text + start_index); + if (end_index == G_MAXINT) + /* Last iterator */ + end_index = len; + + *end_offset = g_utf8_pointer_to_offset (text, + text + end_index); + break; + } + is_next = pango_attr_iterator_next (iter); + pango_attr_iterator_range (iter, &start_index, &end_index); + } + /* Get attributes */ + if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter, + PANGO_ATTR_FAMILY)) != NULL) + { + value = g_strdup_printf("%s", pango_string->value); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_FAMILY_NAME, + value); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_STYLE)) != NULL) + { + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_STYLE, + g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value))); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_WEIGHT)) != NULL) + { + value = g_strdup_printf("%i", pango_int->value); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_WEIGHT, + value); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_VARIANT)) != NULL) + { + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_VARIANT, + g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value))); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_STRETCH)) != NULL) + { + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_STRETCH, + g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value))); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_SIZE)) != NULL) + { + value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_SIZE, + value); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_UNDERLINE)) != NULL) + { + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_UNDERLINE, + g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value))); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_STRIKETHROUGH)) != NULL) + { + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_STRIKETHROUGH, + g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value))); + } + if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter, + PANGO_ATTR_RISE)) != NULL) + { + value = g_strdup_printf("%i", pango_int->value); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_RISE, + value); + } + if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter, + PANGO_ATTR_LANGUAGE)) != NULL) + { + value = g_strdup( pango_language_to_string( pango_lang->value)); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_LANGUAGE, + value); + } + if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter, + PANGO_ATTR_SCALE)) != NULL) + { + value = g_strdup_printf("%g", pango_float->value); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_SCALE, + value); + } + if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter, + PANGO_ATTR_FOREGROUND)) != NULL) + { + value = g_strdup_printf ("%u,%u,%u", + pango_color->color.red, + pango_color->color.green, + pango_color->color.blue); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_FG_COLOR, + value); + } + if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter, + PANGO_ATTR_BACKGROUND)) != NULL) + { + value = g_strdup_printf ("%u,%u,%u", + pango_color->color.red, + pango_color->color.green, + pango_color->color.blue); + attrib_set = _cally_misc_add_attribute (attrib_set, + ATK_TEXT_ATTR_BG_COLOR, + value); + } + pango_attr_iterator_destroy (iter); + return attrib_set; +} diff --git a/clutter/cally/cally-text.h b/clutter/cally/cally-text.h new file mode 100644 index 000000000..54e15d155 --- /dev/null +++ b/clutter/cally/cally-text.h @@ -0,0 +1,63 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_TEXT_H__ +#define __CALLY_TEXT_H__ + +#include "cally-actor.h" + +G_BEGIN_DECLS + +#define CALLY_TYPE_TEXT (cally_text_get_type ()) +#define CALLY_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXT, CallyText)) +#define CALLY_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXT, CallyTextClass)) +#define CALLY_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXT)) +#define CALLY_IS_TEXT_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXT)) +#define CALLY_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXT, CallyTextClass)) + + +typedef struct _CallyText CallyText; +typedef struct _CallyTextClass CallyTextClass; +typedef struct _CallyTextPrivate CallyTextPrivate; + +struct _CallyText +{ + CallyActor parent; + + /* < private > */ + CallyTextPrivate *priv; +}; + +struct _CallyTextClass +{ + CallyActorClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_text_get_type (void); +AtkObject* cally_text_new (ClutterActor *actor); + +G_END_DECLS + +#endif /* __CALLY_TEXT_H__ */ diff --git a/clutter/cally/cally-texture.c b/clutter/cally/cally-texture.c new file mode 100644 index 000000000..13c3a6095 --- /dev/null +++ b/clutter/cally/cally-texture.c @@ -0,0 +1,103 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:callycluttertexture + * @short_description: Implementation of the ATK interfaces for a #ClutterTexture + * @see_also: #ClutterTexture + * + * #CallyClutterTexture implements the required ATK interfaces of #ClutterTexture + * + * In particular it sets a proper role for the texture. + */ + +#include "cally-texture.h" +#include "cally-actor-private.h" + +#define CALLY_TEXTURE_DEFAULT_DESCRIPTION "A texture" + +static void cally_texture_class_init (CallyTextureClass *klass); +static void cally_texture_init (CallyTexture *texture); + +/* AtkObject */ +static void cally_texture_real_initialize (AtkObject *obj, + gpointer data); +static G_CONST_RETURN gchar *cally_texture_get_description (AtkObject *obj); + + +G_DEFINE_TYPE (CallyTexture, cally_texture, CALLY_TYPE_ACTOR) + +static void +cally_texture_class_init (CallyTextureClass *klass) +{ +/* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + class->initialize = cally_texture_real_initialize; + class->get_description = cally_texture_get_description; +} + +static void +cally_texture_init (CallyTexture *texture) +{ + /* nothing to do yet */ +} + +AtkObject* +cally_texture_new (ClutterActor *actor) +{ + GObject *object = NULL; + AtkObject *accessible = NULL; + + g_return_val_if_fail (CLUTTER_IS_TEXTURE (actor), NULL); + + object = g_object_new (CALLY_TYPE_TEXTURE, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, actor); + + return accessible; +} + +static void +cally_texture_real_initialize (AtkObject *obj, + gpointer data) +{ + ATK_OBJECT_CLASS (cally_texture_parent_class)->initialize (obj, data); + + /* default role */ + obj->role = ATK_ROLE_IMAGE; +} + +static G_CONST_RETURN gchar * +cally_texture_get_description (AtkObject *obj) +{ + G_CONST_RETURN gchar *description = NULL; + + g_return_val_if_fail (CALLY_IS_TEXTURE (obj), NULL); + + description = ATK_OBJECT_CLASS (cally_texture_parent_class)->get_description (obj); + if (description == NULL) + description = CALLY_TEXTURE_DEFAULT_DESCRIPTION; + + return description; +} diff --git a/clutter/cally/cally-texture.h b/clutter/cally/cally-texture.h new file mode 100644 index 000000000..6603ee2d1 --- /dev/null +++ b/clutter/cally/cally-texture.h @@ -0,0 +1,63 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_TEXTURE_H__ +#define __CALLY_TEXTURE_H__ + +#include "cally-actor.h" + +G_BEGIN_DECLS + +#define CALLY_TYPE_TEXTURE (cally_texture_get_type ()) +#define CALLY_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXTURE, CallyTexture)) +#define CALLY_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXTURE, CallyTextureClass)) +#define CALLY_IS_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXTURE)) +#define CALLY_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXTURE)) +#define CALLY_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXTURE, CallyTextureClass)) + + +typedef struct _CallyTexture CallyTexture; +typedef struct _CallyTextureClass CallyTextureClass; +typedef struct _CallyTexturePrivate CallyTexturePrivate; + +struct _CallyTexture +{ + CallyActor parent; + + /* < private > */ + CallyTexturePrivate *priv; +}; + +struct _CallyTextureClass +{ + CallyActorClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_texture_get_type (void); +AtkObject *cally_texture_new (ClutterActor *actor); + +G_END_DECLS + +#endif /* __CALLY_TEXTURE_H__ */ diff --git a/clutter/cally/cally-util.c b/clutter/cally/cally-util.c new file mode 100644 index 000000000..14a4a8e7d --- /dev/null +++ b/clutter/cally/cally-util.c @@ -0,0 +1,557 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Based on GailUtil from GAIL + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "cally-util.h" +#include "cally-root.h" +#include "cally-stage.h" + +#ifdef HAVE_CLUTTER_X11 +#include +#endif + +static void cally_util_class_init (CallyUtilClass *klass); +static void cally_util_init (CallyUtil *cally_util); + +/* atkutil.h */ + +static guint cally_util_add_global_event_listener (GSignalEmissionHook listener, + const gchar* event_type); +static void cally_util_remove_global_event_listener (guint remove_listener); +static guint cally_util_add_key_event_listener (AtkKeySnoopFunc listener, + gpointer data); +static void cally_util_remove_key_event_listener (guint remove_listener); +static AtkObject* cally_util_get_root (void); +static G_CONST_RETURN gchar *cally_util_get_toolkit_name (void); +static G_CONST_RETURN gchar *cally_util_get_toolkit_version (void); + +/* private */ +static void _listener_info_destroy (gpointer data); +static guint add_listener (GSignalEmissionHook listener, + const gchar *object_type, + const gchar *signal, + const gchar *hook_data); +static void cally_util_simulate_snooper_install (void); +static void cally_util_simulate_snooper_remove (void); +static gboolean cally_key_snooper (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data); +static void cally_util_stage_added_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data); +static void cally_util_stage_removed_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data); +static gboolean notify_hf (gpointer key, + gpointer value, + gpointer data); +static void insert_hf (gpointer key, + gpointer value, + gpointer data); +static AtkKeyEventStruct * atk_key_event_from_clutter_event_key (ClutterKeyEvent *event); +static void do_window_event_initialization (void); + + +/* This is just a copy of the Gail one, a shared library or place to + define it could be a good idea. */ +typedef struct _CallyUtilListenerInfo CallyUtilListenerInfo; +typedef struct _CallyKeyEventInfo CallyKeyEventInfo; + +struct _CallyUtilListenerInfo +{ + gint key; + guint signal_id; + gulong hook_id; +}; + +struct _CallyKeyEventInfo +{ + AtkKeySnoopFunc listener; + gpointer func_data; +}; + +static AtkObject* root = NULL; +static GHashTable *listener_list = NULL; +static GHashTable *key_listener_list = NULL; +static gint listener_idx = 1; + + +G_DEFINE_TYPE (CallyUtil, cally_util, ATK_TYPE_UTIL); + +static void +cally_util_class_init (CallyUtilClass *klass) +{ + AtkUtilClass *atk_class; + gpointer data; + + data = g_type_class_peek (ATK_TYPE_UTIL); + atk_class = ATK_UTIL_CLASS (data); + + atk_class->add_global_event_listener = cally_util_add_global_event_listener; + atk_class->remove_global_event_listener = cally_util_remove_global_event_listener; + atk_class->add_key_event_listener = cally_util_add_key_event_listener; + atk_class->remove_key_event_listener = cally_util_remove_key_event_listener; + atk_class->get_root = cally_util_get_root; + atk_class->get_toolkit_name = cally_util_get_toolkit_name; + atk_class->get_toolkit_version = cally_util_get_toolkit_version; + + /* FIXME: Instead of create this on the class, I think that would + worth to implement CallyUtil as a singleton instance, so the + class methods will access this instance. This will be a good + future enhancement, meanwhile, just using the same *working* + implementation used on GailUtil */ + + listener_list = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, + _listener_info_destroy); +} + +static void +cally_util_init (CallyUtil *cally_util) +{ + /* instance init: usually not required */ +} + +/* ------------------------------ ATK UTIL METHODS -------------------------- */ + +static AtkObject* +cally_util_get_root (void) +{ + if (!root) + root = cally_root_new (); + + return root; +} + +static G_CONST_RETURN gchar * +cally_util_get_toolkit_name (void) +{ + return "CALLY"; +} + +static G_CONST_RETURN gchar * +cally_util_get_toolkit_version (void) +{ + /* + * FIXME: + * Version is passed in as a -D flag when this file is + * compiled. + */ + return "0.1"; +} + + +static guint +cally_util_add_global_event_listener (GSignalEmissionHook listener, + const gchar *event_type) +{ + guint rc = 0; + gchar **split_string; + + split_string = g_strsplit (event_type, ":", 3); + + if (split_string) + { + if (!strcmp ("window", split_string[0])) + { + /* Using ClutterStage as the window equivalent, although + several methods (move, etc) are missing. This would be + probably defined for other window-related classes (MxWindow) + + FIXME: for this reason, this process should be extendable + on the future.*/ + static gboolean initialized = FALSE; + + if (initialized == FALSE) + { + do_window_event_initialization (); + initialized = TRUE; + } + + rc = add_listener (listener, "CallyStage", split_string[1], event_type); + } + else + { + rc = add_listener (listener, split_string[1], split_string[2], event_type); + } + + g_strfreev (split_string); + } + + return rc; +} + +static void +cally_util_remove_global_event_listener (guint remove_listener) +{ + if (remove_listener > 0) + { + CallyUtilListenerInfo *listener_info; + gint tmp_idx = remove_listener; + + listener_info = (CallyUtilListenerInfo *) + g_hash_table_lookup(listener_list, &tmp_idx); + + if (listener_info != NULL) + { + /* Hook id of 0 and signal id of 0 are invalid */ + if (listener_info->hook_id != 0 && listener_info->signal_id != 0) + { + /* Remove the emission hook */ + g_signal_remove_emission_hook(listener_info->signal_id, + listener_info->hook_id); + + /* Remove the element from the hash */ + g_hash_table_remove(listener_list, &tmp_idx); + } + else + { + g_warning("Invalid listener hook_id %ld or signal_id %d\n", + listener_info->hook_id, listener_info->signal_id); + } + } + else + { + g_warning("No listener with the specified listener id %d", + remove_listener); + } + } + else + { + g_warning("Invalid listener_id %d", remove_listener); + } +} + +static guint +cally_util_add_key_event_listener (AtkKeySnoopFunc listener, + gpointer data) +{ + static guint key=0; + CallyKeyEventInfo *event_info = NULL; + + if (!key_listener_list) + { + key_listener_list = g_hash_table_new_full (NULL, NULL, NULL, g_free); + + cally_util_simulate_snooper_install (); + } + + event_info = g_new (CallyKeyEventInfo, 1); + event_info->listener = listener; + event_info->func_data = data; + + g_hash_table_insert (key_listener_list, GUINT_TO_POINTER (key++), event_info); + /* XXX: we don't check to see if n_listeners > MAXUINT */ + return key - 1; +} + +static void +cally_util_remove_key_event_listener (guint remove_listener) +{ + if (!g_hash_table_remove (key_listener_list, GUINT_TO_POINTER (remove_listener))) { + g_warning ("Not able to remove listener with id %i", remove_listener); + } + + if (g_hash_table_size (key_listener_list) == 0) + { + cally_util_simulate_snooper_remove (); + } +} + +/* ------------------------------ PRIVATE FUNCTIONS ------------------------- */ + +static void +_listener_info_destroy (gpointer data) +{ + g_free(data); +} + +static guint +add_listener (GSignalEmissionHook listener, + const gchar *object_type, + const gchar *signal, + const gchar *hook_data) +{ + GType type; + guint signal_id; + gint rc = 0; + + type = g_type_from_name (object_type); + if (type) + { + signal_id = g_signal_lookup (signal, type); + if (signal_id > 0) + { + CallyUtilListenerInfo *listener_info; + + rc = listener_idx; + + listener_info = g_new (CallyUtilListenerInfo, 1); + listener_info->key = listener_idx; + listener_info->hook_id = + g_signal_add_emission_hook (signal_id, 0, listener, + g_strdup (hook_data), + (GDestroyNotify) g_free); + listener_info->signal_id = signal_id; + + g_hash_table_insert(listener_list, &(listener_info->key), listener_info); + listener_idx++; + } + else + { + /* This is mainly because some "window:xxx" methods not + implemented on CallyStage */ + g_debug ("Signal type %s not supported\n", signal); + } + } + else + { + g_warning("Invalid object type %s\n", object_type); + } + return rc; +} + +/* Trying to emulate gtk_key_snooper install (a kind of wrapper). This + could be implemented without it, but I will maintain it in this + way, so if in the future clutter implements it natively it would be + easier the transition */ +static void +cally_util_simulate_snooper_install (void) +{ + ClutterStageManager *stage_manager = NULL; + ClutterStage *stage = NULL; + GSList *stage_list = NULL; + GSList *iter = NULL; + + stage_manager = clutter_stage_manager_get_default (); + stage_list = clutter_stage_manager_list_stages (stage_manager); + + for (iter = stage_list; iter != NULL; iter = g_slist_next (iter)) + { + stage = CLUTTER_STAGE (iter->data); + + g_signal_connect (G_OBJECT (stage), "captured-event", + G_CALLBACK (cally_key_snooper), NULL); + } + + g_signal_connect (G_OBJECT (stage_manager), "stage-added", + G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper); + g_signal_connect (G_OBJECT (stage_manager), "stage-removed", + G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper); +} + +static void +cally_util_simulate_snooper_remove (void) +{ + ClutterStageManager *stage_manager = NULL; + ClutterStage *stage = NULL; + GSList *stage_list = NULL; + GSList *iter = NULL; + gint num = 0; + + stage_manager = clutter_stage_manager_get_default (); + stage_list = clutter_stage_manager_list_stages (stage_manager); + + for (iter = stage_list; iter != NULL; iter = g_slist_next (iter)) + { + stage = CLUTTER_STAGE (iter->data); + + num += g_signal_handlers_disconnect_by_func (stage, cally_key_snooper, NULL); + } + + g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager), + G_CALLBACK (cally_util_stage_added_cb), + cally_key_snooper); + + g_signal_handlers_disconnect_by_func (G_OBJECT (stage_manager), + G_CALLBACK (cally_util_stage_removed_cb), + cally_key_snooper); + +#ifdef CALLY_DEBUG + g_print ("Number of snooper callbacks disconnected: %i\n", num); +#endif +} + +static AtkKeyEventStruct * +atk_key_event_from_clutter_event_key (ClutterKeyEvent *clutter_event) +{ + AtkKeyEventStruct *atk_event = g_new0 (AtkKeyEventStruct, 1); + gunichar key_unichar; + + switch (clutter_event->type) + { + case CLUTTER_KEY_PRESS: + atk_event->type = ATK_KEY_EVENT_PRESS; + break; + case CLUTTER_KEY_RELEASE: + atk_event->type = ATK_KEY_EVENT_RELEASE; + break; + default: + g_assert_not_reached (); + return NULL; + } + + atk_event->state = clutter_event->modifier_state; + + /* We emit the clutter keyval. This is not exactly the one expected + by AtkKeyEventStruct, as it expects a Gdk-like event, with the + modifiers applied. But to avoid a dependency to gdk, we delegate + that on the AT application. + More information: Bug 1952 and bug 2072 + */ + atk_event->keyval = clutter_event->keyval; + + /* It is expected to store a key defining string here (ie "Space" in + case you press a space). Anyway, there are no function on clutter + to obtain that, and we want to avoid a gdk dependency here, so we + delegate on the AT application to obtain that string using the + rest of the data on the ATK event struct. + + More information: Bug 1952 and 2072 + */ + + key_unichar = clutter_event_get_key_unicode ((ClutterEvent *) clutter_event); + + if (g_unichar_validate (key_unichar) && !g_unichar_iscntrl (key_unichar)) + { + GString *new = NULL; + + new = g_string_new (""); + new = g_string_insert_unichar (new, 0, key_unichar); + atk_event->string = new->str; + g_string_free (new, FALSE); + } + else + atk_event->string = NULL; + + atk_event->length = 0; + + atk_event->keycode = clutter_event->hardware_keycode; + atk_event->timestamp = clutter_event->time; + +#ifdef CALLY_DEBUG + + g_debug ("CallyKeyEvent:\tsym 0x%x\n\t\tmods %x\n\t\tcode %u\n\t\ttime %lx \n\t\tstring %s\n", + (unsigned int) atk_event->keyval, + (unsigned int) atk_event->state, + (unsigned int) atk_event->keycode, + (unsigned long int) atk_event->timestamp, + atk_event->string); +#endif + + return atk_event; +} + + +static gboolean +notify_hf (gpointer key, gpointer value, gpointer data) +{ + CallyKeyEventInfo *info = (CallyKeyEventInfo *) value; + AtkKeyEventStruct *key_event = (AtkKeyEventStruct *)data; + + return (*(AtkKeySnoopFunc) info->listener) (key_event, info->func_data) ? TRUE : FALSE; +} + +static void +insert_hf (gpointer key, gpointer value, gpointer data) +{ + GHashTable *new_table = (GHashTable *) data; + g_hash_table_insert (new_table, key, value); +} + +static gboolean +cally_key_snooper (ClutterActor *actor, + ClutterEvent *event, + gpointer user_data) +{ + AtkKeyEventStruct *key_event = NULL; + gint consumed = 0; + + /* filter key events */ + if ((event->type != CLUTTER_KEY_PRESS) && (event->type != CLUTTER_KEY_RELEASE)) + { + return FALSE; + } + + if (key_listener_list) + { + GHashTable *new_hash = g_hash_table_new (NULL, NULL); + + g_hash_table_foreach (key_listener_list, insert_hf, new_hash); + key_event = atk_key_event_from_clutter_event_key ((ClutterKeyEvent *)event); + /* func data is inside the hash table */ + consumed = g_hash_table_foreach_steal (new_hash, notify_hf, key_event); + g_hash_table_destroy (new_hash); + } + + g_free (key_event->string); + g_free (key_event); + + return (consumed ? 1 : 0); +} + +static void +cally_util_stage_added_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data) +{ + GCallback cally_key_snooper = G_CALLBACK (data); + AtkObject *cally_stage = NULL; + + g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper, NULL); + + cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); + if (cally_stage != NULL) + g_signal_emit_by_name (G_OBJECT(cally_stage), "create", 0); +} + +static void +cally_util_stage_removed_cb (ClutterStageManager *stage_manager, + ClutterStage *stage, + gpointer data) +{ + GCallback cally_key_snooper = G_CALLBACK (data); + gint num = 0; + AtkObject *cally_stage = NULL; + + num = g_signal_handlers_disconnect_by_func (stage, cally_key_snooper, NULL); + + cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); + if (cally_stage != NULL) + g_signal_emit_by_name (G_OBJECT(cally_stage), "destroy", 0); +} + +static void +do_window_event_initialization (void) +{ + /* + * Ensure that CallyStageClass exists. + */ + g_type_class_unref (g_type_class_ref (CALLY_TYPE_STAGE)); +} diff --git a/clutter/cally/cally-util.h b/clutter/cally/cally-util.h new file mode 100644 index 000000000..dfb68390b --- /dev/null +++ b/clutter/cally/cally-util.h @@ -0,0 +1,61 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_UTIL_H__ +#define __CALLY_UTIL_H__ + +#include + +G_BEGIN_DECLS + +#define CALLY_TYPE_UTIL (cally_util_get_type ()) +#define CALLY_UTIL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_UTIL, CallyUtil)) +#define CALLY_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_UTIL, CallyUtilClass)) +#define CALLY_IS_UTIL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_UTIL)) +#define CALLY_IS_UTIL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_UTIL)) +#define CALLY_UTIL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_UTIL, CallyUtilClass)) + +typedef struct _CallyUtil CallyUtil; +typedef struct _CallyUtilClass CallyUtilClass; +typedef struct _CallyUtilPrivate CallyUtilPrivate; + +struct _CallyUtil +{ + AtkUtil parent; + + /* < private > */ + CallyUtilPrivate *priv; +}; + +struct _CallyUtilClass +{ + AtkUtilClass parent_class; + + /* padding for future expansion */ + gpointer _padding_dummy[30]; +}; + +GType cally_util_get_type (void); + +G_END_DECLS + +#endif /* __CALLY_UTIL_H__ */ diff --git a/clutter/cally/cally.pc.in b/clutter/cally/cally.pc.in new file mode 100644 index 000000000..baf0dc859 --- /dev/null +++ b/clutter/cally/cally.pc.in @@ -0,0 +1,18 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +apiversion=@CLUTTER_API_VERSION@ +requires=@CLUTTER_REQUIRES@ +backend=@COGL_WINSYS@ #only kept for backward compatability +winsys=@COGL_WINSYS@ +cogl=@COGL_DRIVER@ #only kept for backward compatability +driver=@COGL_DRIVER@ + +Name: Cally +Description: Clutter Accessibility Implementation Library +Version: @VERSION@ +Requires: atk clutter-1.0 +Libs: -L${libdir} -lclutter-${winsys}-${apiversion} +Cflags: -I${includedir}/clutter-${apiversion} +Requires: ${requires} diff --git a/configure.ac b/configure.ac index dc35b08c5..9a35c8244 100644 --- a/configure.ac +++ b/configure.ac @@ -1017,6 +1017,8 @@ AC_CONFIG_FILES([ clutter/osx/Makefile clutter/win32/Makefile clutter/win32/clutter-win32.pc + clutter/cally/Makefile + clutter/cally/cally.pc clutter/cogl/Makefile clutter/cogl/cogl/Makefile clutter/cogl/cogl/cogl-defines.h From 72da871c0a918a33b742f3353c73c2e984c46f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Mon, 14 Jun 2010 18:05:57 +0200 Subject: [PATCH 02/16] Cally initialization code This commit includes a method to init the a11y support. Two main purposes: * Register the different Atk factories. * Ensure that there are a AtkUtil implementation class available. Part of CB#2097 --- clutter/cally/cally.c | 93 +++++++++++++++++++++++++++++++++++++++++++ clutter/cally/cally.h | 40 +++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 clutter/cally/cally.c create mode 100644 clutter/cally/cally.h diff --git a/clutter/cally/cally.c b/clutter/cally/cally.c new file mode 100644 index 000000000..85be3eb03 --- /dev/null +++ b/clutter/cally/cally.c @@ -0,0 +1,93 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "cally.h" + +#include "cally-factory.h" +#include "cally-util.h" + +extern void gnome_accessibility_module_init (void); +extern void gnome_accessibility_module_shutdown (void); + +static int cally_initialized = FALSE; + +/* factories initialization*/ +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_ACTOR, cally_actor, cally_actor_new) +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_GROUP, cally_group, cally_group_new) +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_STAGE, cally_stage, cally_stage_new) +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXT, cally_text, cally_text_new) +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXTURE, cally_texture, cally_texture_new) +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new) +CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) + +void +cally_accessibility_module_init(void) +{ + if (cally_initialized) + return; + + cally_initialized = TRUE; + + /* setting the factories */ + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_ACTOR, cally_actor); + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_GROUP, cally_group); + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_STAGE, cally_stage); + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXT, cally_text); + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_TEXTURE, cally_texture); + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_RECTANGLE, cally_rectangle); + CALLY_ACTOR_SET_FACTORY (CLUTTER_TYPE_CLONE, cally_clone); + + /* Initialize the CallyUtility class */ + g_type_class_unref (g_type_class_ref (CALLY_TYPE_UTIL)); + + g_message ("Clutter Accessibility Module initialized"); +} + + +/** + * gnome_accessibility_module_shutdown: + * @void: + * + * Common gnome hook to be used in order to activate the module + **/ +void +gnome_accessibility_module_init (void) +{ + cally_accessibility_module_init (); +} + +/** + * gnome_accessibility_module_shutdown: + * @void: + * + * Common gnome hook to be used in order to de-activate the module + **/ +void +gnome_accessibility_module_shutdown (void) +{ + if (!cally_initialized) + return; + + cally_initialized = FALSE; + + g_message ("Clutter Accessibility Module shutdown"); +} diff --git a/clutter/cally/cally.h b/clutter/cally/cally.h new file mode 100644 index 000000000..7120809b4 --- /dev/null +++ b/clutter/cally/cally.h @@ -0,0 +1,40 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __CALLY_H +#define __CALLY_H + +#include "cally-actor.h" +#include "cally-group.h" +#include "cally-stage.h" +#include "cally-text.h" +#include "cally-texture.h" +#include "cally-rectangle.h" +#include "cally-clone.h" + +G_BEGIN_DECLS + +void cally_accessibility_module_init(void); + +G_END_DECLS + +#endif /* __CALLY_H */ From 774541d71e2518f03bc4fdfb7ad481077a9b0dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Tue, 15 Jun 2010 13:45:19 +0200 Subject: [PATCH 03/16] Rename some methods and includes to avoid -Wshadow warnings http://bugzilla.clutter-project.org/show_bug.cgi?id=2097 --- clutter/cally/cally-actor.c | 5 ++--- clutter/cally/cally-util.c | 14 +++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c index b8a86de2f..55dad3c69 100644 --- a/clutter/cally/cally-actor.c +++ b/clutter/cally/cally-actor.c @@ -100,7 +100,6 @@ #include "config.h" -#include #include #ifdef HAVE_CLUTTER_X11 @@ -1224,12 +1223,12 @@ cally_actor_real_notify_clutter (GObject *obj, AtkState state; gboolean value; - if (strcmp (pspec->name, "visible") == 0) + if (g_strcmp0 (pspec->name, "visible") == 0) { state = ATK_STATE_VISIBLE; value = CLUTTER_ACTOR_IS_VISIBLE (actor); } - else if (strcmp (pspec->name, "reactive") == 0) + else if (g_strcmp0 (pspec->name, "reactive") == 0) { state = ATK_STATE_SENSITIVE; value = CLUTTER_ACTOR_IS_REACTIVE (actor); diff --git a/clutter/cally/cally-util.c b/clutter/cally/cally-util.c index 14a4a8e7d..a0890b924 100644 --- a/clutter/cally/cally-util.c +++ b/clutter/cally/cally-util.c @@ -295,7 +295,7 @@ _listener_info_destroy (gpointer data) static guint add_listener (GSignalEmissionHook listener, const gchar *object_type, - const gchar *signal, + const gchar *signal_name, const gchar *hook_data) { GType type; @@ -305,7 +305,7 @@ add_listener (GSignalEmissionHook listener, type = g_type_from_name (object_type); if (type) { - signal_id = g_signal_lookup (signal, type); + signal_id = g_signal_lookup (signal_name, type); if (signal_id > 0) { CallyUtilListenerInfo *listener_info; @@ -327,7 +327,7 @@ add_listener (GSignalEmissionHook listener, { /* This is mainly because some "window:xxx" methods not implemented on CallyStage */ - g_debug ("Signal type %s not supported\n", signal); + g_debug ("Signal type %s not supported\n", signal_name); } } else @@ -521,10 +521,10 @@ cally_util_stage_added_cb (ClutterStageManager *stage_manager, ClutterStage *stage, gpointer data) { - GCallback cally_key_snooper = G_CALLBACK (data); + GCallback cally_key_snooper_cb = G_CALLBACK (data); AtkObject *cally_stage = NULL; - g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper, NULL); + g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper_cb, NULL); cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); if (cally_stage != NULL) @@ -536,11 +536,11 @@ cally_util_stage_removed_cb (ClutterStageManager *stage_manager, ClutterStage *stage, gpointer data) { - GCallback cally_key_snooper = G_CALLBACK (data); + GCallback cally_key_snooper_cb = G_CALLBACK (data); gint num = 0; AtkObject *cally_stage = NULL; - num = g_signal_handlers_disconnect_by_func (stage, cally_key_snooper, NULL); + num = g_signal_handlers_disconnect_by_func (stage, cally_key_snooper_cb, NULL); cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); if (cally_stage != NULL) From 8f8e88b692b04fc8cf1949fa1b98c7ae47846a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Mon, 26 Apr 2010 19:33:49 +0200 Subject: [PATCH 04/16] Initialize accessibility support on clutter_init Initialize the accessibility support calling cally_accessibility_init Take into account that this is required to at least be sure that CallyUtil class is available. It also modifies cally_accessibility_module_init in order to return if the initialization was fine (and the name, removing the module word). It also removes the gnome accessibility hooks, as it is not anymore module code. Solves CB#2098 --- clutter/cally/cally.c | 64 ++++++++++++++++++++++-------------------- clutter/cally/cally.h | 11 ++------ clutter/clutter-main.c | 27 ++++++++++++++++++ clutter/clutter-main.h | 1 + 4 files changed, 65 insertions(+), 38 deletions(-) diff --git a/clutter/cally/cally.c b/clutter/cally/cally.c index 85be3eb03..fd95d411c 100644 --- a/clutter/cally/cally.c +++ b/clutter/cally/cally.c @@ -22,11 +22,18 @@ #include "cally.h" +#include "cally-actor.h" +#include "cally-group.h" +#include "cally-stage.h" +#include "cally-text.h" +#include "cally-texture.h" +#include "cally-rectangle.h" +#include "cally-clone.h" + #include "cally-factory.h" #include "cally-util.h" -extern void gnome_accessibility_module_init (void); -extern void gnome_accessibility_module_shutdown (void); +#include "clutter-debug.h" static int cally_initialized = FALSE; @@ -39,11 +46,21 @@ CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_TEXTURE, cally_texture, cally_texture_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle_new) CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) -void -cally_accessibility_module_init(void) +/** + * cally_acccessibility_init: + * + * Initializes the accessibility support. + * + * Return value: %TRUE if accessibility support has been correctly + * initialized. + * + * Since: 1.4 + */ +gboolean +cally_accessibility_init (void) { if (cally_initialized) - return; + return TRUE; cally_initialized = TRUE; @@ -59,35 +76,22 @@ cally_accessibility_module_init(void) /* Initialize the CallyUtility class */ g_type_class_unref (g_type_class_ref (CALLY_TYPE_UTIL)); - g_message ("Clutter Accessibility Module initialized"); -} + CLUTTER_NOTE (MISC, "Clutter Accessibility initialized"); - -/** - * gnome_accessibility_module_shutdown: - * @void: - * - * Common gnome hook to be used in order to activate the module - **/ -void -gnome_accessibility_module_init (void) -{ - cally_accessibility_module_init (); + return cally_initialized; } /** - * gnome_accessibility_module_shutdown: - * @void: + * cally_get_cally_initialized: * - * Common gnome hook to be used in order to de-activate the module - **/ -void -gnome_accessibility_module_shutdown (void) + * Returns if the accessibility support using cally is enabled. + * + * Return value: %TRUE if accessibility support has been correctly + * initialized. + * + * Since: 1.4 + */ +gboolean cally_get_cally_initialized (void) { - if (!cally_initialized) - return; - - cally_initialized = FALSE; - - g_message ("Clutter Accessibility Module shutdown"); + return cally_initialized; } diff --git a/clutter/cally/cally.h b/clutter/cally/cally.h index 7120809b4..4924dfec8 100644 --- a/clutter/cally/cally.h +++ b/clutter/cally/cally.h @@ -23,17 +23,12 @@ #ifndef __CALLY_H #define __CALLY_H -#include "cally-actor.h" -#include "cally-group.h" -#include "cally-stage.h" -#include "cally-text.h" -#include "cally-texture.h" -#include "cally-rectangle.h" -#include "cally-clone.h" +#include G_BEGIN_DECLS -void cally_accessibility_module_init(void); +gboolean cally_get_cally_initialized (void); +gboolean cally_accessibility_init (void); G_END_DECLS diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 3392f9ce8..e2a406e03 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -114,6 +114,8 @@ #include "cogl/cogl.h" #include "pango/cogl-pango.h" +#include "cally.h" /* For accessibility support */ + /* main context */ static ClutterMainContext *ClutterCntx = NULL; @@ -128,6 +130,7 @@ static gboolean clutter_show_fps = FALSE; static gboolean clutter_fatal_warnings = FALSE; static gboolean clutter_disable_mipmap_text = FALSE; static gboolean clutter_use_fuzzy_picking = FALSE; +static gboolean clutter_enable_accessibility = TRUE; static guint clutter_default_fps = 60; @@ -203,6 +206,24 @@ clutter_get_show_fps (void) return clutter_show_fps; } +/** + * clutter_get_accessibility_enabled: + * + * Returns whether Clutter has accessibility support enabled. As + * least, a value of TRUE means that there are a proper AtkUtil + * implementation available + * + * Return value: %TRUE if Clutter has accessibility support enabled + * + * Since: 1.4 + */ +gboolean +clutter_get_accessibility_enabled (void) +{ + return cally_get_cally_initialized (); +} + + void _clutter_stage_maybe_relayout (ClutterActor *stage) { @@ -1591,6 +1612,10 @@ clutter_init_real (GError **error) clutter_is_initialized = TRUE; ctx->is_initialized = TRUE; + /* Initialize a11y */ + if (clutter_enable_accessibility) + cally_accessibility_init (); + return CLUTTER_INIT_SUCCESS; } @@ -1622,6 +1647,8 @@ static GOptionEntry clutter_args[] = { { "clutter-no-profile", 0, 0, G_OPTION_ARG_CALLBACK, clutter_arg_no_profile_cb, N_("Clutter profiling flags to unset"), "FLAGS" }, #endif /* CLUTTER_ENABLE_PROFILE */ + { "clutter-enable-accessibility", 0, 0, G_OPTION_ARG_NONE, &clutter_enable_accessibility, + N_("Enable accessibility"), NULL }, { NULL, }, }; diff --git a/clutter/clutter-main.h b/clutter/clutter-main.h index 067cef086..f5fe11b62 100644 --- a/clutter/clutter-main.h +++ b/clutter/clutter-main.h @@ -102,6 +102,7 @@ void clutter_do_event (ClutterEvent *event); gboolean clutter_get_debug_enabled (void); gboolean clutter_get_show_fps (void); gulong clutter_get_timestamp (void); +gboolean clutter_get_accessibility_enabled (void); /* Threading functions */ void clutter_threads_init (void); From 790d2165f3178cc947455acfd08d42dcafdbdd02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Mon, 26 Apr 2010 20:07:22 +0200 Subject: [PATCH 05/16] Add accessibility tests http://bugzilla.clutter-project.org/show_bug.cgi?id=2099 Signed-off-by: Emmanuele Bassi --- configure.ac | 1 + tests/Makefile.am | 2 +- tests/README | 3 + tests/accessibility/Makefile.am | 61 ++++ .../cally-atkcomponent-example.c | 102 +++++++ .../cally-atkeditabletext-example.c | 270 ++++++++++++++++++ tests/accessibility/cally-atkevents-example.c | 180 ++++++++++++ tests/accessibility/cally-atktext-example.c | 212 ++++++++++++++ tests/accessibility/cally-clone-example.c | 112 ++++++++ tests/accessibility/cally-examples-util.c | 216 ++++++++++++++ tests/accessibility/cally-examples-util.h | 24 ++ 11 files changed, 1182 insertions(+), 1 deletion(-) create mode 100644 tests/accessibility/Makefile.am create mode 100644 tests/accessibility/cally-atkcomponent-example.c create mode 100644 tests/accessibility/cally-atkeditabletext-example.c create mode 100644 tests/accessibility/cally-atkevents-example.c create mode 100644 tests/accessibility/cally-atktext-example.c create mode 100644 tests/accessibility/cally-clone-example.c create mode 100644 tests/accessibility/cally-examples-util.c create mode 100644 tests/accessibility/cally-examples-util.h diff --git a/configure.ac b/configure.ac index 9a35c8244..fc4a0be2a 100644 --- a/configure.ac +++ b/configure.ac @@ -1030,6 +1030,7 @@ AC_CONFIG_FILES([ clutter/cogl/pango/Makefile clutter/json/Makefile tests/Makefile + tests/accessibility/Makefile tests/conform/Makefile tests/data/Makefile tests/interactive/Makefile diff --git a/tests/Makefile.am b/tests/Makefile.am index e1d8350b8..6447d5c2a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = data interactive micro-bench tools +SUBDIRS = accessibility data interactive micro-bench tools if BUILD_TESTS SUBDIRS += conform diff --git a/tests/README b/tests/README index 4a61151b7..48fd2f386 100644 --- a/tests/README +++ b/tests/README @@ -20,6 +20,9 @@ covers most of the original Clutter tests. Ideally some of these tests will be migrated into the conformance/ directory so they can be used in automated nightly tests. +The accessibility/ tests are tests created to test the accessibility support of +clutter, testing some of the atk interfaces. + The data/ directory contains optional data (like images and ClutterScript definitions) that can be referenced by a test. diff --git a/tests/accessibility/Makefile.am b/tests/accessibility/Makefile.am new file mode 100644 index 000000000..81bc980a2 --- /dev/null +++ b/tests/accessibility/Makefile.am @@ -0,0 +1,61 @@ +include $(top_srcdir)/build/autotools/Makefile.am.silent + +EXAMPLES = cally-atkcomponent-example \ + cally-atkeditabletext-example \ + cally-atkevents-example \ + cally-atktext-example \ + cally-clone-example + +common_ldadd = $(top_builddir)/clutter/libclutter-@CLUTTER_WINSYS@-@CLUTTER_API_VERSION@.la + +CALLY_UTIL_SOURCES = cally-examples-util.c + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/clutter \ + -I$(top_srcdir)/clutter/cogl \ + -I$(top_builddir)/clutter \ + -I$(top_builddir)/clutter/cogl \ + -I$(top_srcdir)/tests/accessibility + +noinst_PROGRAMS = $(EXAMPLES) + +# atk component example +cally_atkcomponent_example_LDADD = $(CLUTTER_LIBS) $(common_ldadd) +cally_atkcomponent_example_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) \ + -DPREFIXDIR=\"$(libdir)\" \ + $(INCLUDES) +cally_atkcomponent_example_SOURCES = cally-atkcomponent-example.c \ + $(CALLY_UTIL_SOURCES) + +# atk text example +cally_atktext_example_LDADD = $(CLUTTER_LIBS) $(common_ldadd) +cally_atktext_example_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)\ + -DPREFIXDIR=\"$(libdir)\" \ + $(INCLUDES) +cally_atktext_example_SOURCES = cally-atktext-example.c \ + $(CALLY_UTIL_SOURCES) + +# atk text example2 +cally_atkevents_example_LDADD = $(CLUTTER_LIBS) $(common_ldadd) +cally_atkevents_example_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)\ + -DPREFIXDIR=\"$(libdir)\" \ + $(INCLUDES) +cally_atkevents_example_SOURCES = cally-atkevents-example.c \ + $(CALLY_UTIL_SOURCES) + +# atk editable text example +cally_atkeditabletext_example_LDADD = $(CLUTTER_LIBS) $(common_ldadd) +cally_atkeditabletext_example_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) \ + -DPREFIXDIR=\"$(libdir)\" \ + $(INCLUDES) +cally_atkeditabletext_example_SOURCES = cally-atkeditabletext-example.c \ + $(CALLY_UTIL_SOURCES) + +# cally clone example +cally_clone_example_LDADD = $(CLUTTER_LIBS) $(common_ldadd) +cally_clone_example_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS) \ + -DPREFIXDIR=\"$(libdir)\" \ + $(INCLUDES) +cally_clone_example_SOURCES = cally-clone-example.c \ + $(CALLY_UTIL_SOURCES) diff --git a/tests/accessibility/cally-atkcomponent-example.c b/tests/accessibility/cally-atkcomponent-example.c new file mode 100644 index 000000000..c50a1abaa --- /dev/null +++ b/tests/accessibility/cally-atkcomponent-example.c @@ -0,0 +1,102 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "cally-examples-util.h" + +#define WIDTH 300 +#define HEIGHT 300 +#define SIZE 50 +#define DEPTH -100 + +static const ClutterColor color1 = { 0xff, 0xff, 0x00, 0xff }; +static const ClutterColor color2 = { 0x00, 0xff, 0x00, 0xff }; +static const ClutterColor color3 = { 0x00, 0x00, 0xff, 0xff }; +static const ClutterColor color4 = { 0xff, 0x00, 0xff, 0xff }; + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage = NULL; + ClutterColor color = { 0x00, 0x00, 0x00, 0xff }; + ClutterActor *button1 = NULL; + ClutterActor *button2 = NULL; + ClutterActor *button3 = NULL; + ClutterActor *button4 = NULL; + ClutterActor *group[4]; + ClutterGeometry geom = {0, 0, SIZE, SIZE}; + gint i = 0; + + clutter_init (&argc, &argv); + + cally_util_a11y_init (&argc, &argv); + + stage = clutter_stage_get_default (); + + clutter_stage_set_color (CLUTTER_STAGE (stage), &color); + clutter_actor_set_size (stage, WIDTH, HEIGHT); + + button1 = clutter_rectangle_new_with_color (&color1); + clutter_actor_set_geometry (button1, &geom); + + button2 = clutter_rectangle_new_with_color (&color2); + geom.x = 2*SIZE; + geom.y = 0; + clutter_actor_set_geometry (button2, &geom); + + geom.x = 0; + geom.y = 2*SIZE; + button3 = clutter_rectangle_new_with_color (&color3); + clutter_actor_set_geometry (button3, &geom); + clutter_actor_set_depth( button3, DEPTH); + + /* a nested hierarchy, to check that the relative positions are + computed properly */ + geom.x = SIZE/2; + geom.y = SIZE/2; + button4 = clutter_rectangle_new_with_color (&color4); + clutter_actor_set_geometry (button4, &geom); + clutter_actor_show (button4); + + for (i = 0; i < 4; i++) { + group[i] = clutter_group_new (); + clutter_actor_set_geometry (group[i], &geom); + + if (i > 0) + clutter_group_add (CLUTTER_GROUP (group[i]), group [i - 1]); + + clutter_actor_show_all (group[i]); + } + + clutter_group_add (CLUTTER_GROUP (stage), button1); + clutter_group_add (CLUTTER_GROUP (stage), button2); + clutter_group_add (CLUTTER_GROUP (stage), button3); + clutter_group_add (CLUTTER_GROUP (stage), group[3]); + clutter_group_add (CLUTTER_GROUP (group[0]), button4); + + clutter_actor_show_all (stage); + + clutter_main (); + + return 0; +} diff --git a/tests/accessibility/cally-atkeditabletext-example.c b/tests/accessibility/cally-atkeditabletext-example.c new file mode 100644 index 000000000..93ccc7b7b --- /dev/null +++ b/tests/accessibility/cally-atkeditabletext-example.c @@ -0,0 +1,270 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "cally-examples-util.h" + +#define WIDTH 800 +#define HEIGHT 600 + +static ClutterActor *text_actor = NULL; +static ClutterActor *text_editable_actor = NULL; + +/* + * Test AtkText interface + */ +static void +test_atk_text (ClutterActor *actor) +{ + AtkObject *object = NULL; + AtkEditableText *cally_editable_text = NULL; + gint pos = 0; + + object = atk_gobject_accessible_for_object (G_OBJECT (actor)); + cally_editable_text = ATK_EDITABLE_TEXT (object); + + if (cally_editable_text != NULL) { + atk_editable_text_set_text_contents (cally_editable_text, "New text"); + atk_editable_text_delete_text (cally_editable_text, 0, 3); + pos = 3; + atk_editable_text_insert_text (cally_editable_text, "New", 0, &pos); + + /* Not implemented in cally, just checking that we can call this + functions */ + atk_editable_text_copy_text (cally_editable_text, 0, -1); + atk_editable_text_paste_text (cally_editable_text, 5); + atk_editable_text_cut_text (cally_editable_text, 0, -1); + } +} + +static gboolean +insert_text_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + gpointer data) +{ + AtkObject *object = NULL; + AtkEditableText *cally_editable_text = NULL; + gint pos = 0; + + object = atk_gobject_accessible_for_object (G_OBJECT (text_editable_actor)); + cally_editable_text = ATK_EDITABLE_TEXT (object); + + pos = 3; + atk_editable_text_insert_text (cally_editable_text, "New", 0, &pos); + + return TRUE; +} + +static gboolean +delete_text_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + gpointer data) +{ + AtkObject *object = NULL; + AtkEditableText *cally_editable_text = NULL; + + object = atk_gobject_accessible_for_object (G_OBJECT (text_editable_actor)); + cally_editable_text = ATK_EDITABLE_TEXT (object); + + atk_editable_text_delete_text (cally_editable_text, 0, 3); + + return TRUE; +} + +static gboolean +set_text_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + gpointer data) +{ + AtkObject *object = NULL; + AtkEditableText *cally_editable_text = NULL; + + object = atk_gobject_accessible_for_object (G_OBJECT (text_editable_actor)); + cally_editable_text = ATK_EDITABLE_TEXT (object); + + atk_editable_text_set_text_contents (cally_editable_text, "New text"); + + return TRUE; +} + +static gboolean +activate_deactivate_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + gpointer data) +{ + gboolean active = FALSE; + + active = clutter_text_get_activatable (CLUTTER_TEXT (text_editable_actor)); + clutter_text_set_activatable (CLUTTER_TEXT (text_editable_actor), !active); + + return TRUE; +} + +static gboolean +print_cursor_position_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + gpointer data) +{ + gint pos = 0; + + pos = clutter_text_get_cursor_position (CLUTTER_TEXT (text_editable_actor)); + + g_print ("current cursor position %i\n", pos); + + return TRUE; +} + +static void +activate_cb (ClutterActor *actor, + gpointer data) +{ + g_print ("Actor activated\n"); +} + +static ClutterActor* +_create_button (const gchar *text) +{ + ClutterActor *button = NULL; + ClutterActor *rectangle = NULL; + ClutterActor *label = NULL; + ClutterColor color_rect = { 0x00, 0xff, 0xff, 0xff }; + ClutterColor color_label = { 0x00, 0x00, 0x00, 0xff }; + + button = clutter_group_new (); + rectangle = clutter_rectangle_new_with_color (&color_rect); + clutter_actor_set_size (rectangle, 375, 35); + + label = clutter_text_new_full ("Sans Bold 32px", + text, &color_label); + clutter_group_add (CLUTTER_GROUP (button), rectangle); + clutter_group_add (CLUTTER_GROUP (button), label); + clutter_actor_set_reactive (button, TRUE); + + return button; +} + + +static void +make_ui (ClutterActor *stage) +{ + ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff }; + ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff }; + ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 }; + ClutterActor *button = NULL; + + clutter_stage_set_color (CLUTTER_STAGE (stage), &color_stage); + clutter_actor_set_size (stage, WIDTH, HEIGHT); + + /* text */ + text_actor = clutter_text_new_full ("Sans Bold 32px", + "Lorem ipsum dolor sit amet", + &color_text); + clutter_group_add (CLUTTER_GROUP (stage), text_actor); + + /* text_editable */ + text_editable_actor = clutter_text_new_full ("Sans Bold 32px", + "consectetur adipisicing elit", + &color_text); + clutter_actor_set_position (text_editable_actor, 0, 100); + clutter_text_set_editable (CLUTTER_TEXT (text_editable_actor), TRUE); + clutter_text_set_selectable (CLUTTER_TEXT (text_editable_actor), TRUE); + clutter_text_set_selection_color (CLUTTER_TEXT (text_editable_actor), + &color_sel); + clutter_text_set_activatable (CLUTTER_TEXT (text_editable_actor), + TRUE); + clutter_text_set_line_wrap (CLUTTER_TEXT (text_editable_actor), TRUE); + clutter_actor_grab_key_focus (text_editable_actor); + clutter_actor_set_reactive (text_editable_actor, TRUE); + + clutter_group_add (CLUTTER_GROUP (stage), text_editable_actor); + g_signal_connect (text_editable_actor, "activate", + G_CALLBACK (activate_cb), NULL); + + /* test buttons */ + button = _create_button ("Set"); + clutter_actor_set_position (button, 100, 200); + + g_signal_connect_after (button, "button-press-event", + G_CALLBACK (set_text_press_cb), NULL); + + clutter_group_add (CLUTTER_GROUP (stage), button); + + button = _create_button ("Delete"); + clutter_actor_set_position (button, 100, 250); + + g_signal_connect_after (button, "button-press-event", + G_CALLBACK (delete_text_press_cb), NULL); + + clutter_group_add (CLUTTER_GROUP (stage), button); + + button = _create_button ("Insert"); + clutter_actor_set_position (button, 100, 300); + + g_signal_connect_after (button, "button-press-event", + G_CALLBACK (insert_text_press_cb), NULL); + + clutter_group_add (CLUTTER_GROUP (stage), button); + + button = _create_button ("Activate/Deactivate"); + clutter_actor_set_position (button, 100, 350); + + g_signal_connect_after (button, "button-press-event", + G_CALLBACK (activate_deactivate_press_cb), NULL); + + clutter_group_add (CLUTTER_GROUP (stage), button); + + button = _create_button ("Cursor position"); + clutter_actor_set_position (button, 100, 450); + + g_signal_connect_after (button, "button-press-event", + G_CALLBACK (print_cursor_position_press_cb), NULL); + + clutter_group_add (CLUTTER_GROUP (stage), button); + +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage = NULL; + + g_set_application_name ("AtkEditableText"); + + clutter_init (&argc, &argv); + + cally_util_a11y_init (&argc, &argv); + + stage = clutter_stage_get_default (); + + make_ui (stage); + + clutter_actor_show_all (stage); + + test_atk_text (text_actor); + test_atk_text (text_editable_actor); + + clutter_main (); + + return 0; +} diff --git a/tests/accessibility/cally-atkevents-example.c b/tests/accessibility/cally-atkevents-example.c new file mode 100644 index 000000000..422e55a1b --- /dev/null +++ b/tests/accessibility/cally-atkevents-example.c @@ -0,0 +1,180 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * The purpose of this example is test key event and global event + * implementation, specifically: + * + * atk_add_global_event_listener + * atk_remove_global_event_listener + * atk_add_key_event_listener + * atk_remove_key_event_listener + */ +#include +#include + +#include "cally-examples-util.h" + +#define WIDTH 800 +#define HEIGHT 600 +#define HEIGHT_STEP 100 +#define NUM_ENTRIES 3 + +struct _Data{ + gint value; +}; +typedef struct _Data Data; + +static gboolean +atk_key_listener (AtkKeyEventStruct *event, gpointer data) +{ + Data *my_data = (Data*) data; + + g_print ("atk_listener: 0x%x ", event->keyval); + + if (my_data != NULL) { + g_print ("\t Data value: %i\n", my_data->value); + } else { + g_print ("\tNo data!!\n"); + } + + return FALSE; +} + +static gboolean +window_event_listener (GSignalInvocationHint * signal_hint, + guint n_param_values, + const GValue * param_values, gpointer data) +{ + AtkObject *accessible; + GSignalQuery signal_query; + const gchar *name, *s; + + g_signal_query (signal_hint->signal_id, &signal_query); + name = signal_query.signal_name; + + accessible = ATK_OBJECT (g_value_get_object (¶m_values[0])); + s = atk_object_get_name (accessible); + + g_print ("Detected window event \"%s\" from object \"%p\" named \"%s\"\n", + name, accessible, s); + + return TRUE; +} +static void +make_ui (ClutterActor *stage) +{ + gint i = 0; + ClutterActor *editable = NULL; + ClutterActor *rectangle = NULL; + ClutterActor *label = NULL; + ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff }; + ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff }; + ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 }; + ClutterColor color_label = { 0x00, 0xff, 0x55, 0xff }; + ClutterColor color_rect = { 0x00, 0xff, 0xff, 0x55 }; + ClutterGeometry label_geom = {0, 50, -1, -1}; + ClutterGeometry editable_geom = {150, 50, 500, 75}; + + + clutter_stage_set_color (CLUTTER_STAGE (stage), &color_stage); + clutter_actor_set_size (stage, WIDTH, HEIGHT); + + for (i = 0; i < NUM_ENTRIES; i++) + { + /* label */ + label = clutter_text_new_full ("Sans Bold 32px", + "Entry", + &color_label); + clutter_actor_set_geometry (label, &label_geom); + + /* editable */ + editable = clutter_text_new_full ("Sans Bold 32px", + "ddd", + &color_text); + clutter_actor_set_geometry (editable, &editable_geom); + clutter_text_set_editable (CLUTTER_TEXT (editable), TRUE); + clutter_text_set_selectable (CLUTTER_TEXT (editable), TRUE); + clutter_text_set_selection_color (CLUTTER_TEXT (editable), + &color_sel); + clutter_actor_grab_key_focus (editable); + clutter_actor_set_reactive (editable, TRUE); + + /* rectangle: to create a entry "feeling" */ + rectangle = clutter_rectangle_new_with_color (&color_rect); + clutter_actor_set_geometry (rectangle, &editable_geom); + + clutter_group_add (CLUTTER_GROUP (stage), label); + clutter_group_add (CLUTTER_GROUP (stage), editable); + clutter_group_add (CLUTTER_GROUP (stage), rectangle); + + label_geom.y += HEIGHT_STEP; + editable_geom.y += HEIGHT_STEP; + } +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage = NULL; + Data data1, data2,data3; + guint id_2 = 0; + + g_set_application_name ("AtkText"); + + clutter_init (&argc, &argv); + + cally_util_a11y_init (&argc, &argv); + + data1.value = 10; + data2.value = 20; + data3.value = 30; + + /* key event listeners */ + atk_add_key_event_listener ((AtkKeySnoopFunc)atk_key_listener, &data1); + id_2 = atk_add_key_event_listener ((AtkKeySnoopFunc)atk_key_listener, &data2); + atk_add_key_event_listener ((AtkKeySnoopFunc)atk_key_listener, &data3); + + atk_remove_key_event_listener (id_2); + + /* event listeners */ + atk_add_global_event_listener (window_event_listener, "window:create"); + atk_add_global_event_listener (window_event_listener, "window:destroy"); + atk_add_global_event_listener (window_event_listener, "window:activate"); + atk_add_global_event_listener (window_event_listener, "window:deactivate"); + + stage = clutter_stage_get_default (); + make_ui (stage); + + clutter_actor_show_all (stage); + + if (clutter_feature_available (CLUTTER_FEATURE_STAGE_MULTIPLE)) + { + stage = clutter_stage_new (); + make_ui (stage); + clutter_actor_show_all (stage); + } + + clutter_main (); + + return 0; +} diff --git a/tests/accessibility/cally-atktext-example.c b/tests/accessibility/cally-atktext-example.c new file mode 100644 index 000000000..c456ec101 --- /dev/null +++ b/tests/accessibility/cally-atktext-example.c @@ -0,0 +1,212 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "cally-examples-util.h" + +#define WIDTH 800 +#define HEIGHT 600 + +static ClutterActor *text_actor = NULL; +static ClutterActor *text_editable_actor = NULL; + +/* + * Test AtkText interface + */ +static void +test_atk_text (ClutterActor *actor) +{ + gchar *text = NULL; + AtkObject *object = NULL; + AtkText *cally_text = NULL; + gboolean bool = FALSE; + gunichar unichar; + gchar buf[7]; + gint count = -1; + gint start = -1; + gint end = -1; + gint pos = -1; + AtkAttributeSet *at_set = NULL; + + object = atk_gobject_accessible_for_object (G_OBJECT (actor)); + cally_text = ATK_TEXT (object); + + if (cally_text != NULL) { + text = atk_text_get_text (cally_text, 0, -1); + g_print ("atk_text_get_text output: %s\n", text); + g_free (text); text = NULL; + + unichar = atk_text_get_character_at_offset (cally_text, 5); + g_unichar_to_utf8 (unichar, buf); + g_print ("atk_text_get_character_at_offset: %s\n", buf); + + text = atk_text_get_text_before_offset (cally_text, + 5, ATK_TEXT_BOUNDARY_WORD_END, + &start, &end); + g_print ("atk_text_get_text_before_offset: %s, %i, %i\n", + text, start, end); + g_free (text); text = NULL; + + text = atk_text_get_text_at_offset (cally_text, + 5, ATK_TEXT_BOUNDARY_WORD_END, + &start, &end); + g_print ("atk_text_get_text_at_offset: %s, %i, %i\n", + text, start, end); + g_free (text); text = NULL; + + text = atk_text_get_text_after_offset (cally_text, + 5, ATK_TEXT_BOUNDARY_WORD_END, + &start, &end); + g_print ("atk_text_get_text_after_offset: %s, %i, %i\n", + text, start, end); + g_free (text); text = NULL; + + pos = atk_text_get_caret_offset (cally_text); + g_print ("atk_text_get_caret_offset: %i\n", pos); + + atk_text_set_caret_offset (cally_text, 5); + + count = atk_text_get_character_count (cally_text); + g_print ("atk_text_get_character_count: %i\n", count); + + count = atk_text_get_n_selections (cally_text); + g_print ("atk_text_get_n_selections: %i\n", count); + + text = atk_text_get_selection (cally_text, 0, &start, &end); + g_print ("atk_text_get_selection: %s, %i, %i\n", text, start, end); + g_free(text); text = NULL; + + bool = atk_text_remove_selection (cally_text, 0); + g_print ("atk_text_remove_selection (0): %i\n", bool); + + bool = atk_text_remove_selection (cally_text, 1); + g_print ("atk_text_remove_selection (1): %i\n", bool); + + bool = atk_text_add_selection (cally_text, 5, 10); + g_print ("atk_text_add_selection: %i\n", bool); + + bool = atk_text_set_selection (cally_text, 0, 6, 10); + g_print ("atk_text_set_selection: %i\n", bool); + + at_set = atk_text_get_run_attributes (cally_text, 10, + &start, &end); + g_print ("atk_text_get_run_attributes: %i, %i\n", start, end); + + at_set = atk_text_get_default_attributes (cally_text); + g_print ("atk_text_get_default_attributes: (at_set==NULL) == %i \n", + at_set == NULL); + + } +} + +static gboolean +button_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + gpointer data) +{ + test_atk_text (text_actor); + test_atk_text (text_editable_actor); + + return TRUE; +} + +static void +make_ui (ClutterActor *stage) +{ + ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff }; + ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff }; + ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 }; + ClutterColor color_rect = { 0x00, 0xff, 0xff, 0xff }; + ClutterColor color_label = { 0x00, 0x00, 0x00, 0xff }; + ClutterActor *button = NULL; + ClutterActor *rectangle = NULL; + ClutterActor *label = NULL; + + clutter_stage_set_color (CLUTTER_STAGE (stage), &color_stage); + clutter_actor_set_size (stage, WIDTH, HEIGHT); + + /* text */ + text_actor = clutter_text_new_full ("Sans Bold 32px", + "Lorem ipsum dolor sit amet", + &color_text); + clutter_group_add (CLUTTER_GROUP (stage), text_actor); + + /* text_editable */ + text_editable_actor = clutter_text_new_full ("Sans Bold 32px", + "consectetur adipisicing elit", + &color_text); + clutter_actor_set_position (text_editable_actor, 0, 100); + clutter_text_set_editable (CLUTTER_TEXT (text_editable_actor), TRUE); + clutter_text_set_selectable (CLUTTER_TEXT (text_editable_actor), TRUE); + clutter_text_set_selection_color (CLUTTER_TEXT (text_editable_actor), + &color_sel); + clutter_text_set_line_wrap (CLUTTER_TEXT (text_editable_actor), TRUE); + clutter_actor_grab_key_focus (text_editable_actor); + clutter_actor_set_reactive (text_editable_actor, TRUE); + + clutter_group_add (CLUTTER_GROUP (stage), text_editable_actor); + + /* test button */ + button = clutter_group_new (); + rectangle = clutter_rectangle_new_with_color (&color_rect); + clutter_actor_set_size (rectangle, 75, 35); + + label = clutter_text_new_full ("Sans Bold 32px", + "Test", &color_label); + clutter_actor_set_position (button, 100, 200); + clutter_group_add (CLUTTER_GROUP (button), rectangle); + clutter_group_add (CLUTTER_GROUP (button), label); + clutter_actor_set_reactive (button, TRUE); + + g_signal_connect_after (button, "button-press-event", + G_CALLBACK (button_press_cb), NULL); + + clutter_group_add (CLUTTER_GROUP (stage), button); + +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage = NULL; + + g_set_application_name ("AtkText"); + + clutter_init (&argc, &argv); + + cally_util_a11y_init (&argc, &argv); + + stage = clutter_stage_get_default (); + + make_ui (stage); + + clutter_actor_show_all (stage); + + test_atk_text (text_actor); + test_atk_text (text_editable_actor); + + clutter_main (); + + return 0; +} diff --git a/tests/accessibility/cally-clone-example.c b/tests/accessibility/cally-clone-example.c new file mode 100644 index 000000000..efb62fa9b --- /dev/null +++ b/tests/accessibility/cally-clone-example.c @@ -0,0 +1,112 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include "cally-examples-util.h" + +#define WIDTH 800 +#define HEIGHT 600 +#define HEIGHT_STEP 100 +#define NUM_ENTRIES 3 + +static void +make_ui (ClutterActor *stage) +{ + ClutterActor *editable = NULL; + ClutterActor *rectangle = NULL; + ClutterActor *label = NULL; + ClutterColor color_stage = { 0x00, 0x00, 0x00, 0xff }; + ClutterColor color_text = { 0xff, 0x00, 0x00, 0xff }; + ClutterColor color_sel = { 0x00, 0xff, 0x00, 0x55 }; + ClutterColor color_label = { 0x00, 0xff, 0x55, 0xff }; + ClutterColor color_rect = { 0x00, 0xff, 0xff, 0x55 }; + ClutterGeometry editable_geom = {150, 50, 100, 75}; + ClutterActor *full_entry = NULL; + ClutterActor *cloned_entry = NULL; + + + clutter_stage_set_color (CLUTTER_STAGE (stage), &color_stage); + clutter_actor_set_size (stage, WIDTH, HEIGHT); + + label = clutter_text_new_full ("Sans Bold 32px", + "Entry", + &color_label); + clutter_actor_set_position (label, 0, 50); + + /* editable */ + editable = clutter_text_new_full ("Sans Bold 32px", + "ddd", + &color_text); + clutter_actor_set_position (editable, 150, 50); + clutter_text_set_editable (CLUTTER_TEXT (editable), TRUE); + clutter_text_set_selectable (CLUTTER_TEXT (editable), TRUE); + clutter_text_set_selection_color (CLUTTER_TEXT (editable), + &color_sel); + clutter_actor_grab_key_focus (editable); + clutter_actor_set_reactive (editable, TRUE); + + /* rectangle: to create a entry "feeling" */ + rectangle = clutter_rectangle_new_with_color (&color_rect); + clutter_actor_set_geometry (rectangle, &editable_geom); + + full_entry = clutter_group_new (); + clutter_actor_set_position (full_entry, 0, 50); + clutter_actor_set_size (full_entry, 100, 75); + clutter_group_add (CLUTTER_GROUP (full_entry), label); + clutter_group_add (CLUTTER_GROUP (full_entry), editable); + clutter_group_add (CLUTTER_GROUP (full_entry), rectangle); + clutter_actor_show_all (full_entry); + clutter_actor_set_scale (full_entry, 2, 1); + clutter_group_add (CLUTTER_GROUP (stage), full_entry); + + /* Cloning! */ + cloned_entry = clutter_clone_new (full_entry); + clutter_actor_set_position (cloned_entry, 50, 200); + clutter_actor_set_scale (cloned_entry, 1, 2); + clutter_actor_show_all (cloned_entry); + clutter_actor_set_reactive (cloned_entry, TRUE); + + clutter_group_add (CLUTTER_GROUP (stage), cloned_entry); +} + +int +main (int argc, char *argv[]) +{ + ClutterActor *stage = NULL; + + g_set_application_name ("Clone Example"); + + clutter_init (&argc, &argv); + + cally_util_a11y_init (&argc, &argv); + + stage = clutter_stage_get_default (); + make_ui (stage); + + clutter_actor_show_all (stage); + + clutter_main (); + + return 0; +} diff --git a/tests/accessibility/cally-examples-util.c b/tests/accessibility/cally-examples-util.c new file mode 100644 index 000000000..0c9a44a5f --- /dev/null +++ b/tests/accessibility/cally-examples-util.c @@ -0,0 +1,216 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include +#include + +#include + +#include "cally-examples-util.h" + +/* Checking the at-spi sources, the module directory is + * $(libdir)/gtk-2.0/modules + * + * It is supposed cally would be installed on the same libdir. + * + * You could use the option atk-bridge-dir to use other directory. + */ +#define ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY PREFIXDIR"/gtk-2.0/modules" + +/* Convenient default directory (debug purposes) */ +#define CALLY_DEFAULT_MODULE_DIRECTORY "../cally/.libs" + + +static gchar ** +_get_clutter_module_paths (void) +{ + gchar **retval; + GPtrArray *paths; + const gchar *modules_dir; + + paths = g_ptr_array_new (); + +/* CLUTTER_[API/ABI]_VERSION_S not provided by clutter */ +/* g_ptr_array_add (paths, */ +/* g_build_filename (g_get_home_dir (), */ +/* ".clutter-" CLUTTER_API_VERSION_S, */ +/* CLUTTER_ABI_VERSION_S, */ +/* "modules", */ +/* NULL)); */ +/* g_ptr_array_add (paths, */ +/* g_build_filename (CLUTTER_LIBDIR, */ +/* "clutter-" CLUTTER_API_VERSION_S, */ +/* CLUTTER_ABI_VERSION_S, */ +/* "modules", */ +/* NULL)); */ + + g_ptr_array_add (paths, g_strdup (CALLY_DEFAULT_MODULE_DIRECTORY)); + + modules_dir = g_getenv ("CLUTTER_MODULES_PATH"); + if (modules_dir) + g_ptr_array_add (paths, g_strdup (modules_dir)); + + g_ptr_array_add (paths, NULL); + + retval = (gchar **) paths->pdata; + g_ptr_array_free (paths, FALSE); + + return retval; +} + +static gchar * +_search_for_clutter_module (const gchar *module_name) +{ + gchar **paths, **path; + gchar *module_path = NULL; + + paths = _get_clutter_module_paths (); + + for (path = paths; *path; path++) + { + gchar *tmp_name; + + tmp_name = g_module_build_path (*path, module_name); + if (g_file_test (tmp_name, G_FILE_TEST_EXISTS)) + { + module_path = tmp_name; + break; + } + + g_free (tmp_name); + } + + g_strfreev (paths); + + return module_path; +} + +static gchar * +_search_for_bridge_module (const gchar *module_name) +{ + /* We simplify the search for the atk bridge, see see the definition + * of the macro for more information*/ + return g_strdup (ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY); +} + +static gchar* +_a11y_check_custom_bridge (int *argc, + char ***argv) +{ + GError *error = NULL; + GOptionContext *context; + static gchar *bridge_dir = NULL; + static GOptionEntry entries [] = + { + {"atk-bridge-dir", 'd', 0, G_OPTION_ARG_STRING, &bridge_dir, "atk-bridge module directory", NULL} + }; + + context = g_option_context_new ("- cally examples"); + g_option_context_add_main_entries (context, entries, NULL); + if (!g_option_context_parse (context, argc, argv, &error)) + { + g_print ("%s\n", error->message); + g_print ("Use --help for more information.\n"); + exit (0); + } + + return bridge_dir; +} + + +static gboolean +_a11y_invoke_module (const gchar *module_path, + gboolean init) +{ + GModule *handle; + void (*invoke_fn) (void); + const char *method; + + if (init) + method = "gnome_accessibility_module_init"; + else + method = "gnome_accessibility_module_shutdown"; + + if (!module_path) + return FALSE; + + if (!(handle = g_module_open (module_path, G_MODULE_BIND_LAZY))) + { + g_warning ("Accessibility: failed to load module '%s': '%s'", + module_path, g_module_error ()); + + return FALSE; + } + + if (!g_module_symbol (handle, method, (gpointer *)&invoke_fn)) + { + g_warning ("Accessibility: error library '%s' does not include " + "method '%s' required for accessibility support", + module_path, method); + g_module_close (handle); + + return FALSE; + } + + g_debug ("Module %s loaded successfully", module_path); + invoke_fn (); + + return TRUE; +} + +/** + * This method will initialize the accessibility support provided by cally. + * + * Basically it will load the cally module using gmodule functions. + * + */ +void +cally_util_a11y_init (int *argc, char ***argv) +{ + gchar *bridge_dir = NULL; + gchar *cally_path = NULL; + gchar *bridge_path = NULL; + + cally_path = _search_for_clutter_module ("cally-1.0"); + + if (cally_path == NULL) + { + g_warning ("Accessibility: failed to find module 'cally-1.0' " + "which is needed to make this application accessible"); + return; + } + + bridge_dir = _a11y_check_custom_bridge (argc, argv); + if (bridge_dir == NULL) + bridge_dir = _search_for_bridge_module ("atk-bridge"); + + bridge_path = g_module_build_path (bridge_dir, "libatk-bridge"); + + + _a11y_invoke_module (cally_path, TRUE); + _a11y_invoke_module (bridge_path, TRUE); + + g_free (bridge_dir); + g_free (bridge_path); + g_free (cally_path); +} diff --git a/tests/accessibility/cally-examples-util.h b/tests/accessibility/cally-examples-util.h new file mode 100644 index 000000000..0245f3148 --- /dev/null +++ b/tests/accessibility/cally-examples-util.h @@ -0,0 +1,24 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2009 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +void +cally_util_a11y_init (int *argc, char ***argv); From e110b3569446b3c950273c69651e9aaed21e28a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Tue, 27 Apr 2010 12:08:42 +0200 Subject: [PATCH 06/16] Avoid to load cally module on a11y examples As cally is being integrated on clutter is not required to load cally module anymore. Anyway, it is still required to load the atk bridge by hand. The current way to load it could change in the future, more information here: https://bugzilla.gnome.org/show_bug.cgi?id=612599 https://bugzilla.gnome.org/show_bug.cgi?id=619946 Part [4/4] of CB#2099 --- tests/accessibility/cally-examples-util.c | 80 +---------------------- 1 file changed, 3 insertions(+), 77 deletions(-) diff --git a/tests/accessibility/cally-examples-util.c b/tests/accessibility/cally-examples-util.c index 0c9a44a5f..875d6fc0a 100644 --- a/tests/accessibility/cally-examples-util.c +++ b/tests/accessibility/cally-examples-util.c @@ -37,74 +37,6 @@ */ #define ATK_BRIDGE_DEFAULT_MODULE_DIRECTORY PREFIXDIR"/gtk-2.0/modules" -/* Convenient default directory (debug purposes) */ -#define CALLY_DEFAULT_MODULE_DIRECTORY "../cally/.libs" - - -static gchar ** -_get_clutter_module_paths (void) -{ - gchar **retval; - GPtrArray *paths; - const gchar *modules_dir; - - paths = g_ptr_array_new (); - -/* CLUTTER_[API/ABI]_VERSION_S not provided by clutter */ -/* g_ptr_array_add (paths, */ -/* g_build_filename (g_get_home_dir (), */ -/* ".clutter-" CLUTTER_API_VERSION_S, */ -/* CLUTTER_ABI_VERSION_S, */ -/* "modules", */ -/* NULL)); */ -/* g_ptr_array_add (paths, */ -/* g_build_filename (CLUTTER_LIBDIR, */ -/* "clutter-" CLUTTER_API_VERSION_S, */ -/* CLUTTER_ABI_VERSION_S, */ -/* "modules", */ -/* NULL)); */ - - g_ptr_array_add (paths, g_strdup (CALLY_DEFAULT_MODULE_DIRECTORY)); - - modules_dir = g_getenv ("CLUTTER_MODULES_PATH"); - if (modules_dir) - g_ptr_array_add (paths, g_strdup (modules_dir)); - - g_ptr_array_add (paths, NULL); - - retval = (gchar **) paths->pdata; - g_ptr_array_free (paths, FALSE); - - return retval; -} - -static gchar * -_search_for_clutter_module (const gchar *module_name) -{ - gchar **paths, **path; - gchar *module_path = NULL; - - paths = _get_clutter_module_paths (); - - for (path = paths; *path; path++) - { - gchar *tmp_name; - - tmp_name = g_module_build_path (*path, module_name); - if (g_file_test (tmp_name, G_FILE_TEST_EXISTS)) - { - module_path = tmp_name; - break; - } - - g_free (tmp_name); - } - - g_strfreev (paths); - - return module_path; -} - static gchar * _search_for_bridge_module (const gchar *module_name) { @@ -188,15 +120,12 @@ void cally_util_a11y_init (int *argc, char ***argv) { gchar *bridge_dir = NULL; - gchar *cally_path = NULL; gchar *bridge_path = NULL; - cally_path = _search_for_clutter_module ("cally-1.0"); - - if (cally_path == NULL) + if (clutter_get_accessibility_enabled () == FALSE) { - g_warning ("Accessibility: failed to find module 'cally-1.0' " - "which is needed to make this application accessible"); + g_warning ("Accessibility: clutter has no accessibility enabled" + " skipping the atk-bridge load"); return; } @@ -206,11 +135,8 @@ cally_util_a11y_init (int *argc, char ***argv) bridge_path = g_module_build_path (bridge_dir, "libatk-bridge"); - - _a11y_invoke_module (cally_path, TRUE); _a11y_invoke_module (bridge_path, TRUE); g_free (bridge_dir); g_free (bridge_path); - g_free (cally_path); } From e0a1f20ca2a0c38015acde9d1e77fa8c3e484a6c Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 5 Jul 2010 13:59:36 +0100 Subject: [PATCH 07/16] docs: Add Cally API reference --- .gitignore | 14 ++ configure.ac | 2 + doc/reference/Makefile.am | 2 +- doc/reference/cally/Makefile.am | 87 +++++++++++++ doc/reference/cally/cally-docs.xml.in | 130 ++++++++++++++++++ doc/reference/cally/cally-sections.txt | 174 +++++++++++++++++++++++++ doc/reference/cally/cally.types | 9 ++ doc/reference/clutter/Makefile.am | 3 +- 8 files changed, 419 insertions(+), 2 deletions(-) create mode 100644 doc/reference/cally/Makefile.am create mode 100644 doc/reference/cally/cally-docs.xml.in create mode 100644 doc/reference/cally/cally-sections.txt create mode 100644 doc/reference/cally/cally.types diff --git a/.gitignore b/.gitignore index d37b79a2a..c12698e92 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ stamp-marshal /clutter/cogl/cogl/driver/gles/cogl-fixed-fragment-shader.[ch] /clutter/x11/clutter-x11-enum-types.[ch] /clutter/json/*.gir +/clutter/cally/cally*.pc *.gir *.typelib config.* @@ -69,6 +70,19 @@ doc/reference/cogl/cogl.signals doc/reference/cogl/cogl-docs.xml doc/reference/cogl/*.stamp doc/reference/cogl/*.bak +doc/reference/cally/cally-*.txt +!/doc/reference/cally/cally-sections.txt +doc/reference/cally/html +doc/reference/cally/tmpl +doc/reference/cally/xml +doc/reference/cally/cally.args +doc/reference/cally/cally.hierarchy +doc/reference/cally/cally.interfaces +doc/reference/cally/cally.prerequisites +doc/reference/cally/cally.signals +doc/reference/cally/cally-docs.xml +doc/reference/cally/*.stamp +doc/reference/cally/*.bak doltcompile doltlibtool gtk-doc.make diff --git a/configure.ac b/configure.ac index fc4a0be2a..9fe375de2 100644 --- a/configure.ac +++ b/configure.ac @@ -1042,6 +1042,8 @@ AC_CONFIG_FILES([ doc/reference/clutter/clutter-docs.xml doc/reference/cogl/Makefile doc/reference/cogl/cogl-docs.xml + doc/reference/cally/Makefile + doc/reference/cally/cally-docs.xml doc/common/Makefile doc/manual/Makefile doc/manual/clutter-manual.xml diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 9c93f95fe..dc5b73965 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -1 +1 @@ -SUBDIRS = cogl clutter +SUBDIRS = cogl clutter cally diff --git a/doc/reference/cally/Makefile.am b/doc/reference/cally/Makefile.am new file mode 100644 index 000000000..02d81952f --- /dev/null +++ b/doc/reference/cally/Makefile.am @@ -0,0 +1,87 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=cally + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../gtk +DOC_SOURCE_DIR=../../../clutter/cally + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS=--type-init-func="clutter_base_init()" + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS=--deprecated-guards="CALLY_DISABLE_DEPRECATED" + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml +MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=cally + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS=\ + --extra-dir=../cogl/html \ + --extra-dir=../clutter/html \ + --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib \ + --extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/gobject \ + --extra-dir=$(CAIRO_PREFIX)/share/gtk-doc/html/cairo \ + --extra-dir=$(PANGO_PREFIX)/share/gtk-doc/html/pango + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/clutter/cally/*.h $(top_builddir)/clutter/cally/*.h +CFILE_GLOB=$(top_srcdir)/clutter/cally/*.c $(top_builddir)/clutter/cally/*.c + +# Header files to ignore when scanning. +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h +IGNORE_HFILES=cally-actor-private.h + +EXTRA_HFILES= + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files= + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) + +INCLUDES=-I$(top_srcdir) -I$(top_srcdir)/clutter -I$(top_srcdir)/clutter/cogl -I$(top_builddir) -I$(top_builddir)/clutter -I$(top_builddir)/clutter/cogl $(CLUTTER_CFLAGS) +GTKDOC_LIBS=$(top_builddir)/clutter/libclutter-@CLUTTER_SONAME_INFIX@-@CLUTTER_API_VERSION@.la $(CLUTTER_LIBS) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +#EXTRA_DIST += diff --git a/doc/reference/cally/cally-docs.xml.in b/doc/reference/cally/cally-docs.xml.in new file mode 100644 index 000000000..e0a5bf3dd --- /dev/null +++ b/doc/reference/cally/cally-docs.xml.in @@ -0,0 +1,130 @@ + + +]> + + + + Cally Reference Manual + for Clutter &version; + + + 2010 + Intel Corporation + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free + Documentation License, Version 1.1 or any later + version published by the Free Software Foundation with no + Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. You may obtain a copy of the GNU Free + Documentation License from the Free Software + Foundation by visiting their Web site or by writing + to: + +
+ The Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, + USA +
+
+
+
+ + + Cally Reference + + + Base Classes + + + + + + + + + + + Utility API + + + + + + + + + + + Cally Actors and Objects + + + Object Hierarchy + + + + + + Object Index + + + + + + + Index of all symbols + + + + + Index of deprecated symbols + + + + + Index of new symbols in 1.4 + + + + + License + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General + Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) + any later version. + + + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Library General Public License for + more details. + + + + You may obtain a copy of the GNU Library General + Public License from the Free Software Foundation by + visiting their Web + site or by writing to: + +
+ Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307 + USA +
+
+
+ +
diff --git a/doc/reference/cally/cally-sections.txt b/doc/reference/cally/cally-sections.txt new file mode 100644 index 000000000..bf275e9f0 --- /dev/null +++ b/doc/reference/cally/cally-sections.txt @@ -0,0 +1,174 @@ +
+cally-clone +CallyClone +CallyClone +CallyCloneClass +cally_clone_new + +CALLY_CLONE +CALLY_IS_CLONE +CALLY_TYPE_CLONE +CALLY_CLONE_CLASS +CALLY_IS_CLONE_CLASS +CALLY_CLONE_GET_CLASS + +CallyClonePrivate +cally_clone_get_type +
+ +
+cally-actor +CallyActor +CallyActor +CallyActorClass +CallyActionFunc +cally_actor_new +cally_actor_add_action +cally_actor_remove_action +cally_actor_remove_action_by_name + +CALLY_ACTOR +CALLY_IS_ACTOR +CALLY_TYPE_ACTOR +CALLY_ACTOR_CLASS +CALLY_IS_ACTOR_CLASS +CALLY_ACTOR_GET_CLASS + +CallyActorPrivate +cally_actor_get_type +
+ +
+cally-text +CallyText +CallyText +CallyTextClass +cally_text_new + +CALLY_TEXT +CALLY_IS_TEXT +CALLY_TYPE_TEXT +CALLY_TEXT_CLASS +CALLY_IS_TEXT_CLASS +CALLY_TEXT_GET_CLASS + +CallyTextPrivate +cally_text_get_type +
+ +
+cally-util +CallyUtil +CallyUtil +CallyUtilClass + +CALLY_UTIL +CALLY_IS_UTIL +CALLY_TYPE_UTIL +CALLY_UTIL_CLASS +CALLY_IS_UTIL_CLASS +CALLY_UTIL_GET_CLASS + +CallyUtilPrivate +cally_util_get_type +
+ +
+cally-texture +CallyTexture +CallyTexture +CallyTextureClass +cally_texture_new + +CALLY_TEXTURE +CALLY_IS_TEXTURE +CALLY_TYPE_TEXTURE +CALLY_TEXTURE_CLASS +CALLY_IS_TEXTURE_CLASS +CALLY_TEXTURE_GET_CLASS + +CallyTexturePrivate +cally_texture_get_type +
+ +
+cally-root +CallyRoot +CallyRoot +CallyRootClass +cally_root_new + +CALLY_ROOT +CALLY_IS_ROOT +CALLY_TYPE_ROOT +CALLY_ROOT_CLASS +CALLY_IS_ROOT_CLASS +CALLY_ROOT_GET_CLASS + +CallyRootPrivate +cally_root_get_type +
+ +
+cally-group +CallyGroup +CallyGroup +CallyGroupClass +cally_group_new + +CALLY_GROUP +CALLY_IS_GROUP +CALLY_TYPE_GROUP +CALLY_GROUP_CLASS +CALLY_IS_GROUP_CLASS +CALLY_GROUP_GET_CLASS + +CallyGroupPrivate +cally_group_get_type +
+ +
+cally-stage +CallyStage +CallyStage +CallyStageClass +cally_stage_new + +CALLY_STAGE +CALLY_IS_STAGE +CALLY_TYPE_STAGE +CALLY_STAGE_CLASS +CALLY_IS_STAGE_CLASS +CALLY_STAGE_GET_CLASS + +CallyStagePrivate +cally_stage_get_type +
+ +
+cally-rectangle +CallyRectangle +CallyRectangle +CallyRectangleClass +cally_rectangle_new + +CALLY_RECTANGLE +CALLY_IS_RECTANGLE +CALLY_TYPE_RECTANGLE +CALLY_RECTANGLE_CLASS +CALLY_IS_RECTANGLE_CLASS +CALLY_RECTANGLE_GET_CLASS + +CallyRectanglePrivate +cally_rectangle_get_type +
+ +
+cally +General API +cally_get_cally_initialized +cally_accessibility_init + +CALLY_ACCESSIBLE_FACTORY +CALLY_ACTOR_SET_FACTORY +
diff --git a/doc/reference/cally/cally.types b/doc/reference/cally/cally.types new file mode 100644 index 000000000..085efc2bb --- /dev/null +++ b/doc/reference/cally/cally.types @@ -0,0 +1,9 @@ +cally_actor_get_type +cally_clone_get_type +cally_group_get_type +cally_rectangle_get_type +cally_root_get_type +cally_stage_get_type +cally_text_get_type +cally_texture_get_type +cally_util_get_type diff --git a/doc/reference/clutter/Makefile.am b/doc/reference/clutter/Makefile.am index 5b89cc071..041231f9e 100644 --- a/doc/reference/clutter/Makefile.am +++ b/doc/reference/clutter/Makefile.am @@ -81,13 +81,14 @@ IGNORE_HFILES=\ clutter-script-private.h \ clutter-stage-window.h \ clutter-timeout-interval.h \ + cally \ cogl \ egl \ fruity \ glx \ + json \ osx \ x11 \ - json \ win32 EXTRA_HFILES=\ From da4dbbb9260fcbe3a142e0287a6b3b2ea90420ff Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 5 Jul 2010 14:00:29 +0100 Subject: [PATCH 08/16] Add binaries of the Cally examples to the ignore file --- tests/accessibility/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/accessibility/.gitignore diff --git a/tests/accessibility/.gitignore b/tests/accessibility/.gitignore new file mode 100644 index 000000000..2b1a0b151 --- /dev/null +++ b/tests/accessibility/.gitignore @@ -0,0 +1,5 @@ +/cally-atkcomponent-example +/cally-atkeditabletext-example +/cally-atkevents-example +/cally-atktext-example +/cally-clone-example From 09c6553f0dd086413ce80c17eec05665a6ea03d3 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 5 Jul 2010 14:43:18 +0100 Subject: [PATCH 09/16] cally: Clean up the headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make Cally follow the single-include header file policy of Clutter and Cogl; this means making cally.h the single include header, and requires a new cally-main.h file for the functions defined by cally.h. Also: • clean up the licensing notice and remove the FSF address; • document the object structures (instance and class); • G_GNUC_CONST-ify the get_type() functions; • reduce the padding for CallyActor sub-classes; • reduce the amount of headers included. --- clutter/cally/Makefile.am | 3 +- clutter/cally/cally-actor-private.h | 11 +++--- clutter/cally/cally-actor.c | 11 +++--- clutter/cally/cally-actor.h | 45 +++++++++++++++++++----- clutter/cally/cally-clone.h | 35 ++++++++++++++----- clutter/cally/cally-group.h | 34 ++++++++++++++---- clutter/cally/cally-main.h | 39 +++++++++++++++++++++ clutter/cally/cally-rectangle.h | 35 ++++++++++++++----- clutter/cally/cally-root.h | 32 +++++++++++++---- clutter/cally/cally-stage.h | 34 ++++++++++++++---- clutter/cally/cally-text.c | 6 ++++ clutter/cally/cally-text.h | 53 ++++++++++++++++++++--------- clutter/cally/cally-texture.h | 35 ++++++++++++++----- clutter/cally/cally-util.h | 31 +++++++++++++---- clutter/cally/cally.c | 7 ++++ clutter/cally/cally.h | 29 +++++++++------- clutter/cally/cally.pc.in | 8 ++--- doc/reference/cally/Makefile.am | 2 +- 18 files changed, 346 insertions(+), 104 deletions(-) create mode 100644 clutter/cally/cally-main.h diff --git a/clutter/cally/Makefile.am b/clutter/cally/Makefile.am index 75cec6a2b..2abbe9bdb 100644 --- a/clutter/cally/Makefile.am +++ b/clutter/cally/Makefile.am @@ -23,6 +23,7 @@ cally_h_sources = cally.h \ cally-actor.h \ cally-factory.h \ cally-group.h \ + cally-main.h \ cally-rectangle.h \ cally-root.h \ cally-stage.h \ @@ -76,4 +77,4 @@ libcally_HEADERS = \ $(cally_h_sources) libcally_la_LIBADD = \ - $(CLUTTER_LIBS) \ No newline at end of file + $(CLUTTER_LIBS) diff --git a/clutter/cally/cally-actor-private.h b/clutter/cally/cally-actor-private.h index b9c0d0b46..e3d6b8dd2 100644 --- a/clutter/cally/cally-actor-private.h +++ b/clutter/cally/cally-actor-private.h @@ -1,9 +1,13 @@ /* CALLY - The Clutter Accessibility Implementation Library * - * Copyright (C) 2009 Igalia, S.L. + * Copyright (C) 2008 Igalia, S.L. * * Author: Alejandro Piñeiro Iglesias * + * Some parts are based on GailWidget from GAIL + * GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -15,10 +19,9 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ + #ifndef __CALLY_ACTOR_PRIVATE_H__ #define __CALLY_ACTOR_PRIVATE_H__ diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c index 55dad3c69..379c9b995 100644 --- a/clutter/cally/cally-actor.c +++ b/clutter/cally/cally-actor.c @@ -4,7 +4,7 @@ * * Author: Alejandro Piñeiro Iglesias * - * Some parts are based on GailWidget, GailContaineer, GailCell from GAIL + * Some parts are based on GailWidget from GAIL * GAIL - The GNOME Accessibility Implementation Library * Copyright 2001, 2002, 2003 Sun Microsystems Inc. * @@ -19,13 +19,12 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /** * SECTION:cally-actor + * @Title: CallyActor * @short_description: Implementation of the ATK interfaces for #ClutterActor * @see_also: #ClutterActor * @@ -33,7 +32,7 @@ * exposing the common elements on each ClutterActor (position, extents, etc). */ -/** +/* * * IMPLEMENTATION NOTES: * @@ -98,7 +97,9 @@ * */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include diff --git a/clutter/cally/cally-actor.h b/clutter/cally/cally-actor.h index 707845903..2aaef49c5 100644 --- a/clutter/cally/cally-actor.h +++ b/clutter/cally/cally-actor.h @@ -19,16 +19,18 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_ACTOR_H__ #define __CALLY_ACTOR_H__ #include -#include +#include G_BEGIN_DECLS @@ -47,23 +49,47 @@ typedef struct _CallyActorPrivate CallyActorPrivate; * CallyActionFunc: * @cally_actor: a #CallyActor * - * Action func, to be used on AtkAction implementation as a individual + * Action function, to be used on #AtkAction implementations as a individual * action + * + * Since: 1.4 */ -typedef void (*CallyActionFunc) (CallyActor *cally_actor); +typedef void (* CallyActionFunc) (CallyActor *cally_actor); +/** + * CallyActor: + * + * The CallyActor structure contains only private + * data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyActor { + /*< private >*/ AtkGObjectAccessible parent; - /* < private > */ CallyActorPrivate *priv; }; +/** + * CallyActorClass: + * @notify_clutter: FIXME + * @focus_clutter: FIXME + * @add_actor: FIXME + * @remove_actor: FIXME + * + * The CallyActorClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyActorClass { + /*< private >*/ AtkGObjectAccessibleClass parent_class; + /*< public >*/ /* Signal handler for notify signal on Clutter Actor */ void (*notify_clutter) (GObject *object, GParamSpec *pspec); @@ -82,12 +108,13 @@ struct _CallyActorClass ClutterActor *actor, gpointer data); + /*< private >*/ /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[32]; }; -GType cally_actor_get_type (void); +GType cally_actor_get_type (void) G_GNUC_CONST; AtkObject* cally_actor_new (ClutterActor *actor); guint cally_actor_add_action (CallyActor *cally_actor, diff --git a/clutter/cally/cally-clone.h b/clutter/cally/cally-clone.h index 7b63dbeae..aeda63d23 100644 --- a/clutter/cally/cally-clone.h +++ b/clutter/cally/cally-clone.h @@ -15,15 +15,18 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_CLONE_H__ #define __CALLY_CLONE_H__ -#include "cally-actor.h" +#include +#include G_BEGIN_DECLS @@ -34,28 +37,44 @@ G_BEGIN_DECLS #define CALLY_IS_CLONE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_CLONE)) #define CALLY_CLONE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_CLONE, CallyCloneClass)) - typedef struct _CallyClone CallyClone; typedef struct _CallyCloneClass CallyCloneClass; typedef struct _CallyClonePrivate CallyClonePrivate; +/** + * CallyClone: + * + * The CallyClone structure contains only private + * data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyClone { + /*< private >*/ CallyActor parent; - /* < private > */ CallyClonePrivate *priv; }; +/** + * CallyCloneClass: + * + * The CallyCloneClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyCloneClass { + /*< private >*/ CallyActorClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[8]; }; -GType cally_clone_get_type (void); +GType cally_clone_get_type (void) G_GNUC_CONST; AtkObject *cally_clone_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/cally/cally-group.h b/clutter/cally/cally-group.h index 86920030d..9813ef3cb 100644 --- a/clutter/cally/cally-group.h +++ b/clutter/cally/cally-group.h @@ -18,15 +18,18 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_GROUP_H__ #define __CALLY_GROUP_H__ -#include "cally-actor.h" +#include +#include G_BEGIN_DECLS @@ -41,23 +44,40 @@ typedef struct _CallyGroup CallyGroup; typedef struct _CallyGroupClass CallyGroupClass; typedef struct _CallyGroupPrivate CallyGroupPrivate; +/** + * CallyGroup: + * + * The CallyGroup structure contains only + * private data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyGroup { + /*< private >*/ CallyActor parent; - /* < private > */ CallyGroupPrivate *priv; }; +/** + * CallyGroupClass: + * + * The CallyGroupClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyGroupClass { + /*< private >*/ CallyActorClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[8]; }; -GType cally_group_get_type (void); +GType cally_group_get_type (void) G_GNUC_CONST; AtkObject* cally_group_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/cally/cally-main.h b/clutter/cally/cally-main.h new file mode 100644 index 000000000..00e613601 --- /dev/null +++ b/clutter/cally/cally-main.h @@ -0,0 +1,39 @@ +/* CALLY - The Clutter Accessibility Implementation Library + * + * Copyright (C) 2008 Igalia, S.L. + * + * Author: Alejandro Piñeiro Iglesias + * + * Some parts are based on GailWidget from GAIL + * GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __CALLY_MAIN_H__ +#define __CALLY_MAIN_H__ + +G_BEGIN_DECLS + +gboolean cally_get_cally_initialized (void); +gboolean cally_accessibility_init (void); + +G_END_DECLS + +#endif /* __CALLY_MAIN_H__ */ diff --git a/clutter/cally/cally-rectangle.h b/clutter/cally/cally-rectangle.h index b2230c311..23587fb0e 100644 --- a/clutter/cally/cally-rectangle.h +++ b/clutter/cally/cally-rectangle.h @@ -15,15 +15,18 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_RECTANGLE_H__ #define __CALLY_RECTANGLE_H__ -#include "cally-actor.h" +#include +#include G_BEGIN_DECLS @@ -34,28 +37,44 @@ G_BEGIN_DECLS #define CALLY_IS_RECTANGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_RECTANGLE)) #define CALLY_RECTANGLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_RECTANGLE, CallyRectangleClass)) - typedef struct _CallyRectangle CallyRectangle; typedef struct _CallyRectangleClass CallyRectangleClass; typedef struct _CallyRectanglePrivate CallyRectanglePrivate; +/** + * CallyRectangle: + * + * The CallyRectangle structure contains only private + * data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyRectangle { + /*< private >*/ CallyActor parent; - /* < private > */ CallyRectanglePrivate *priv; }; +/** + * CallyRectangleClass: + * + * The CallyRectangleClass structure contains + * only private data + * + * Since: 1.4 + */ struct _CallyRectangleClass { + /*< private >*/ CallyActorClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[8]; }; -GType cally_rectangle_get_type (void); +GType cally_rectangle_get_type (void) G_GNUC_CONST; AtkObject* cally_rectangle_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/cally/cally-root.h b/clutter/cally/cally-root.h index 540a74282..fd3dcbfd0 100644 --- a/clutter/cally/cally-root.h +++ b/clutter/cally/cally-root.h @@ -15,11 +15,13 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_ROOT_H__ #define __CALLY_ROOT_H__ @@ -38,27 +40,43 @@ typedef struct _CallyRoot CallyRoot; typedef struct _CallyRootClass CallyRootClass; typedef struct _CallyRootPrivate CallyRootPrivate; +/** + * CallyRoot: + * + * The CallyRoot structure contains only private + * data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyRoot { + /*< private >*/ AtkGObjectAccessible parent; - /* < private > */ CallyRootPrivate *priv; }; +/** + * CallyRootClass: + * + * The CallyRootClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyRootClass { + /*< private >*/ AtkGObjectAccessibleClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[16]; }; -GType cally_root_get_type (void); +GType cally_root_get_type (void) G_GNUC_CONST; AtkObject *cally_root_new (void); - G_END_DECLS #endif /* __CALLY_ROOT_H__ */ diff --git a/clutter/cally/cally-stage.h b/clutter/cally/cally-stage.h index e95c08eed..836c6a1aa 100644 --- a/clutter/cally/cally-stage.h +++ b/clutter/cally/cally-stage.h @@ -15,15 +15,18 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_STAGE_H__ #define __CALLY_STAGE_H__ -#include "cally-group.h" +#include +#include G_BEGIN_DECLS @@ -38,23 +41,40 @@ typedef struct _CallyStage CallyStage; typedef struct _CallyStageClass CallyStageClass; typedef struct _CallyStagePrivate CallyStagePrivate; +/** + * CallyStage: + * + * The CallyStage structure contains only + * private data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyStage { + /*< private >*/ CallyGroup parent; - /* < private > */ CallyStagePrivate *priv; }; +/** + * CallyStageClass: + * + * The CallyStageClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyStageClass { + /*< private >*/ CallyGroupClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[16]; }; -GType cally_stage_get_type (void); +GType cally_stage_get_type (void) G_GNUC_CONST; AtkObject *cally_stage_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/cally/cally-text.c b/clutter/cally/cally-text.c index bd55d299c..3ca103c31 100644 --- a/clutter/cally/cally-text.c +++ b/clutter/cally/cally-text.c @@ -64,9 +64,15 @@ * See details on bug CB#1734 */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "cally-text.h" #include "cally-actor-private.h" +#include "clutter-main.h" + static void cally_text_class_init (CallyTextClass *klass); static void cally_text_init (CallyText *cally_text); static void cally_text_finalize (GObject *obj); diff --git a/clutter/cally/cally-text.h b/clutter/cally/cally-text.h index 54e15d155..d465dafe5 100644 --- a/clutter/cally/cally-text.h +++ b/clutter/cally/cally-text.h @@ -15,47 +15,66 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_TEXT_H__ #define __CALLY_TEXT_H__ -#include "cally-actor.h" +#include +#include G_BEGIN_DECLS -#define CALLY_TYPE_TEXT (cally_text_get_type ()) -#define CALLY_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXT, CallyText)) -#define CALLY_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXT, CallyTextClass)) -#define CALLY_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXT)) -#define CALLY_IS_TEXT_CLASS(klass)(G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXT)) -#define CALLY_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXT, CallyTextClass)) +#define CALLY_TYPE_TEXT (cally_text_get_type ()) +#define CALLY_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALLY_TYPE_TEXT, CallyText)) +#define CALLY_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALLY_TYPE_TEXT, CallyTextClass)) +#define CALLY_IS_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALLY_TYPE_TEXT)) +#define CALLY_IS_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXT)) +#define CALLY_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXT, CallyTextClass)) +typedef struct _CallyText CallyText; +typedef struct _CallyTextClass CallyTextClass; +typedef struct _CallyTextPrivate CallyTextPrivate; -typedef struct _CallyText CallyText; -typedef struct _CallyTextClass CallyTextClass; -typedef struct _CallyTextPrivate CallyTextPrivate; - +/** + * CallyText: + * + * The CallyText structure contains only private + * data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyText { + /*< private >*/ CallyActor parent; - /* < private > */ CallyTextPrivate *priv; }; +/** + * CallyTextClass: + * + * The CallyTextClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyTextClass { + /*< private >*/ CallyActorClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[8]; }; -GType cally_text_get_type (void); +GType cally_text_get_type (void) G_GNUC_CONST; AtkObject* cally_text_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/cally/cally-texture.h b/clutter/cally/cally-texture.h index 6603ee2d1..70f1e8a54 100644 --- a/clutter/cally/cally-texture.h +++ b/clutter/cally/cally-texture.h @@ -15,15 +15,18 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_TEXTURE_H__ #define __CALLY_TEXTURE_H__ -#include "cally-actor.h" +#include +#include G_BEGIN_DECLS @@ -34,28 +37,44 @@ G_BEGIN_DECLS #define CALLY_IS_TEXTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CALLY_TYPE_TEXTURE)) #define CALLY_TEXTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CALLY_TYPE_TEXTURE, CallyTextureClass)) - typedef struct _CallyTexture CallyTexture; typedef struct _CallyTextureClass CallyTextureClass; typedef struct _CallyTexturePrivate CallyTexturePrivate; +/** + * CallyTexture: + * + * The CallyTexture structure contains only + * private data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyTexture { + /*< private >*/ CallyActor parent; - /* < private > */ CallyTexturePrivate *priv; }; +/** + * CallyTextureClass: + * + * The CallyTextureClass structure contains + * only private data + * + * Since: 1.4 + */ struct _CallyTextureClass { + /*< private >*/ CallyActorClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[8]; }; -GType cally_texture_get_type (void); +GType cally_texture_get_type (void) G_GNUC_CONST; AtkObject *cally_texture_new (ClutterActor *actor); G_END_DECLS diff --git a/clutter/cally/cally-util.h b/clutter/cally/cally-util.h index dfb68390b..23d386ce6 100644 --- a/clutter/cally/cally-util.h +++ b/clutter/cally/cally-util.h @@ -15,11 +15,13 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ +#if !defined(__CALLY_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + #ifndef __CALLY_UTIL_H__ #define __CALLY_UTIL_H__ @@ -38,23 +40,40 @@ typedef struct _CallyUtil CallyUtil; typedef struct _CallyUtilClass CallyUtilClass; typedef struct _CallyUtilPrivate CallyUtilPrivate; +/** + * CallyUtil: + * + * The CallyUtil structure contains only + * private data and should be accessed using the provided API + * + * Since: 1.4 + */ struct _CallyUtil { + /*< private >*/ AtkUtil parent; - /* < private > */ CallyUtilPrivate *priv; }; +/** + * CallyUtilClass: + * + * The CallyUtilClass structure contains only + * private data + * + * Since: 1.4 + */ struct _CallyUtilClass { + /*< private >*/ AtkUtilClass parent_class; /* padding for future expansion */ - gpointer _padding_dummy[30]; + gpointer _padding_dummy[8]; }; -GType cally_util_get_type (void); +GType cally_util_get_type (void) G_GNUC_CONST; G_END_DECLS diff --git a/clutter/cally/cally.c b/clutter/cally/cally.c index fd95d411c..b2419ca62 100644 --- a/clutter/cally/cally.c +++ b/clutter/cally/cally.c @@ -20,6 +20,10 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "cally.h" #include "cally-actor.h" @@ -33,7 +37,10 @@ #include "cally-factory.h" #include "cally-util.h" +#include "clutter.h" + #include "clutter-debug.h" +#include "clutter-private.h" static int cally_initialized = FALSE; diff --git a/clutter/cally/cally.h b/clutter/cally/cally.h index 4924dfec8..11fa9fc6c 100644 --- a/clutter/cally/cally.h +++ b/clutter/cally/cally.h @@ -15,21 +15,26 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ -#ifndef __CALLY_H -#define __CALLY_H +#ifndef __CALLY_H__ +#define __CALLY_H__ -#include +#define __CALLY_H_INSIDE__ -G_BEGIN_DECLS +#include "cally-actor.h" +#include "cally-clone.h" +#include "cally-factory.h" +#include "cally-group.h" +#include "cally-main.h" +#include "cally-rectangle.h" +#include "cally-root.h" +#include "cally-stage.h" +#include "cally-text.h" +#include "cally-texture.h" +#include "cally-util.h" -gboolean cally_get_cally_initialized (void); -gboolean cally_accessibility_init (void); +#undef __CALLY_H_INSIDE__ -G_END_DECLS - -#endif /* __CALLY_H */ +#endif /* __CALLY_H__ */ diff --git a/clutter/cally/cally.pc.in b/clutter/cally/cally.pc.in index baf0dc859..224668f79 100644 --- a/clutter/cally/cally.pc.in +++ b/clutter/cally/cally.pc.in @@ -2,12 +2,12 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ + apiversion=@CLUTTER_API_VERSION@ +winsys=@CLUTTER_WINSYS@ +soname_infix=@CLUTTER_SONAME_INFIX@ +cogl_driver=@COGL_DRIVER@ requires=@CLUTTER_REQUIRES@ -backend=@COGL_WINSYS@ #only kept for backward compatability -winsys=@COGL_WINSYS@ -cogl=@COGL_DRIVER@ #only kept for backward compatability -driver=@COGL_DRIVER@ Name: Cally Description: Clutter Accessibility Implementation Library diff --git a/doc/reference/cally/Makefile.am b/doc/reference/cally/Makefile.am index 02d81952f..ff52c2dac 100644 --- a/doc/reference/cally/Makefile.am +++ b/doc/reference/cally/Makefile.am @@ -53,7 +53,7 @@ CFILE_GLOB=$(top_srcdir)/clutter/cally/*.c $(top_builddir)/clutter/cally/*.c # Header files to ignore when scanning. # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h -IGNORE_HFILES=cally-actor-private.h +IGNORE_HFILES=cally-actor-private.h cally.h EXTRA_HFILES= From a63eb10855a94426ecd53cc9888f08b1ced1cede Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 5 Jul 2010 15:10:42 +0100 Subject: [PATCH 10/16] docs: Fix Cally documentation --- clutter/cally/cally-actor.c | 64 +++++++++++++++++++-------------- clutter/cally/cally-clone.c | 43 ++++++++++++++++++++-- clutter/cally/cally-group.c | 19 ++++++++-- clutter/cally/cally-rectangle.c | 4 +-- clutter/cally/cally-root.c | 11 +++--- clutter/cally/cally-stage.c | 5 +-- clutter/cally/cally-text.c | 4 +-- clutter/cally/cally-texture.c | 5 +-- 8 files changed, 109 insertions(+), 46 deletions(-) diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c index 379c9b995..41bd368a1 100644 --- a/clutter/cally/cally-actor.c +++ b/clutter/cally/cally-actor.c @@ -29,7 +29,7 @@ * @see_also: #ClutterActor * * #CallyActor implements the required ATK interfaces of #ClutterActor - * exposing the common elements on each ClutterActor (position, extents, etc). + * exposing the common elements on each actor (position, extents, etc). */ /* @@ -114,7 +114,7 @@ typedef struct _CallyActorActionInfo CallyActorActionInfo; -/** +/*< private > * CallyActorActionInfo: * @name: name of the action * @description: description of the action @@ -238,8 +238,17 @@ struct _CallyActorPrivate GList *children; }; - -AtkObject* +/** + * cally_actor_new: + * @actor: a #ClutterActor + * + * Creates a new #CallyActor for the given @actor + * + * Return value: the newly created #CallyActor + * + * Since: 1.4 + */ +AtkObject * cally_actor_new (ClutterActor *actor) { gpointer object; @@ -889,7 +898,7 @@ _is_actor_on_screen (ClutterActor *actor) return TRUE; } -/** +/* * * This gets the top level origin, it is, the position of the stage in * the global screen. You can see it as the absolute display position @@ -898,7 +907,7 @@ _is_actor_on_screen (ClutterActor *actor) * FIXME: only the case with x11 is implemented, other backends are * required * - **/ + */ static void _get_top_level_origin (ClutterActor *actor, gint *x, @@ -1116,14 +1125,14 @@ cally_actor_action_get_keybinding (AtkAction *action, /* Misc functions */ -/** +/* * Checks if the parent actor, and his parent, etc is all visible * Used to check the showing property * * FIXME: the same functionality is implemented on clutter since version 0.8.4 * by clutter_actor_get_paint_visibility, so we should change this function * if a clutter version update is made - **/ + */ static gboolean _cally_actor_all_parents_visible (ClutterActor *actor) { @@ -1352,23 +1361,24 @@ _cally_actor_release_action (CallyActor *cally_actor) /** * cally_actor_add_action: + * @cally_actor: a #CallyActor * @action_name: the action name * @action_description: the action description * @action_keybinding: the action keybinding * @action_func: the callback of the action, to be executed with do_action * - * Adds a new action to be accessed with the AtkAction interface. + * Adds a new action to be accessed with the #AtkAction interface. * * Return value: added action id, or 0 if failure * - * Since: 1.2 + * Since: 1.4 */ guint -cally_actor_add_action (CallyActor *cally_actor, - const gchar *action_name, - const gchar *action_description, - const gchar *action_keybinding, - CallyActionFunc action_func) +cally_actor_add_action (CallyActor *cally_actor, + const gchar *action_name, + const gchar *action_description, + const gchar *action_keybinding, + CallyActionFunc action_func) { CallyActorActionInfo *info = NULL; CallyActorPrivate *priv = NULL; @@ -1404,17 +1414,18 @@ cally_actor_add_action (CallyActor *cally_actor, /** * cally_actor_remove_action: + * @cally_actor: a #CallyActor * @action_id: the action id * - * Removes a action, using the @action_id returned by cally_actor_add_action + * Removes a action, using the @action_id returned by cally_actor_add_action() * - * Return value: TRUE if the operation was succesful, FALSE otherwise + * Return value: %TRUE if the operation was succesful, %FALSE otherwise * - * Since: 1.2 + * Since: 1.4 */ gboolean cally_actor_remove_action (CallyActor *cally_actor, - gint action_id) + gint action_id) { GList *list_node = NULL; CallyActorPrivate *priv = NULL; @@ -1435,18 +1446,19 @@ cally_actor_remove_action (CallyActor *cally_actor, } /** - * cally_actor_remove_action: - * @action_name: the name of the action + * cally_actor_remove_action_by_name: + * @cally_actor: a #CallyActor + * @action_name: the name of the action to remove * - * Removes a action, using the @action_name used when the action was added - * with cally_actor_add_action + * Removes an action, using the @action_name used when the action was added + * with cally_actor_add_action() * - * Return value: TRUE if the operation was succesful, FALSE otherwise + * Return value: %TRUE if the operation was succesful, %FALSE otherwise * - * Since: 1.2 + * Since: 1.4 */ gboolean -cally_actor_remove_action_by_name (CallyActor *cally_actor, +cally_actor_remove_action_by_name (CallyActor *cally_actor, const gchar *action_name) { GList *node = NULL; diff --git a/clutter/cally/cally-clone.c b/clutter/cally/cally-clone.c index 0bde12053..9ddf6f958 100644 --- a/clutter/cally/cally-clone.c +++ b/clutter/cally/cally-clone.c @@ -21,16 +21,53 @@ */ /** - * SECTION:callyclutterclone + * SECTION:cally-clone + * @Title: CallyClone * @short_description: Implementation of the ATK interfaces for a #ClutterClone * @see_also: #ClutterClone * - * #CallyClutterClone implements the required ATK interfaces of #ClutterClone + * #CallyClone implements the required ATK interfaces of #ClutterClone * * In particular it sets a proper role for the clone, as just a image, * as it is the sanest and simplest approach. + */ + +/* Design rationale for CallyClone: * - * Check http://lists.o-hand.com/clutter/3797.html for more information + * In the old times, it was just ClutterCloneTexture. So, from a a11y POV + * CallyCloneTexture was just another image, like ClutterTexture, and if + * it was a clone was irrevelant. So on cally-0.8, CallyCloneTexture + * expose a object with role ATK_ROLE_IMAGE. But now, ClutterClone is more + * general. You can clone any object, including groups, and made things + * like have one text entry, and a clone with different properties in the + * same window, updated both at once. + * + * The question is if the idea is have a ClutterClone as a "first-class" + * citizen inside the stage hierarchy (full clone), or it is just supposed + * to be a mirror image of the original object. + * + * In the case of the a11y POV this would mean that if the text changes on + * the source, the clone should emit as well the text-changing signals. + * + * As ClutterClone smartly just paint the same object with different + * parameters, this would mean that it should be the cally object the one + * that should replicate the source clutter hierarchy to do that, + * something that just sound crazy. + * + * Taking into account that: + * + * - ClutterClone doesn't re-emit mirrored signals from the source + * I think that likely the answer would be "yes, it is just a + * mirrored image, not a real full clone". + * + * - You can't interact directly with the clone (ie: focus, and so on). + * Its basic usage (right now) is clone textures. + * + * Any other solution could be overwhelming. + * + * I think that the final solution would be that ClutterClone from the + * a11y POV should still be managed as a image (with the proper properties, + * position, size, etc.). */ #include "cally-clone.h" diff --git a/clutter/cally/cally-group.c b/clutter/cally/cally-group.c index ddcd9f81d..d83c552e9 100644 --- a/clutter/cally/cally-group.c +++ b/clutter/cally/cally-group.c @@ -24,14 +24,17 @@ */ /** - * SECTION:callycluttergroup + * SECTION:cally-group + * @Title: CallyGroup * @short_description: Implementation of the ATK interfaces for a #ClutterGroup * @see_also: #ClutterGroup * * #CallyClutterGroup implements the required ATK interfaces of #ClutterGroup * In particular it exposes: + * * - * Each of the Clutter actors contained in the Clutter Group. + * Each of the Clutter actors contained in the + * Group. * */ @@ -65,7 +68,17 @@ cally_group_init (CallyGroup *group) /* nothing to do yet */ } -AtkObject* +/** + * cally_group_new: + * @actor: a #ClutterGroup + * + * Creates a #CallyGroup for @actor + * + * Return value: the newly created #CallyGroup + * + * Since: 1.4 + */ +AtkObject * cally_group_new (ClutterActor *actor) { GObject *object = NULL; diff --git a/clutter/cally/cally-rectangle.c b/clutter/cally/cally-rectangle.c index 934beb996..aff7f31f3 100644 --- a/clutter/cally/cally-rectangle.c +++ b/clutter/cally/cally-rectangle.c @@ -21,11 +21,11 @@ */ /** - * SECTION:callyclutterrectangle + * SECTION:cally-rectangle * @short_description: Implementation of the ATK interfaces for a #ClutterRectangle * @see_also: #ClutterRectangle * - * #CallyClutterRectangle implements the required ATK interfaces of #ClutterRectangle + * #CallyRectangle implements the required ATK interfaces of #ClutterRectangle * * In particular it sets a proper role for the rectangle. */ diff --git a/clutter/cally/cally-root.c b/clutter/cally/cally-root.c index b7897534a..f919c8531 100644 --- a/clutter/cally/cally-root.c +++ b/clutter/cally/cally-root.c @@ -21,19 +21,18 @@ */ /** - * SECTION:callyroot + * SECTION:cally-root * @short_description: Root object for the CALLY toolkit * @see_also: #ClutterStage * * #CallyRoot is the root object of the accessibility tree-like * hierarchy, exposing the application level. * - * Somewhat equivalent to GailTopLevel. We consider that this class - * expose the a11y information of the ClutterStageManager, as the + * Somewhat equivalent to #GailTopLevel. We consider that this class + * expose the a11y information of the #ClutterStageManager, as the * children of this object are the different ClutterStage managed (so - * the GObject used in the atk_object_initialize is the - * ClutterStageManager). - * + * the #GObject used in the atk_object_initialize() is the + * #ClutterStageManager). */ #include diff --git a/clutter/cally/cally-stage.c b/clutter/cally/cally-stage.c index 57f037be4..720b881a7 100644 --- a/clutter/cally/cally-stage.c +++ b/clutter/cally/cally-stage.c @@ -21,11 +21,12 @@ */ /** - * SECTION:callystage + * SECTION:cally-stage + * @Title: CallyStage * @short_description: Implementation of the ATK interfaces for a #ClutterStage * @see_also: #ClutterStage * - * #CallyStage implements the required ATK interfaces of #ClutterStage + * #CallyStage implements the required ATK interfaces for #ClutterStage * */ diff --git a/clutter/cally/cally-text.c b/clutter/cally/cally-text.c index 3ca103c31..008613a7e 100644 --- a/clutter/cally/cally-text.c +++ b/clutter/cally/cally-text.c @@ -29,13 +29,13 @@ * @short_description: Implementation of the ATK interfaces for a #ClutterText * @see_also: #ClutterText * - * #CallyClutterText implements the required ATK interfaces of + * #CallyText implements the required ATK interfaces of * #ClutterText, #AtkText and #AtkEditableText * * */ -/** +/* * IMPLEMENTATION NOTES: * * * AtkText: There are still some methods not implemented yet: diff --git a/clutter/cally/cally-texture.c b/clutter/cally/cally-texture.c index 13c3a6095..df0a67abf 100644 --- a/clutter/cally/cally-texture.c +++ b/clutter/cally/cally-texture.c @@ -21,11 +21,12 @@ */ /** - * SECTION:callycluttertexture + * SECTION:cally-texture + * @Title: CallyTexture * @short_description: Implementation of the ATK interfaces for a #ClutterTexture * @see_also: #ClutterTexture * - * #CallyClutterTexture implements the required ATK interfaces of #ClutterTexture + * #CallyTexture implements the required ATK interfaces of #ClutterTexture * * In particular it sets a proper role for the texture. */ From d45499f88b3b3fb4b7f5e95434677ad6710776ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Wed, 7 Jul 2010 14:05:27 +0200 Subject: [PATCH 11/16] cally: Check HAVE_CONFIG_H on cally-util.c --- clutter/cally/cally-util.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/clutter/cally/cally-util.c b/clutter/cally/cally-util.c index a0890b924..8b8300909 100644 --- a/clutter/cally/cally-util.c +++ b/clutter/cally/cally-util.c @@ -23,7 +23,24 @@ * Boston, MA 02111-1307, USA. */ +/** + * SECTION:cally-util + * @Title: CallyUtil + * @short_description: #AtkUtil implementation + * @see_also: #ClutterActor + * + * #CallyUtil implements #AtkUtil abstract methods. Although it + * includes the name "Util" it is in fact one of the most important + * interfaces to be implemented in any ATK toolkit implementation. + + * For instance, it defines atk_get_root(), the method that returns + * the root object in the hierarchy. Without it, you don't have + * available any accessible object. + */ + +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include From ffd1f125604a2a25015804bcf2b8ebb6503fdd77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Tue, 6 Jul 2010 13:36:48 +0200 Subject: [PATCH 12/16] cally: Use proper backend information on CallyActor It uses HAVE_CLUTTER_GLX to check the current backend in use for some accessibility related methods. Fixes CB#2071 --- clutter/cally/cally-actor.c | 4 ++-- clutter/cally/cally-util.c | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c index 41bd368a1..a95fe9d81 100644 --- a/clutter/cally/cally-actor.c +++ b/clutter/cally/cally-actor.c @@ -103,7 +103,7 @@ #include -#ifdef HAVE_CLUTTER_X11 +#ifdef HAVE_CLUTTER_GLX #include #endif @@ -917,7 +917,7 @@ _get_top_level_origin (ClutterActor *actor, *x = 0; *y = 0; -#ifdef HAVE_CLUTTER_X11 +#ifdef HAVE_CLUTTER_GLX ClutterActor *stage = NULL; Display *display = NULL; Window root_window; diff --git a/clutter/cally/cally-util.c b/clutter/cally/cally-util.c index 8b8300909..40396fdea 100644 --- a/clutter/cally/cally-util.c +++ b/clutter/cally/cally-util.c @@ -50,10 +50,6 @@ #include "cally-root.h" #include "cally-stage.h" -#ifdef HAVE_CLUTTER_X11 -#include -#endif - static void cally_util_class_init (CallyUtilClass *klass); static void cally_util_init (CallyUtil *cally_util); From 137790bec9d4c29a4e5504ea49623884e90e3cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Tue, 6 Jul 2010 13:25:44 +0200 Subject: [PATCH 13/16] cally: Refactoring "window:create" and "window:destroy" emission code Previously "window:create" and "window:destroy" were emitted on CallyUtil. Although it works, and CallyUtil already have callbacks to stage_added/removed signals, I think that it is more tidy/clear to do that on CallyRoot: * CallyRoot already has code to manage ClutterStage addition/removal * In fact, we can see CallyRoot as the object exposing the a11y information from ClutterStageManager, so it fits better here. * CallyUtil callbacks these signals are related to key event listeners (key snooper simulation). One of the main CallyUtil responsabilities is managing event (connecting, emitting), so I would prefer to not start to add/mix more functionalities here. Ideally it would be better to emit all CallyStage methods from CallyStage, but it is clear that "create" and "destroy" are more easy to emit from a external object --- clutter/cally/cally-root.c | 2 ++ clutter/cally/cally-util.c | 10 ---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/clutter/cally/cally-root.c b/clutter/cally/cally-root.c index f919c8531..aaad2f86b 100644 --- a/clutter/cally/cally-root.c +++ b/clutter/cally/cally-root.c @@ -248,6 +248,7 @@ cally_util_stage_added_cb (ClutterStageManager *stage_manager, index = g_slist_index (root->priv->stage_list, cally_stage); g_signal_emit_by_name (root, "children_changed::add", index, cally_stage, NULL); + g_signal_emit_by_name (cally_stage, "create", 0); } static void @@ -269,4 +270,5 @@ cally_util_stage_removed_cb (ClutterStageManager *stage_manager, index = g_slist_index (root->priv->stage_list, cally_stage); g_signal_emit_by_name (root, "children_changed::remove", index, cally_stage, NULL); + g_signal_emit_by_name (cally_stage, "destroy", 0); } diff --git a/clutter/cally/cally-util.c b/clutter/cally/cally-util.c index 40396fdea..fd0b43a2a 100644 --- a/clutter/cally/cally-util.c +++ b/clutter/cally/cally-util.c @@ -535,13 +535,8 @@ cally_util_stage_added_cb (ClutterStageManager *stage_manager, gpointer data) { GCallback cally_key_snooper_cb = G_CALLBACK (data); - AtkObject *cally_stage = NULL; g_signal_connect (G_OBJECT (stage), "captured-event", cally_key_snooper_cb, NULL); - - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - if (cally_stage != NULL) - g_signal_emit_by_name (G_OBJECT(cally_stage), "create", 0); } static void @@ -551,13 +546,8 @@ cally_util_stage_removed_cb (ClutterStageManager *stage_manager, { GCallback cally_key_snooper_cb = G_CALLBACK (data); gint num = 0; - AtkObject *cally_stage = NULL; num = g_signal_handlers_disconnect_by_func (stage, cally_key_snooper_cb, NULL); - - cally_stage = clutter_actor_get_accessible (CLUTTER_ACTOR (stage)); - if (cally_stage != NULL) - g_signal_emit_by_name (G_OBJECT(cally_stage), "destroy", 0); } static void From c931e11e3df98119f1d2c64abc64083453ad0ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Tue, 6 Jul 2010 13:28:38 +0200 Subject: [PATCH 14/16] cally: Cleaning CallyText * Removing superfluous g_return_if_fail * Removing unused ClutterText::text-changed callback --- clutter/cally/cally-text.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/clutter/cally/cally-text.c b/clutter/cally/cally-text.c index 008613a7e..066c5460e 100644 --- a/clutter/cally/cally-text.c +++ b/clutter/cally/cally-text.c @@ -136,8 +136,6 @@ static AtkAttributeSet* cally_text_get_run_attributes (AtkText *text, static void _cally_text_get_selection_bounds (ClutterText *clutter_text, gint *start_offset, gint *end_offset); -static void _cally_text_text_changed_cb (ClutterText *clutter_text, - gpointer data); static void _cally_text_insert_text_cb (ClutterText *clutter_text, gchar *new_text, gint new_text_length, @@ -306,9 +304,6 @@ cally_text_real_initialize(AtkObject *obj, cally_text->priv->cursor_position = clutter_text_get_cursor_position (clutter_text); cally_text->priv->selection_bound = clutter_text_get_selection_bound (clutter_text); - g_signal_connect (clutter_text, "text-changed", - G_CALLBACK (_cally_text_text_changed_cb), - cally_text); g_signal_connect (clutter_text, "insert-text", G_CALLBACK (_cally_text_insert_text_cb), cally_text); @@ -401,8 +396,6 @@ cally_text_get_text (AtkText *text, { ClutterActor *actor = NULL; - g_return_val_if_fail (CALLY_IS_TEXT (text), NULL); - actor = CALLY_GET_CLUTTER_ACTOR (text); if (actor == NULL) /* Object is defunct */ return NULL; @@ -763,17 +756,6 @@ _cally_text_get_selection_bounds (ClutterText *clutter_text, } } -static void -_cally_text_text_changed_cb (ClutterText *clutter_text, - gpointer data) -{ - CallyText *cally_text = NULL; - - g_return_if_fail (CALLY_IS_TEXT (data)); - - cally_text = CALLY_TEXT (data); -} - static void _cally_text_delete_text_cb (ClutterText *clutter_text, gint start_pos, From a2f8ce175fed304b8e48304ff82703af58022bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Pi=C3=B1eiro?= Date: Tue, 6 Jul 2010 16:51:24 +0200 Subject: [PATCH 15/16] cally: Improving cally doc * Add documentation for all undocumented symbols * Add an overview section --- clutter/cally/cally-actor.c | 2 +- clutter/cally/cally-actor.h | 8 +-- clutter/cally/cally-clone.c | 11 ++++ clutter/cally/cally-factory.h | 26 ++++++++ clutter/cally/cally-rectangle.c | 11 ++++ clutter/cally/cally-root.c | 11 +++- clutter/cally/cally-stage.c | 65 ++++++++++++++++++++ clutter/cally/cally-text.c | 11 ++++ clutter/cally/cally-texture.c | 11 ++++ clutter/cally/cally.c | 11 +++- doc/reference/cally/Makefile.am | 6 +- doc/reference/cally/cally-docs.xml.in | 7 ++- doc/reference/cally/cally-overview.xml | 74 +++++++++++++++++++++++ doc/reference/clutter/running-clutter.xml | 4 ++ 14 files changed, 248 insertions(+), 10 deletions(-) create mode 100644 doc/reference/cally/cally-overview.xml diff --git a/clutter/cally/cally-actor.c b/clutter/cally/cally-actor.c index a95fe9d81..303cf374c 100644 --- a/clutter/cally/cally-actor.c +++ b/clutter/cally/cally-actor.c @@ -244,7 +244,7 @@ struct _CallyActorPrivate * * Creates a new #CallyActor for the given @actor * - * Return value: the newly created #CallyActor + * Return value: the newly created #AtkObject * * Since: 1.4 */ diff --git a/clutter/cally/cally-actor.h b/clutter/cally/cally-actor.h index 2aaef49c5..c870ac304 100644 --- a/clutter/cally/cally-actor.h +++ b/clutter/cally/cally-actor.h @@ -74,10 +74,10 @@ struct _CallyActor /** * CallyActorClass: - * @notify_clutter: FIXME - * @focus_clutter: FIXME - * @add_actor: FIXME - * @remove_actor: FIXME + * @notify_clutter: Signal handler for notify signal on Clutter actor + * @focus_clutter: Signal handler for key-focus-in and key-focus-out signal on Clutter actor + * @add_actor: Signal handler for actor-added signal on ClutterContainer interface + * @remove_actor: Signal handler for actor-added signal on ClutterContainer interface * * The CallyActorClass structure contains only * private data diff --git a/clutter/cally/cally-clone.c b/clutter/cally/cally-clone.c index 9ddf6f958..4c59d0820 100644 --- a/clutter/cally/cally-clone.c +++ b/clutter/cally/cally-clone.c @@ -102,6 +102,17 @@ cally_clone_init (CallyClone *clone) /* nothing to do yet */ } +/** + * cally_clone_new: + * @actor: a #ClutterActor + * + * Creates a new #CallyClone for the given @actor. @actor must be a + * #ClutterClone. + * + * Return value: the newly created #AtkObject + * + * Since: 1.4 + */ AtkObject* cally_clone_new (ClutterActor *actor) { diff --git a/clutter/cally/cally-factory.h b/clutter/cally/cally-factory.h index 37e0219c2..432844fb6 100644 --- a/clutter/cally/cally-factory.h +++ b/clutter/cally/cally-factory.h @@ -29,6 +29,22 @@ #include #include +/** + * CALLY_ACCESSIBLE_FACTORY: + * @type: GType of the accessible which is created by the factory + * @type_as_function: prefix of the accessible object methods + * @opt_create_accessible: method to instantiate the accessibility object + * + * Defines a new #AtkObjectFactory factory to create accessible + * objects of a specific GType. It defines the factory GType and also + * overrides the proper #AtkObjectFactory methods. + * + * It assumes that the accessibility object provides a + * @opt_create_accessible method in order to create the accessibility + * object. It returns a @type GType object. + * + * Since: 1.4 + */ #define CALLY_ACCESSIBLE_FACTORY(type, type_as_function, opt_create_accessible) \ \ static GType \ @@ -83,6 +99,16 @@ type_as_function ## _factory_get_type (void) \ return t; \ } +/** + * CALLY_ACTOR_SET_FACTORY: + * @widget_type: GType of the clutter actor + * @type_as_function: prefix of the accessible object methods + * + * Sets the #AtkObjectFactory to be used in order to instantiate + * accessibility objects for the actor which GType is @widget_type. + * + * Since: 1.4 + */ #define CALLY_ACTOR_SET_FACTORY(widget_type, type_as_function) \ atk_registry_set_factory_type (atk_get_default_registry (), \ widget_type, \ diff --git a/clutter/cally/cally-rectangle.c b/clutter/cally/cally-rectangle.c index aff7f31f3..b0c10a47e 100644 --- a/clutter/cally/cally-rectangle.c +++ b/clutter/cally/cally-rectangle.c @@ -62,6 +62,17 @@ cally_rectangle_init (CallyRectangle *rectangle) /* nothing to do yet */ } +/** + * cally_rectangle_new: + * @actor: a #ClutterActor + * + * Creates a new #CallyRectangle for the given @actor. @actor must be + * a #ClutterRectangle. + * + * Return value: the newly created #AtkObject + * + * Since: 1.4 + */ AtkObject* cally_rectangle_new (ClutterActor *actor) { diff --git a/clutter/cally/cally-root.c b/clutter/cally/cally-root.c index aaad2f86b..780d946c8 100644 --- a/clutter/cally/cally-root.c +++ b/clutter/cally/cally-root.c @@ -22,7 +22,7 @@ /** * SECTION:cally-root - * @short_description: Root object for the CALLY toolkit + * @short_description: Root object for the Cally toolkit * @see_also: #ClutterStage * * #CallyRoot is the root object of the accessibility tree-like @@ -105,6 +105,15 @@ cally_root_init (CallyRoot *root) root->priv->stage_removed_id = 0; } +/** + * cally_root_new: + * + * Creates a new #CallyRoot object. + * + * Return value: the newly created #AtkObject + * + * Since: 1.4 + */ AtkObject* cally_root_new (void) { diff --git a/clutter/cally/cally-stage.c b/clutter/cally/cally-stage.c index 720b881a7..75bc4869b 100644 --- a/clutter/cally/cally-stage.c +++ b/clutter/cally/cally-stage.c @@ -28,6 +28,11 @@ * * #CallyStage implements the required ATK interfaces for #ClutterStage * + * Some implementation details: at this moment #CallyStage is used as + * the most similar Window object in this toolkit (ie: emitting window + * related signals), although the real purpose of #ClutterStage is + * being a canvas. Anyway, this is required for applications using + * just clutter, or directly #ClutterStage */ #include "cally-stage.h" @@ -88,6 +93,18 @@ cally_stage_class_init (CallyStageClass *klass) g_type_class_add_private (gobject_class, sizeof (CallyStagePrivate)); + /** + * CallyStage::activate: + * @cally_actor: the object which received the signal + * + * The ::activate signal is emitted when the stage receives the key + * focus from the underlying window system. + * + * Toolkit implementation note: it is used when anyone adds a global + * event listener to "window:activate" + * + * Since: 1.4 + */ cally_stage_signals [ACTIVATE] = g_signal_new ("activate", G_TYPE_FROM_CLASS (klass), @@ -96,6 +113,18 @@ cally_stage_class_init (CallyStageClass *klass) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + /** + * CallyStage::create: + * @cally_actor: the object which received the signal + * + * The ::create signal is emitted when the stage is created. + * + * Toolkit implementation note: it is used when anyone adds a global + * event listener to "window:create" + * + * Since: 1.4 + */ cally_stage_signals [CREATE] = g_signal_new ("create", G_TYPE_FROM_CLASS (klass), @@ -104,6 +133,19 @@ cally_stage_class_init (CallyStageClass *klass) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + /** + * CallyStage::deactivate: + * @cally_actor: the object which received the signal + * + * The ::deactivate signal is emitted when the stage loses key focus + * from the underlying window system. + * + * Toolkit implementation note: it is used when anyone adds a global + * event listener to "window:deactivate" + * + * Since: 1.4 + */ cally_stage_signals [DEACTIVATE] = g_signal_new ("deactivate", G_TYPE_FROM_CLASS (klass), @@ -112,6 +154,18 @@ cally_stage_class_init (CallyStageClass *klass) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + /** + * CallyStage::destroy: + * @cally_actor: the object which received the signal + * + * The ::destroy signal is emitted when the stage is destroyed. + * + * Toolkit implementation note: it is used when anyone adds a global + * event listener to "window:destroy" + * + * Since: 1.4 + */ cally_stage_signals [DESTROY] = g_signal_new ("destroy", G_TYPE_FROM_CLASS (klass), @@ -132,6 +186,17 @@ cally_stage_init (CallyStage *cally_stage) priv->active = FALSE; } +/** + * cally_stage_new: + * @actor: a #ClutterActor + * + * Creates a new #CallyStage for the given @actor. @actor should be a + * #ClutterStage. + * + * Return value: the newly created #AtkObject + * + * Since: 1.4 + */ AtkObject* cally_stage_new (ClutterActor *actor) { diff --git a/clutter/cally/cally-text.c b/clutter/cally/cally-text.c index 066c5460e..f7c72d9f6 100644 --- a/clutter/cally/cally-text.c +++ b/clutter/cally/cally-text.c @@ -269,6 +269,17 @@ cally_text_finalize (GObject *obj) G_OBJECT_CLASS (cally_text_parent_class)->finalize (obj); } +/** + * cally_text_new: + * @actor: a #ClutterActor + * + * Creates a new #CallyText for the given @actor. @actor must be a + * #ClutterText. + * + * Return value: the newly created #AtkObject + * + * Since: 1.4 + */ AtkObject* cally_text_new (ClutterActor *actor) { diff --git a/clutter/cally/cally-texture.c b/clutter/cally/cally-texture.c index df0a67abf..8b2508fc9 100644 --- a/clutter/cally/cally-texture.c +++ b/clutter/cally/cally-texture.c @@ -63,6 +63,17 @@ cally_texture_init (CallyTexture *texture) /* nothing to do yet */ } +/** + * cally_texture_new: + * @actor: a #ClutterActor + * + * Creates a new #CallyTexture for the given @actor. @actor must be + * a #ClutterTexture. + * + * Return value: the newly created #AtkObject + * + * Since: 1.4 + */ AtkObject* cally_texture_new (ClutterActor *actor) { diff --git a/clutter/cally/cally.c b/clutter/cally/cally.c index b2419ca62..ea016c531 100644 --- a/clutter/cally/cally.c +++ b/clutter/cally/cally.c @@ -20,6 +20,15 @@ * Boston, MA 02111-1307, USA. */ +/** + * SECTION:cally + * @Title: Cally + * @short_description: Cally initialization methods. + * + * Cally initialization methods. + * + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -54,7 +63,7 @@ CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_RECTANGLE, cally_rectangle, cally_rectangle CALLY_ACCESSIBLE_FACTORY (CALLY_TYPE_CLONE, cally_clone, cally_clone_new) /** - * cally_acccessibility_init: + * cally_accessibility_init: * * Initializes the accessibility support. * diff --git a/doc/reference/cally/Makefile.am b/doc/reference/cally/Makefile.am index ff52c2dac..775c70179 100644 --- a/doc/reference/cally/Makefile.am +++ b/doc/reference/cally/Makefile.am @@ -63,12 +63,14 @@ HTML_IMAGES= # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files= +content_files= \ + cally-overview.xml # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded # These files must be listed here *and* in content_files # e.g. expand_content_files=running.sgml -expand_content_files= +expand_content_files= \ + cally-overview.xml # CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. # Only needed if you are using gtkdoc-scangobj to dynamically query widget diff --git a/doc/reference/cally/cally-docs.xml.in b/doc/reference/cally/cally-docs.xml.in index e0a5bf3dd..82c8a2d50 100644 --- a/doc/reference/cally/cally-docs.xml.in +++ b/doc/reference/cally/cally-docs.xml.in @@ -10,8 +10,10 @@ for Clutter &version; + 2008 + 2009 2010 - Intel Corporation + Igalia S.L. @@ -37,6 +39,8 @@ + + Cally Reference @@ -44,6 +48,7 @@ Base Classes + diff --git a/doc/reference/cally/cally-overview.xml b/doc/reference/cally/cally-overview.xml new file mode 100644 index 000000000..4be86fbab --- /dev/null +++ b/doc/reference/cally/cally-overview.xml @@ -0,0 +1,74 @@ + + + + Alejandro + Piñeiro Iglesias + +
+ apinheiro@igalia.com +
+
+
+
+ + Overview + + + + Cally (Clutter Accessibility Implementation Library) is the + Clutter implementation of the ATK interfaces. You can see as the + Clutter equivalent of GAIL, which provides accessibility support + for GTK+ and other GNOME related libraries. + + This implementation expose Clutter actors to accessibility + tools like Orca. This allows not only writing accessible user + interfaces, but also allows testing and verification frameworks + based on accessibility technologies to inspect and test a Clutter + scene graph. + + This reference manual defines the different APIs defined in + Cally. Anyway take into account that the most common use of case + Cally is transparent to the user, as the different accessibility + tools are intended to use the abstract ATK interfaces, and *not + directly* Cally, so this tools can communicate with applications + using different toolkits, like GTK+, Java, Clutter, etc. + + The purpose of this reference is allow to extend Cally + functionality in any Clutter-based widget toolkit. Clutter is more + low-level that other toolkits like GTK+, and some toolkits have + started to appear based on Clutter: MX, Shell Toolkit, Candies, + Glitter, etc. This means that it is really likely that these + libraries will require extra accessibility support. + + GAIL used a different approach, being a almost-pure-opaque + implementation of the ATK interfaces. So you can't extend it + directly. You need to use GObject and ATK mechanisms, like + run-time anonymous inheritance, to extend it. Although valid to + some custom cases, it showed to be really problematic and hacky in + wider approaches, like HAIL(Hildon Accessibility Implementation + Library). As explained, Clutter is more likely to be extended, so + these issues would arise sooner. + + Part of the accessibility support is implemented on Clutter, + like the initialization code, and the method to obtain the + accessibility object for each Clutter object. In the same way, to + make it easier, and to allow access to Clutter object private + data, it would be really likely that the accessibility support + would be implemented directly on some Clutter objects + + Check the next clutter methods for more information: + + + clutter_actor_get_accessible() + Virtual method to obtain the accessibility object of a + clutter actor + + + clutter_get_accessibility_enabled() + Method to check if accessibility is enabled. + + + + + +
diff --git a/doc/reference/clutter/running-clutter.xml b/doc/reference/clutter/running-clutter.xml index 64e97ec1a..7e0a64662 100644 --- a/doc/reference/clutter/running-clutter.xml +++ b/doc/reference/clutter/running-clutter.xml @@ -137,6 +137,10 @@ Unsets FLAGS from the COGL debugging flags. + + --clutter-enable-accessibility + Enables accessibility support. + The X11 backends also have the following command line From a3c69dc27c5fc492184a2b6948f59ef27b60f10c Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 7 Jul 2010 15:57:43 +0100 Subject: [PATCH 16/16] cally: Add introspection generation Toolkits and applications not written in C might still need access to the Cally API to write accessibility extensions based on it for their own native elements. --- clutter/Makefile.am | 30 +++++++++++++++++++++++++++--- clutter/cally/Makefile.am | 6 ++---- clutter/cogl/cogl/Makefile.am | 2 +- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/clutter/Makefile.am b/clutter/Makefile.am index cc204b2ac..f60adfb44 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -322,7 +322,7 @@ json_gir_pkg= # If we are building it, ClutterJson gets the same handling as described # for Cogl above -ClutterJson-@CLUTTER_API_VERSION@.gir: Clutter-@CLUTTER_API_VERSION@.gir json/ClutterJson-@CLUTTER_API_VERSION@.gir +ClutterJson-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir json/ClutterJson-@CLUTTER_API_VERSION@.gir $(QUIET_GEN) \ shlib=`sed -n 's/.*shared-library="\([^"]*\)".*/\1/p' < Clutter-@CLUTTER_API_VERSION@.gir` ; \ sed "s/shared-library=\"[^\"]*\"/shared-library=\"$$shlib\"/"< json/ClutterJson-@CLUTTER_API_VERSION@.gir > $@ @@ -338,7 +338,7 @@ if HAVE_INTROSPECTION # subdir Makefile.am, so just extract them from cogl.h instead. The doc # comments for COGL are in the headers, so we don't need the source files. -Clutter-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libclutter-@CLUTTER_SONAME_INFIX@-@CLUTTER_API_VERSION@.la +Clutter-@CLUTTER_API_VERSION@.gir: Makefile $(INTROSPECTION_SCANNER) libclutter-@CLUTTER_SONAME_INFIX@-@CLUTTER_API_VERSION@.la $(QUIET_GEN)$(INTROSPECTION_SCANNER) -v \ --namespace Clutter --nsversion=@CLUTTER_API_VERSION@ \ $(INCLUDES) \ @@ -377,13 +377,37 @@ Clutter-@CLUTTER_API_VERSION@.typelib: $(clutter_json_gir) Cogl-@CLUTTER_API_VER # until after we've built the shared library. To create the final Cogl.gir # that we compile and install, we transfer the shared-library="" line from # Clutter.gir to Cogl.gir -Cogl-@CLUTTER_API_VERSION@.gir: Clutter-@CLUTTER_API_VERSION@.gir cogl/cogl/Cogl-@CLUTTER_API_VERSION@.gir +Cogl-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir cogl/cogl/Cogl-@CLUTTER_API_VERSION@.gir $(QUIET_GEN) \ shlib=`sed -n 's/.*shared-library="\([^"]*\)".*/\1/p' < Clutter-@CLUTTER_API_VERSION@.gir` ; \ sed "s/shared-library=\"[^\"]*\"/shared-library=\"$$shlib\"/"< cogl/cogl/Cogl-@CLUTTER_API_VERSION@.gir > $@ BUILT_GIRSOURCES += Cogl-@CLUTTER_API_VERSION@.gir +# Cally depends on Clutter because it exposes Clutter types; for this reason, +# we cannot build Cally.gir under cally/ and then do the shlib trick we do +# for Cogl and ClutterJson. +Cally-@CLUTTER_API_VERSION@.gir: Makefile $(INTROSPECTION_SCANNER) Clutter-@CLUTTER_API_VERSION@.gir + $(QUIET_GEN)$(INTROSPECTION_SCANNER) -v \ + --namespace Cally --nsversion=@CLUTTER_API_VERSION@ \ + $(INCLUDES) \ + $(AM_CPPFLAGS) \ + --c-include='cally/cally.h' \ + --include=GObject-2.0 \ + --include=Atk-1.0 \ + --include=Pango-1.0 \ + --include=Clutter-1.0 \ + --library=libclutter-@CLUTTER_SONAME_INFIX@-@CLUTTER_API_VERSION@.la \ + --libtool="$(top_builddir)/libtool" \ + --pkg gobject-2.0 \ + --pkg atk \ + --pkg clutter-1.0 \ + --output $@ \ + $(top_srcdir)/clutter/cally/*.h \ + $(top_srcdir)/clutter/cally/*.c + +BUILT_GIRSOURCES += Cally-@CLUTTER_API_VERSION@.gir + # INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to # install anything - we need to install inside our prefix. girdir = $(datadir)/gir-1.0 diff --git a/clutter/cally/Makefile.am b/clutter/cally/Makefile.am index 2abbe9bdb..e929a9477 100644 --- a/clutter/cally/Makefile.am +++ b/clutter/cally/Makefile.am @@ -73,8 +73,6 @@ libcallydir=$(includedir)/clutter-@CLUTTER_API_VERSION@/cally # unlikely in any real final clutter-based application to use only raw # CALLY. In fact, after HAIL experience, probably export GAIL # interfaces would be a good idea -libcally_HEADERS = \ - $(cally_h_sources) +libcally_HEADERS = $(cally_h_sources) -libcally_la_LIBADD = \ - $(CLUTTER_LIBS) +libcally_la_LIBADD = $(CLUTTER_LIBS) diff --git a/clutter/cogl/cogl/Makefile.am b/clutter/cogl/cogl/Makefile.am index 7af9efdb9..465391f83 100644 --- a/clutter/cogl/cogl/Makefile.am +++ b/clutter/cogl/cogl/Makefile.am @@ -221,7 +221,7 @@ coglinclude_HEADERS = $(cogl_headers) nodist_coglinclude_HEADERS = cogl-defines.h if HAVE_INTROSPECTION -Cogl-@CLUTTER_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libclutter-cogl.la +Cogl-@CLUTTER_API_VERSION@.gir: Makefile $(INTROSPECTION_SCANNER) libclutter-cogl.la $(QUIET_GEN)$(INTROSPECTION_SCANNER) -v \ --namespace Cogl --nsversion=@CLUTTER_API_VERSION@ \ $(INCLUDES) \