[at-spi2-core] Notify registry of event registrations and use to start polling of mouse
- From: Mike Gorse <mgorse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [at-spi2-core] Notify registry of event registrations and use to start polling of mouse
- Date: Mon, 9 Aug 2010 16:14:21 +0000 (UTC)
commit f4f23b3beb205397f30ab3bba91325d4c3ab6526
Author: Mike Gorse <mgorse novell com>
Date: Mon Aug 9 12:12:01 2010 -0400
Notify registry of event registrations and use to start polling of mouse
FDO#29427; listening for mouse:abs events now works.
This is also the first step in moving towards only emitting events when
a client is listening.
registryd/deviceeventcontroller.c | 5 +-
registryd/introspection.c | 12 ++-
registryd/paths.h | 1 +
registryd/registry.c | 189 ++++++++++++++++++++++++++++++++++++-
registryd/registry.h | 4 +
xml/Application.xml | 8 ++
6 files changed, 215 insertions(+), 4 deletions(-)
---
diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c
index 529bf69..ea61c15 100644
--- a/registryd/deviceeventcontroller.c
+++ b/registryd/deviceeventcontroller.c
@@ -999,7 +999,7 @@ spi_controller_register_device_listener (SpiDEController *controller,
{
have_mouse_listener = TRUE;
if (!have_mouse_event_listener)
- g_timeout_add (100, spi_dec_poll_mouse_idle, controller->registry);
+ g_timeout_add (100, spi_dec_poll_mouse_idle, controller);
}
spi_dbus_add_disconnect_match (controller->bus, listener->bus_name);
break;
@@ -2959,6 +2959,7 @@ spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus)
SpiDEController *dec = g_object_new (SPI_DEVICE_EVENT_CONTROLLER_TYPE, NULL);
dec->registry = g_object_ref (reg);
+ reg->dec = g_object_ref (dec);
dec->bus = bus;
dbus_connection_register_object_path (bus, SPI_DBUS_PATH_DEC, &dec_vtable, dec);
@@ -2975,7 +2976,7 @@ spi_device_event_controller_start_poll_mouse (SpiRegistry *registry)
{
have_mouse_event_listener = TRUE;
if (!have_mouse_listener)
- g_timeout_add (100, spi_dec_poll_mouse_idle, registry);
+ g_timeout_add (100, spi_dec_poll_mouse_idle, registry->dec);
}
}
diff --git a/registryd/introspection.c b/registryd/introspection.c
index 01ceadc..198c241 100644
--- a/registryd/introspection.c
+++ b/registryd/introspection.c
@@ -26,10 +26,12 @@ const char *spi_org_a11y_atspi_Accessible =
" <method name=\"GetChildAtIndex\">"
" <arg direction=\"in\" name=\"index\" type=\"i\" />"
" <arg direction=\"out\" type=\"(so)\" />"
-" </method>"
" "
+" </method>"
+""
" <method name=\"GetChildren\">"
" <arg direction=\"out\" type=\"a(so)\" />"
+" "
" </method>"
""
" <method name=\"GetIndexInParent\">"
@@ -118,6 +120,14 @@ const char *spi_org_a11y_atspi_Application =
" <arg direction=\"out\" type=\"s\" />"
" </method>"
""
+" <method name=\"RegisterEventListener\">"
+" <arg direction=\"in\" name=\"event\" type=\"s\" />"
+" </method>"
+""
+" <method name=\"DeregisterEventListener\">"
+" <arg direction=\"in\" name=\"event\" type=\"s\" />"
+" </method>"
+""
"</interface>"
"";
diff --git a/registryd/paths.h b/registryd/paths.h
index 6ef98bd..b0f3f7a 100644
--- a/registryd/paths.h
+++ b/registryd/paths.h
@@ -37,6 +37,7 @@
#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_APPLICATION SPI_DBUS_INTERFACE_PREFIX "Application"
#define SPI_DBUS_INTERFACE_ACCESSIBLE SPI_DBUS_INTERFACE_PREFIX "Accessible"
#define SPI_DBUS_INTERFACE_COMPONENT SPI_DBUS_INTERFACE_PREFIX "Component"
diff --git a/registryd/registry.c b/registryd/registry.c
index 8391971..3c4ddf5 100644
--- a/registryd/registry.c
+++ b/registryd/registry.c
@@ -30,6 +30,13 @@
#include "registry.h"
#include "introspection.h"
+typedef struct event_data event_data;
+struct event_data
+{
+ gchar *bus_name;
+ gchar **data;
+};
+
static void
children_added_listener (DBusConnection * bus,
gint index,
@@ -193,6 +200,69 @@ remove_application (SpiRegistry *reg, DBusConnection *bus, guint index)
g_ptr_array_remove_index (reg->apps, index);
}
+static gboolean
+event_is_subtype (gchar **needle, gchar **haystack)
+{
+ while (*haystack && **haystack)
+ {
+ if (g_strcmp0 (*needle, *haystack))
+ return FALSE;
+ needle++;
+ haystack++;
+ }
+ return TRUE;
+}
+
+static gboolean
+needs_mouse_poll (char **event)
+{
+ if (g_strcmp0 (event [0], "Mouse") != 0)
+ return FALSE;
+ if (!event [1] || !event [1][0])
+ return TRUE;
+ return (g_strcmp0 (event [1], "Abs") == 0);
+}
+
+static void
+remove_events (SpiRegistry *registry, const char *bus_name, const char *event)
+{
+ event_data *evdata;
+ gchar **remove_data;
+ GList *list;
+ gboolean mouse_found = FALSE;
+
+ remove_data = g_strsplit (event, ":", 3);
+ if (!remove_data)
+ {
+ return;
+ }
+
+ for (list = registry->events; list;)
+ {
+ event_data *evdata = list->data;
+ if (!g_strcmp0 (evdata->bus_name, bus_name) &&
+ event_is_subtype (evdata->data, remove_data))
+ {
+ list = list->next;
+ g_strfreev (evdata->data);
+ g_free (evdata->bus_name);
+ g_free (evdata);
+ registry->events = g_list_remove (registry->events, evdata);
+ }
+ else
+ {
+ if (needs_mouse_poll (evdata->data))
+ mouse_found = TRUE;
+ list = list->next;
+ }
+ }
+
+ if (!mouse_found)
+ spi_device_event_controller_stop_poll_mouse ();
+
+ g_strfreev (remove_data);
+}
+
static void
handle_disconnection (DBusConnection *bus, DBusMessage *message, void *user_data)
{
@@ -218,8 +288,44 @@ handle_disconnection (DBusConnection *bus, DBusMessage *message, void *user_data
g_ptr_array_remove_index (reg->apps, i);
}
}
+
+ remove_events (reg, old, "");
+ }
+ }
+}
+
+/*
+ * Converts names of th eform "active-descendant-changed" to
+ *"ActiveDesendantChanged"
+ */
+static gchar *
+ensure_proper_format (const char *name)
+{
+ gchar *ret = (gchar *) g_malloc (strlen (name) * 2 + 2);
+ gchar *p = ret;
+ gboolean need_upper = TRUE;
+
+ if (!ret)
+ return NULL;
+ while (*name)
+ {
+ if (need_upper)
+ {
+ *p++ = toupper (*name);
+ need_upper = FALSE;
+ }
+ else if (*name == '-')
+ need_upper = TRUE;
+ else if (*name == ':')
+ {
+ need_upper = TRUE;
+ *p++ = *name;
}
+ else
+ *p++ = *name;
+ name++;
}
+ return ret;
}
static DBusHandlerResult
@@ -227,10 +333,15 @@ signal_filter (DBusConnection *bus, DBusMessage *message, void *user_data)
{
SpiRegistry *registry = SPI_REGISTRY (user_data);
guint res = DBUS_HANDLER_RESULT_HANDLED;
+ const gint type = dbus_message_get_type (message);
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"))
+ if (type != DBUS_MESSAGE_TYPE_SIGNAL)
+ return;
+
+ 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;
@@ -667,6 +778,70 @@ impl_GetInterfaces (DBusConnection * bus,
return reply;
}
+/* I would rather these two be signals, but I'm not sure that dbus-python
+ * supports emitting signals except for a service, so implementing as both
+ * a method call and signal for now.
+ */
+static DBusMessage *
+impl_register_event_listener (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ SpiRegistry *registry = SPI_REGISTRY (user_data);
+ const char *orig_name;
+ gchar *name;
+ event_data *evdata;
+ gchar **data;
+ GList *new_list;
+
+ if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &orig_name,
+ DBUS_TYPE_INVALID))
+ return;
+
+ name = ensure_proper_format (orig_name);
+
+ evdata = (event_data *) g_malloc (sizeof (*evdata));
+ if (!evdata)
+ return;
+ data = g_strsplit (name, ":", 3);
+ if (!data)
+ {
+ g_free (evdata);
+ return;
+ }
+ evdata->bus_name = g_strdup (dbus_message_get_sender (message));
+ evdata->data = data;
+ new_list = g_list_append (registry->events, evdata);
+ if (new_list)
+ registry->events = new_list;
+
+ if (needs_mouse_poll (evdata->data))
+ {
+ spi_device_event_controller_start_poll_mouse (registry);
+ }
+
+ g_free (name);
+ /* TODO: Send a signal */
+ return dbus_message_new_method_return (message);
+}
+
+static DBusMessage *
+impl_deregister_event_listener (DBusConnection *bus, DBusMessage *message, void *user_data)
+{
+ SpiRegistry *registry = SPI_REGISTRY (user_data);
+ const char *orig_name;
+ gchar *name;
+
+ if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &orig_name,
+ DBUS_TYPE_INVALID))
+ return;
+ name = ensure_proper_format (orig_name);
+
+ remove_events (registry, dbus_message_get_sender (message), name);
+
+ /* TODO: Send a signal */
+ g_free (name);
+ return dbus_message_new_method_return (message);
+}
+
/*---------------------------------------------------------------------------*/
static void
@@ -939,6 +1114,16 @@ handle_method (DBusConnection *bus, DBusMessage *message, void *user_data)
result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+ if (!strcmp (iface, SPI_DBUS_INTERFACE_APPLICATION))
+ {
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ if (!strcmp(member, "RegisterEventListener"))
+ reply = impl_register_event_listener (bus, message, user_data);
+ else if (!strcmp(member, "DeregisterEventListener"))
+ reply = impl_deregister_event_listener (bus, message, user_data);
+ else
+ result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
if (!strcmp (iface, "org.freedesktop.DBus.Introspectable"))
{
result = DBUS_HANDLER_RESULT_HANDLED;
@@ -994,6 +1179,8 @@ spi_registry_new (DBusConnection *bus)
emit_Available (bus);
+ reg->events = NULL;
+
return reg;
}
diff --git a/registryd/registry.h b/registryd/registry.h
index 6d4a04c..16dd0d9 100644
--- a/registryd/registry.h
+++ b/registryd/registry.h
@@ -32,6 +32,8 @@
typedef struct _SpiRegistry SpiRegistry;
typedef struct _SpiRegistryClass SpiRegistryClass;
+#include "deviceeventcontroller.h"
+
G_BEGIN_DECLS
#define SPI_REGISTRY_TYPE (spi_registry_get_type ())
@@ -42,10 +44,12 @@ G_BEGIN_DECLS
struct _SpiRegistry {
GObject parent;
+ SpiDEController *dec;
GPtrArray *apps;
dbus_int32_t id;
DBusConnection *bus;
+ GList *events;
};
struct _SpiRegistryClass {
diff --git a/xml/Application.xml b/xml/Application.xml
index cc90347..674a49d 100644
--- a/xml/Application.xml
+++ b/xml/Application.xml
@@ -13,5 +13,13 @@
<arg direction="out" type="s"/>
</method>
+ <method name="RegisterEventListener">
+ <arg direction="in" name="event" type="s"/>
+ </method>
+
+ <method name="DeregisterEventListener">
+ <arg direction="in" name="event" type="s"/>
+ </method>
+
</interface>
</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]