[at-spi2-core] Make the registry implement the accessible interface and add a socket interface for adding chilren t
- From: Mark Doffman <markdoffman src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [at-spi2-core] Make the registry implement the accessible interface and add a socket interface for adding chilren t
- Date: Sun, 24 Jan 2010 13:29:02 +0000 (UTC)
commit f8893786b2a61f8294e6cc73d3bdc2ae18264a7b
Author: Mark Doffman <mark doffman codethink co uk>
Date: Wed Jan 20 12:14:53 2010 -0800
Make the registry implement the accessible interface and add
a socket interface for adding chilren to its accessible object.
registryd/deviceeventcontroller.c | 2 +-
registryd/paths.h | 43 +--
registryd/registry.c | 821 +++++++++++++++++++++++++++++++------
registryd/registry.h | 2 +-
4 files changed, 708 insertions(+), 160 deletions(-)
---
diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c
index d094f2c..30d8774 100644
--- a/registryd/deviceeventcontroller.c
+++ b/registryd/deviceeventcontroller.c
@@ -398,7 +398,7 @@ static void emit(SpiDEController *controller, const char *interface, const char
DBusMessage *signal = NULL;
DBusMessageIter iter, iter_variant;
int nil = 0;
- const char *path = SPI_DBUS_PATH_DESKTOP;
+ const char *path = SPI_DBUS_PATH_ROOT;
signal = dbus_message_new_signal (path, interface, name);
diff --git a/registryd/paths.h b/registryd/paths.h
index 0d1ed40..49758e5 100644
--- a/registryd/paths.h
+++ b/registryd/paths.h
@@ -24,35 +24,26 @@
#ifndef SPI_PATHS_H_
#define SPI_PATHS_H_
-#define SPI_DBUS_NAME_REGISTRY "org.freedesktop.atspi.Registry"
-#define SPI_DBUS_PATH_REGISTRY "/org/freedesktop/atspi/registry"
-#define SPI_DBUS_INTERFACE_REGISTRY "org.freedesktop.atspi.Registry"
+#define SPI_DBUS_NAME_PREFIX "org.freedesktop.atspi."
+#define SPI_DBUS_PATH_PREFIX "/org/freedesktop/atspi/"
+#define SPI_DBUS_INTERFACE_PREFIX "org.freedesktop.atspi."
-#define SPI_DBUS_PATH_DESKTOP "/org/freedesktop/atspi/accessible/desktop"
-#define SPI_DBUS_INTERFACE_DESKTOP "org.freedesktop.atspi.Desktop"
+#define SPI_DBUS_PATH_NULL SPI_DBUS_PATH_PREFIX "null"
+#define SPI_DBUS_PATH_ROOT SPI_DBUS_PATH_PREFIX "root"
-#define SPI_DBUS_PATH_DEC "/org/freedesktop/atspi/registry/deviceeventcontroller"
-#define SPI_DBUS_PATH_NULL "/org/freedesktop/accessible/null"
+#define SPI_DBUS_NAME_REGISTRY SPI_DBUS_NAME_PREFIX "org.freedesktop.atspi.Registry"
+#define SPI_DBUS_PATH_REGISTRY SPI_DBUS_PATH_PREFIX "registry"
+#define SPI_DBUS_INTERFACE_REGISTRY SPI_DBUS_INTERFACE_PREFIX "Registry"
-#define SPI_DBUS_INTERFACE_DEC "org.freedesktop.atspi.DeviceEventController"
-#define SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER "org.freedesktop.atspi.DeviceEventListener"
+#define SPI_DBUS_PATH_DEC SPI_DBUS_PATH_PREFIX "registry/deviceeventcontroller"
+#define SPI_DBUS_INTERFACE_DEC SPI_DBUS_INTERFACE_PREFIX "DeviceEventController"
+#define SPI_DBUS_INTERFACE_DEVICE_EVENT_LISTENER SPI_DBUS_INTERFACE_PREFIX "DeviceEventListener"
-#define SPI_DBUS_INTERFACE_TREE "org.freedesktop.atspi.Tree"
-#define SPI_DBUS_INTERFACE_ACCESSIBLE "org.freedesktop.atspi.Accessible"
-#define SPI_DBUS_INTERFACE_ACTION "org.freedesktop.atspi.Action"
-#define SPI_DBUS_INTERFACE_APPLICATION "org.freedesktop.atspi.Application"
-#define SPI_DBUS_INTERFACE_COLLECTION "org.freedesktop.atspi.Collection"
-#define SPI_DBUS_INTERFACE_COMPONENT "org.freedesktop.atspi.Component"
-#define SPI_DBUS_INTERFACE_DOCUMENT "org.freedesktop.atspi.Document"
-#define SPI_DBUS_INTERFACE_EDITABLE_TEXT "org.freedesktop.atspi.EditableText"
-#define SPI_DBUS_INTERFACE_EVENT_KEYBOARD "org.freedesktop.atspi.Event.Keyboard"
-#define SPI_DBUS_INTERFACE_EVENT_MOUSE "org.freedesktop.atspi.Event.Mouse"
-#define SPI_DBUS_INTERFACE_HYPERLINK "org.freedesktop.atspi.Hyperlink"
-#define SPI_DBUS_INTERFACE_HYPERTEXT "org.freedesktop.atspi.Hypertext"
-#define SPI_DBUS_INTERFACE_IMAGE "org.freedesktop.atspi.Image"
-#define SPI_DBUS_INTERFACE_SELECTION "org.freedesktop.atspi.Selection"
-#define SPI_DBUS_INTERFACE_TABLE "org.freedesktop.atspi.Table"
-#define SPI_DBUS_INTERFACE_TEXT "org.freedesktop.atspi.Text"
-#define SPI_DBUS_INTERFACE_VALUE "org.freedesktop.atspi.Value"
+#define SPI_DBUS_INTERFACE_ACCESSIBLE SPI_DBUS_INTERFACE_PREFIX "Accessible"
+#define SPI_DBUS_INTERFACE_COMPONENT SPI_DBUS_INTERFACE_PREFIX "Component"
+#define SPI_DBUS_INTERFACE_EVENT_KEYBOARD SPI_DBUS_INTERFACE_PREFIX "Keyboard"
+#define SPI_DBUS_INTERFACE_EVENT_MOUSE SPI_DBUS_INTERFACE_PREFIX "Event.Mouse"
+#define SPI_DBUS_INTERFACE_EVENT_OBJECT SPI_DBUS_INTERFACE_PREFIX "Event.Object"
+#define SPI_DBUS_INTERFACE_SOCKET SPI_DBUS_INTERFACE_PREFIX "Socket"
#endif /* SPI_PATHS_H_ */
diff --git a/registryd/registry.c b/registryd/registry.c
index f720920..92406e0 100644
--- a/registryd/registry.c
+++ b/registryd/registry.c
@@ -2,7 +2,7 @@
* AT-SPI - Assistive Technology Service Provider Interface
* (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
*
- * Copyright 2008, Codethink Ltd.
+ * Copyright 2008, 2010 Codethink Ltd.
* Copyright 2001, 2002 Sun Microsystems Inc.,
* Copyright 2001, 2002 Ximian, Inc.
*
@@ -29,11 +29,45 @@
#include "paths.h"
#include "registry.h"
-enum
+static gboolean
+children_added_listener (DBusConnection * bus,
+ gint index,
+ const gchar * name,
+ const gchar * path);
+
+static gboolean
+children_removed_listener (DBusConnection * bus,
+ gint index,
+ const gchar * name,
+ const gchar * path);
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct _SpiReference
{
- REGISTRY_APPLICATION_REMOVE = 0,
- REGISTRY_APPLICATION_ADD = 1
-};
+ gchar *name;
+ gchar *path;
+} SpiReference;
+
+static SpiReference *
+spi_reference_new (const gchar *name, const gchar *path)
+{
+ SpiReference *ref;
+
+ ref = g_new0 (SpiReference, 1);
+ ref->name = g_strdup (name);
+ ref->path = g_strdup (path);
+
+ return ref;
+}
+
+static void
+spi_reference_free (SpiReference *ref)
+{
+ g_free (ref->name);
+ g_free (ref->path);
+ g_free (ref);
+}
/*---------------------------------------------------------------------------*/
@@ -50,209 +84,617 @@ spi_registry_class_init (SpiRegistryClass *klass)
static void
spi_registry_init (SpiRegistry *registry)
{
- registry->apps = g_sequence_new (g_free);
+ registry->apps = g_ptr_array_new_with_free_func ((GDestroyNotify) spi_reference_free);
}
/*---------------------------------------------------------------------------*/
-static void emit_update_applications(SpiRegistry *reg, guint sigtype, const char *app)
+static dbus_bool_t
+return_v_string (DBusMessageIter * iter, const gchar * str)
{
- DBusMessage *msg = NULL;
- DBusError error;
-
- dbus_error_init (&error);
+ DBusMessageIter variant;
- if ((msg = dbus_message_new_signal (SPI_DBUS_PATH_REGISTRY,
- SPI_DBUS_INTERFACE_REGISTRY,
- "UpdateApplications"))) {
- dbus_message_append_args(msg, DBUS_TYPE_INT32, &sigtype,
- DBUS_TYPE_STRING, &app, DBUS_TYPE_INVALID);
-
- dbus_connection_send (reg->bus, msg, NULL);
+ dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "s",
+ &variant);
+ dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &str);
+ dbus_message_iter_close_container (iter, &variant);
+}
- dbus_message_unref (msg);
- }
+static void
+append_reference (DBusMessageIter * iter, const char * name, const char * path)
+{
+ DBusMessageIter iter_struct;
- dbus_error_free (&error);
+ dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL,
+ &iter_struct);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &name);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_OBJECT_PATH, &path);
+ dbus_message_iter_close_container (iter, &iter_struct);
}
-
/*---------------------------------------------------------------------------*/
-static gint
-data_str_cmp (gpointer a, gpointer b, gpointer data)
+static gboolean
+compare_reference (SpiReference *one, SpiReference *two)
{
- return g_strcmp0(a, b);
+ if (g_strcmp0 (one->name, two->name) == 0 &&
+ g_strcmp0 (one->path, two->path) == 0)
+ return TRUE;
+ else
+ return FALSE;
}
static gboolean
-seq_add_string (GSequence *seq, gchar *str)
+find_index_of_reference (GPtrArray *arr, const gchar *name, const gchar * path, guint *index)
{
- GSequenceIter *iter;
- gchar *item;
- gboolean res = FALSE;
+ SpiReference *ref;
+ gboolean found = FALSE;
+ guint i = 0;
- iter = g_sequence_search (seq, str, (GCompareDataFunc) data_str_cmp, NULL);
- iter = g_sequence_iter_prev (iter);
+ ref = spi_reference_new (name, path);
- if (!g_sequence_iter_is_end (iter))
+ for (i = 0; i < arr->len && found == FALSE; i++)
{
- item = g_sequence_get (iter);
- if (g_strcmp0 (item, str))
+ if (compare_reference (ref, g_ptr_array_index (arr, i)));
{
- g_sequence_insert_sorted (seq, g_strdup(str), (GCompareDataFunc) data_str_cmp, NULL);
- res = TRUE;
+ found = TRUE;
}
}
- else
- {
- g_sequence_insert_sorted (seq, g_strdup(str), (GCompareDataFunc) data_str_cmp, NULL);
- res = TRUE;
- }
- return res;
+ spi_reference_free (ref);
+
+ *index = i;
+ return found;
}
-static gboolean
-seq_remove_string (GSequence *seq, gchar *str)
+static void
+add_application (SpiRegistry *reg, DBusConnection *bus, const gchar *name, const gchar *path)
+{
+ g_ptr_array_add (reg->apps, spi_reference_new (name, path));
+ children_added_listener (bus, reg->apps->len - 1, name, path);
+}
+
+static void
+remove_application (SpiRegistry *reg, DBusConnection *bus, guint index)
{
- GSequenceIter *iter;
- gchar *item;
- gboolean res = FALSE;
+ const gchar *name = "";
+ g_ptr_array_remove_index (reg->apps, index);
+ /*TODO spi_remove_device_listeners (registry->de_controller, old);*/
+ children_removed_listener (bus, index, name, SPI_DBUS_PATH_NULL);
+}
- iter = g_sequence_search (seq, str, (GCompareDataFunc) data_str_cmp, NULL);
- iter = g_sequence_iter_prev (iter);
+static void
+handle_disconnection (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ char *name, *old, *new;
+ SpiRegistry *reg = SPI_REGISTRY (user_data);
- if (!g_sequence_iter_is_end (iter))
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &old,
+ DBUS_TYPE_STRING, &new,
+ DBUS_TYPE_INVALID))
{
- item = g_sequence_get (iter);
- if (!g_strcmp0 (item, str))
+ if (*old != '\0' && *new == '\0')
{
- g_sequence_remove (iter);
- res = TRUE;
+ /* Remove all children with the application name the same as the disconnected application. */
+ guint i;
+ for (i = 0; i < reg->apps->len; i++)
+ {
+ while (g_strcmp0 (old, g_ptr_array_index (reg->apps, i)))
+ {
+ const gchar *rname = "";
+ g_ptr_array_remove_index (reg->apps, i);
+ children_removed_listener (bus, i, rname, SPI_DBUS_PATH_NULL);
+ }
+ }
}
}
+}
+
+static DBusHandlerResult
+signal_filter (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ SpiRegistry *registry = SPI_REGISTRY (user_data);
+ guint res = DBUS_HANDLER_RESULT_HANDLED;
+ const char *iface = dbus_message_get_interface (message);
+ const char *member = dbus_message_get_member (message);
+
+ if (!g_strcmp0(iface, DBUS_INTERFACE_DBUS) && !g_strcmp0(member, "NameOwnerChanged"))
+ handle_disconnection (bus, message, user_data);
+ else
+ res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
return res;
}
-static void
-add_application (DBusConnection *bus, SpiRegistry *reg, gchar *app)
+/* org.at_spi.Socket interface */
+/*---------------------------------------------------------------------------*/
+
+static DBusMessage*
+impl_Embed (DBusConnection *bus, DBusMessage *message, void *user_data)
{
- if (seq_add_string (reg->apps, app))
- {
- emit_update_applications (reg, REGISTRY_APPLICATION_ADD, app);
- }
+ gchar *app_name, *obj_path;
+ SpiRegistry *reg = SPI_REGISTRY (user_data);
+
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &app_name,
+ DBUS_TYPE_STRING, &obj_path,
+ DBUS_TYPE_INVALID))
+ add_application(reg, bus, app_name, obj_path);
+ return NULL;
}
-static void
-remove_application (DBusConnection *bus, SpiRegistry *reg, gchar *app)
+static DBusMessage*
+impl_Unembed (DBusConnection *bus, DBusMessage *message, void *user_data)
{
- if (seq_remove_string (reg->apps, app))
+ gchar *app_name, *obj_path;
+ SpiRegistry *reg = SPI_REGISTRY (user_data);
+
+ if (dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &app_name,
+ DBUS_TYPE_STRING, &obj_path,
+ DBUS_TYPE_INVALID))
{
- /*TODO spi_remove_device_listeners (registry->de_controller, old);*/
- emit_update_applications (reg, REGISTRY_APPLICATION_REMOVE, app);
+ guint index;
+ if (find_index_of_reference (reg->apps, app_name, obj_path, &index))
+ remove_application(reg, bus, index);
}
+ return NULL;
}
+/* org.at_spi.Component interface */
/*---------------------------------------------------------------------------*/
-static void
-add_bus_name_cb (gpointer item, gpointer data)
+static DBusMessage *
+impl_Contains (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ dbus_bool_t retval = FALSE;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetAccessibleAtPoint (DBusConnection * bus, DBusMessage * message,
+ void *user_data)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+ append_reference (&iter,
+ dbus_bus_get_unique_name (bus),
+ SPI_DBUS_PATH_NULL);
+
+ return reply;
+}
+
+static DBusMessage *
+impl_GetExtents (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ dbus_uint32_t coord_type;
+ dbus_int32_t x = 0, y = 0, width = 1024, height = 768;
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_struct;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (message, &iter);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_STRUCT, NULL,
+ &iter_struct);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &x);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &y);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &width);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_INT32, &height);
+ dbus_message_iter_close_container (&iter, &iter_struct);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetPosition (DBusConnection * bus, DBusMessage * message,
+ void *user_data)
+{
+ DBusMessage *reply;
+ dbus_int32_t x = 0, y = 0;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32,
+ &y, DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetSize (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ /* TODO - Get the screen size */
+ DBusMessage *reply;
+ dbus_int32_t width = 1024, height = 768;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_INT32, &width,
+ DBUS_TYPE_INT32, &height, DBUS_TYPE_INVALID);
+ return reply;
+}
+
+#define LAYER_WIDGET 3;
+
+static DBusMessage *
+impl_GetLayer (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply;
+ dbus_uint32_t rv = LAYER_WIDGET;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetMDIZOrder (DBusConnection * bus, DBusMessage * message,
+ void *user_data)
+{
+ DBusMessage *reply;
+ dbus_int16_t rv = 0;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_INT16, &rv,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GrabFocus (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply;
+ dbus_bool_t retval = FALSE;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetAlpha (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ double rv = 1.0;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_DOUBLE, &rv,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+/* org.at_spi.Accessible interface */
+/*---------------------------------------------------------------------------*/
+
+static dbus_bool_t
+impl_get_Name (DBusMessageIter * iter, void *user_data)
+{
+ const gchar *name = "main";
+ return return_v_string (iter, name);
+}
+
+static dbus_bool_t
+impl_get_Description (DBusMessageIter * iter, void *user_data)
+{
+ const gchar *description = "";
+ return return_v_string (iter, description);
+}
+
+static dbus_bool_t
+impl_get_Parent (DBusMessageIter * iter, void *user_data)
+{
+ const gchar *name = "";
+ append_reference (iter,
+ name,
+ SPI_DBUS_PATH_NULL);
+ return TRUE;
+}
+
+static dbus_bool_t
+impl_get_ChildCount (DBusMessageIter * iter, void *user_data)
+{
+ SpiRegistry *reg = SPI_REGISTRY (user_data);
+ dbus_int32_t rv = reg->apps->len;
+
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_INT32, &rv);
+}
+
+static DBusMessage *
+impl_GetChildAtIndex (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
{
- DBusMessageIter *iter_array = (DBusMessageIter *) data;
+ SpiRegistry *reg = SPI_REGISTRY (user_data);
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusError error;
+ SpiReference *ref;
+ dbus_int32_t i;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args
+ (message, &error, DBUS_TYPE_INT32, &i, DBUS_TYPE_INVALID))
+ {
+ return dbus_message_new_error (message, DBUS_ERROR_FAILED, "Invalid arguments");
+ }
- dbus_message_iter_append_basic (iter_array, DBUS_TYPE_STRING, (gchar **) &item);
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+
+ ref = g_ptr_array_index (reg->apps, i);
+ append_reference (&iter, ref->name, ref->path);
+
+ return reply;
}
static DBusMessage *
-impl_GetApplications (DBusConnection *bus, DBusMessage *message, void *user_data)
+impl_GetChildren (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
{
DBusMessage *reply = NULL;
DBusMessageIter iter, iter_array;
SpiRegistry *reg = SPI_REGISTRY (user_data);
+ int i;
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &iter_array);
- g_sequence_foreach (reg->apps, add_bus_name_cb, &iter_array);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(so)", &iter_array);
+ for (i=0; i < reg->apps->len; i++)
+ {
+ SpiReference *current = g_ptr_array_index (reg->apps, i);
+ append_reference (&iter_array, current->name, current->path);
+ }
dbus_message_iter_close_container(&iter, &iter_array);
return reply;
}
-/*---------------------------------------------------------------------------*/
+static DBusMessage *
+impl_GetIndexInParent (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply;
+ dbus_uint32_t rv = 0;
-static DBusMessage*
-impl_RegisterApplication (DBusConnection *bus, DBusMessage *message, void *user_data)
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv, DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetRelationSet (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
{
- gchar *app_name;
- SpiRegistry *reg = SPI_REGISTRY (user_data);
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_array;
- if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID))
- add_application(bus, reg, app_name);
- return NULL;
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "(ua(so))", &iter_array);
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ return reply;
}
-static DBusMessage*
-impl_DeregisterApplication (DBusConnection *bus, DBusMessage *message, void *user_data)
+static DBusMessage *
+impl_GetRole (DBusConnection * bus, DBusMessage * message, void * user_data)
{
- gchar *app_name;
- SpiRegistry *reg = SPI_REGISTRY (user_data);
+ DBusMessage *reply;
+ dbus_uint32_t rv = 0;
- if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &app_name, DBUS_TYPE_INVALID))
- remove_application(bus, reg, app_name);
- return NULL;
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_UINT32, &rv, DBUS_TYPE_INVALID);
+ return reply;
}
-/*---------------------------------------------------------------------------*/
+static DBusMessage *
+impl_GetRoleName (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply;
+ const char *role_name = "unknown";
-static void
-handle_disconnection (DBusConnection *bus, DBusMessage *message, void *user_data)
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetLocalizedRoleName (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
{
- char *name, *old, *new;
- SpiRegistry *reg = SPI_REGISTRY (user_data);
+ /* TODO - Localize this */
+ DBusMessage *reply;
+ const char *role_name = "unknown";
- if (dbus_message_get_args (message, NULL,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &old,
- DBUS_TYPE_STRING, &new,
- DBUS_TYPE_INVALID))
+ reply = dbus_message_new_method_return (message);
+ dbus_message_append_args (reply, DBUS_TYPE_STRING, &role_name,
+ DBUS_TYPE_INVALID);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetState (DBusConnection * bus, DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter, iter_array;
+
+ dbus_uint32_t states[2] = {0, 0};
+ guint count;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "u", &iter_array);
+ for (count = 0; count < 2; count++)
{
- if (*old != '\0' && *new == '\0')
- {
- remove_application(bus, reg, old);
- }
+ dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_UINT32,
+ &states[count]);
}
+ dbus_message_iter_close_container (&iter, &iter_array);
+ return reply;
+}
+
+static DBusMessage *
+impl_GetAttributes (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter, array;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{ss}", &array);
+ dbus_message_iter_close_container (&iter, &array);
+
+ return reply;
+}
+
+static DBusMessage *
+impl_GetApplication (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+ append_reference (&iter,
+ dbus_bus_get_unique_name (bus),
+ SPI_DBUS_PATH_NULL);
+
+ return reply;
+}
+
+static DBusMessage *
+impl_GetInterfaces (DBusConnection * bus,
+ DBusMessage * message, void *user_data)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter, iter_array;
+
+ const char *acc = SPI_DBUS_INTERFACE_ACCESSIBLE;
+ const char *com = SPI_DBUS_INTERFACE_COMPONENT;
+
+ reply = dbus_message_new_method_return (message);
+
+ dbus_message_iter_init_append (reply, &iter);
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s",
+ &iter_array);
+ dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &acc);
+ dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &com);
+ dbus_message_iter_close_container (&iter, &iter_array);
+
+ return reply;
}
/*---------------------------------------------------------------------------*/
-static DBusHandlerResult
-signal_filter (DBusConnection *bus, DBusMessage *message, void *user_data)
+static void
+emit_Available (DBusConnection * bus)
{
- SpiRegistry *registry = SPI_REGISTRY (user_data);
- guint res = DBUS_HANDLER_RESULT_HANDLED;
- const char *iface = dbus_message_get_interface (message);
- const char *member = dbus_message_get_member (message);
+ DBusMessage *sig;
+ DBusMessageIter iter;
+
+ sig = dbus_message_new_signal(SPI_DBUS_PATH_ROOT, SPI_DBUS_INTERFACE_SOCKET, "Available");
- if (!g_strcmp0(iface, DBUS_INTERFACE_DBUS) && !g_strcmp0(member, "NameOwnerChanged"))
- handle_disconnection (bus, message, user_data);
- else
- res = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ dbus_message_iter_init_append(sig, &iter);
+ append_reference (&iter, SPI_DBUS_NAME_REGISTRY, SPI_DBUS_PATH_ROOT);
- return res;
+ dbus_connection_send(bus, sig, NULL);
+ dbus_message_unref(sig);
}
/*---------------------------------------------------------------------------*/
-#define _SPI_DEBUG(format, args...) g_print (format , ## args)
+/*
+ * Emits an AT-SPI event.
+ * AT-SPI events names are split into three parts:
+ * class:major:minor
+ * This is mapped onto D-Bus events as:
+ * D-Bus Interface:Signal Name:Detail argument
+ *
+ * Marshals a basic type into the 'any_data' attribute of
+ * the AT-SPI event.
+ */
+static void
+emit_event (DBusConnection *bus,
+ const char *klass,
+ const char *major,
+ const char *minor,
+ dbus_int32_t detail1,
+ dbus_int32_t detail2,
+ const char *name,
+ const char *path)
+{
+ DBusMessage *sig;
+ DBusMessageIter iter, iter_variant;
+
+ sig = dbus_message_new_signal(SPI_DBUS_PATH_ROOT, klass, major);
-static gchar *app_sig_match_name_owner =
- "type='signal', interface='org.freedesktop.DBus', member='NameOwnerChanged'";
+ dbus_message_iter_init_append(sig, &iter);
+
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &minor);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2);
+
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "(so)",
+ &iter_variant);
+ append_reference (&iter_variant, name, path);
+ dbus_message_iter_close_container (&iter, &iter_variant);
+
+ dbus_connection_send(bus, sig, NULL);
+ dbus_message_unref(sig);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Children changed signal converter and forwarder.
+ *
+ * Klass (Interface) org.freedesktop.atspi.Event.Object
+ * Major is the signal name.
+ * Minor is 'add' or 'remove'
+ * detail1 is the index.
+ * detail2 is 0.
+ * any_data is the child reference.
+ */
+
+static gboolean
+children_added_listener (DBusConnection * bus,
+ gint index,
+ const gchar * name,
+ const gchar * path)
+{
+ emit_event (bus, SPI_DBUS_INTERFACE_EVENT_OBJECT, "ChildrenChanged", "add", index, 0,
+ name, path);
+}
+
+static gboolean
+children_removed_listener (DBusConnection * bus,
+ gint index,
+ const gchar * name,
+ const gchar * path)
+{
+ emit_event (bus, SPI_DBUS_INTERFACE_EVENT_OBJECT, "ChildrenChanged", "remove", index, 0,
+ name, SPI_DBUS_PATH_NULL);
+}
+
+/*---------------------------------------------------------------------------*/
static DBusHandlerResult
-handle_registry_method (DBusConnection *bus, DBusMessage *message, void *user_data)
+handle_method (DBusConnection *bus, DBusMessage *message, void *user_data)
{
+ DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
const gchar *iface = dbus_message_get_interface (message);
const gchar *member = dbus_message_get_member (message);
const gint type = dbus_message_get_type (message);
@@ -265,35 +707,148 @@ handle_registry_method (DBusConnection *bus, DBusMessage *message, void *user_da
iface == NULL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (strcmp (iface, SPI_DBUS_INTERFACE_REGISTRY))
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ if (!strcmp (iface, "org.freedesktop.DBus.Properties"))
+ {
+ if (!strcmp (member, "Get"))
+ {
+ const gchar *prop_iface;
+ const gchar *prop_member;
+ DBusError error;
+
+ dbus_error_init (&error);
+ if (dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_STRING,
+ &prop_iface,
+ DBUS_TYPE_STRING,
+ &prop_member,
+ DBUS_TYPE_INVALID))
+ {
+ DBusMessageIter iter;
+
+ reply = dbus_message_new_method_return (message);
+ dbus_message_iter_init_append (reply, &iter);
+
+ if (strcmp (iface, SPI_DBUS_INTERFACE_ACCESSIBLE))
+ {
+ if (!strcmp (member, "Name"))
+ impl_get_Name (&iter, user_data);
+ else if (!strcmp (member, "Description"))
+ impl_get_Description (&iter, user_data);
+ else if (!strcmp (member, "Parent"))
+ impl_get_Parent (&iter, user_data);
+ else if (!strcmp (member, "ChildCount"))
+ impl_get_ChildCount (&iter, user_data);
+ else
+ {
+ dbus_message_unref (reply);
+ reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, "Property unavailable");
+ }
+ }
+ }
+ else
+ {
+ reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, error.message);
+ }
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ else if (!strcmp (member, "GetAll"))
+ {
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
- if (!strcmp (member, "GetApplications"))
- reply = impl_GetApplications (bus, message, user_data);
- else if (!strcmp (member, "RegisterApplication"))
- reply = impl_RegisterApplication (bus, message, user_data);
- else if (!strcmp (member, "DeregisterApplication"))
- reply = impl_DeregisterApplication (bus, message, user_data);
- else
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ if (strcmp (iface, SPI_DBUS_INTERFACE_ACCESSIBLE))
+ {
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ if (!strcmp (member, "GetChildAtIndex"))
+ reply = impl_GetChildAtIndex (bus, message, user_data);
+ else if (!strcmp (member, "GetChildren"))
+ reply = impl_GetChildren (bus, message, user_data);
+ else if (!strcmp (member, "GetIndexInParent"))
+ reply = impl_GetIndexInParent (bus, message, user_data);
+ else if (!strcmp (member, "GetRelationSet"))
+ reply = impl_GetRelationSet (bus, message, user_data);
+ else if (!strcmp (member, "GetRole"))
+ reply = impl_GetRole (bus, message, user_data);
+ else if (!strcmp (member, "GetRoleName"))
+ reply = impl_GetRoleName (bus, message, user_data);
+ else if (!strcmp (member, "GetLocalizedRoleName"))
+ reply = impl_GetLocalizedRoleName (bus, message, user_data);
+ else if (!strcmp (member, "GetState"))
+ reply = impl_GetState (bus, message, user_data);
+ else if (!strcmp (member, "GetAttributes"))
+ reply = impl_GetAttributes (bus, message, user_data);
+ else if (!strcmp (member, "GetApplication"))
+ reply = impl_GetApplication (bus, message, user_data);
+ else if (!strcmp (member, "GetInterfaces"))
+ reply = impl_GetInterfaces (bus, message, user_data);
+ else
+ result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (strcmp (iface, SPI_DBUS_INTERFACE_COMPONENT))
+ {
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ if (!strcmp (member, "Contains"))
+ reply = impl_Contains (bus, message, user_data);
+ else if (!strcmp (member, "GetAccessibleAtPoint"))
+ reply = impl_GetAccessibleAtPoint (bus, message, user_data);
+ else if (!strcmp (member, "GetExtents"))
+ reply = impl_GetExtents (bus, message, user_data);
+ else if (!strcmp (member, "GetPosition"))
+ reply = impl_GetPosition (bus, message, user_data);
+ else if (!strcmp (member, "GetSize"))
+ reply = impl_GetSize (bus, message, user_data);
+ else if (!strcmp (member, "GetLayer"))
+ reply = impl_GetLayer (bus, message, user_data);
+ else if (!strcmp (member, "GetMDIZOrder"))
+ reply = impl_GetMDIZOrder (bus, message, user_data);
+ else if (!strcmp (member, "GrabFocus"))
+ reply = impl_GrabFocus (bus, message, user_data);
+ else if (!strcmp (member, "GetAlpha"))
+ reply = impl_GetAlpha (bus, message, user_data);
+ else
+ result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (strcmp (iface, SPI_DBUS_INTERFACE_SOCKET))
+ {
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ if (!strcmp (member, "Embed"))
+ reply = impl_Embed (bus, message, user_data);
+ else if (!strcmp (member, "Unembed"))
+ reply = impl_Unembed (bus, message, user_data);
+ else
+ result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
- if (!reply)
+ if (result == DBUS_HANDLER_RESULT_HANDLED)
{
- reply = dbus_message_new_method_return (message);
+ if (!reply)
+ {
+ reply = dbus_message_new_method_return (message);
+ }
+
+ dbus_connection_send (bus, reply, NULL);
+ dbus_message_unref (reply);
}
- dbus_connection_send (bus, reply, NULL);
- dbus_message_unref (reply);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return result;
}
+/*---------------------------------------------------------------------------*/
+
static DBusObjectPathVTable registry_vtable =
{
NULL,
- &handle_registry_method,
+ &handle_method,
NULL, NULL, NULL, NULL
};
+static gchar *app_sig_match_name_owner =
+ "type='signal', interface='org.freedesktop.DBus', member='NameOwnerChanged'";
+
SpiRegistry *
spi_registry_new (DBusConnection *bus)
{
@@ -306,6 +861,8 @@ spi_registry_new (DBusConnection *bus)
dbus_connection_register_object_path (bus, SPI_DBUS_PATH_REGISTRY, ®istry_vtable, reg);
+ emit_Available (bus);
+
return reg;
}
diff --git a/registryd/registry.h b/registryd/registry.h
index 6d1be2a..ec33618 100644
--- a/registryd/registry.h
+++ b/registryd/registry.h
@@ -42,7 +42,7 @@ G_BEGIN_DECLS
struct _SpiRegistry {
GObject parent;
- GSequence *apps;
+ GPtrArray *apps;
DBusConnection *bus;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]