summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gorse <mgorse@suse.com>2022-07-01 21:14:14 -0500
committerMike Gorse <mgorse@suse.com>2022-07-02 02:50:03 -0500
commit7b4d74532e39a2c6a473945506b1cfebbbd1666e (patch)
tree9b6e5f04babee2ca7e4e6c84d2d89bf21f9edf27
parent28d732a20180b5b3f07cb0079b9d9943b881b929 (diff)
downloadat-spi2-core-7b4d74532e39a2c6a473945506b1cfebbbd1666e.tar.gz
Add atspi_event_listener_register_with_app
Allows an event listener to be registered only for a given application. Fixes #52
-rw-r--r--atspi/atspi-event-listener.c122
-rw-r--r--atspi/atspi-event-listener.h16
-rw-r--r--doc/libatspi/libatspi-sections.txt1
-rw-r--r--registryd/registry.c32
-rw-r--r--xml/Registry.xml2
5 files changed, 142 insertions, 31 deletions
diff --git a/atspi/atspi-event-listener.c b/atspi/atspi-event-listener.c
index c45ad91b..a79957c9 100644
--- a/atspi/atspi-event-listener.c
+++ b/atspi/atspi-event-listener.c
@@ -38,6 +38,7 @@ typedef struct
char *name;
char *detail;
GArray *properties;
+ AtspiAccessible *app;
} EventListenerEntry;
G_DEFINE_TYPE (AtspiEventListener, atspi_event_listener, G_TYPE_OBJECT)
@@ -336,7 +337,7 @@ demarshal_rect (DBusMessageIter *iter, AtspiRect *rect)
}
static gboolean
-convert_event_type_to_dbus (const char *eventType, char **categoryp, char **namep, char **detailp, GPtrArray **matchrule_array)
+convert_event_type_to_dbus (const char *eventType, char **categoryp, char **namep, char **detailp, AtspiAccessible *app, GPtrArray **matchrule_array)
{
gchar *tmp = _atspi_strdup_and_adjust_for_dbus (eventType);
char *category = NULL, *name = NULL, *detail = NULL;
@@ -357,6 +358,14 @@ convert_event_type_to_dbus (const char *eventType, char **categoryp, char **name
gchar *matchrule;
(*matchrule_array) = g_ptr_array_new ();
matchrule = g_strdup_printf ("type='signal',interface='org.a11y.atspi.Event.%s'", category);
+ if (app)
+ {
+ gchar *new_str = g_strconcat (matchrule, ",sender='",
+ app->parent.app->bus_name, "'",
+ NULL);
+ g_free (matchrule);
+ matchrule = new_str;
+ }
if (name && name [0])
{
gchar *new_str = g_strconcat (matchrule, ",member='", name, "'", NULL);
@@ -399,6 +408,9 @@ listener_entry_free (EventListenerEntry *e)
g_array_free (e->properties, TRUE);
+ if (e->app)
+ g_object_unref (e->app);
+
g_free (e);
}
@@ -521,7 +533,7 @@ atspi_event_listener_register (AtspiEventListener *listener,
* for a description of the format and legal event types.
* @properties: (element-type gchar*) (transfer none) (allow-none): a list of
* properties that should be sent along with the event. The
- * properties are valued for the duration of the event callback.k
+ * properties are valued for the duration of the event callback.
* TODO: Document.
*
* Adds an in-process callback function to an existing #AtspiEventListener.
@@ -545,23 +557,49 @@ atspi_event_listener_register_full (AtspiEventListener *listener,
error);
}
+/**
+ * atspi_event_listener_register_with_app:
+ * @listener: The #AtspiEventListener to register against an event type.
+ * @event_type: a character string indicating the type of events for which
+ * notification is requested. See #atspi_event_listener_register
+ * for a description of the format and legal event types.
+* @properties: (element-type gchar*) (transfer none) (allow-none): a list of
+ * properties that should be sent along with the event. The
+ * properties are valued for the duration of the event callback.
+ * @app: (allow-none): the application whose events should be reported, or
+ * %null for all applications.
+ *
+ * Adds an in-process callback function to an existing #AtspiEventListener.
+ *
+ * Returns: #TRUE if successful, otherwise #FALSE.
+ **/
+gboolean
+atspi_event_listener_register_with_app (AtspiEventListener *listener,
+ const gchar *event_type,
+ GArray *properties,
+ AtspiAccessible *app,
+ GError **error)
+{
+ return atspi_event_listener_register_from_callback_with_app (listener->callback,
+ listener->user_data,
+ listener->cb_destroyed,
+ event_type,
+ properties,
+ app,
+ error);
+}
+
static gboolean
notify_event_registered (EventListenerEntry *e)
{
+ const char *app_path = (e->app? e->app->parent.app->bus_name: "");
- if (e->properties)
- dbind_method_call_reentrant (_atspi_bus (), atspi_bus_registry,
- atspi_path_registry,
- atspi_interface_registry,
- "RegisterEvent",
- NULL, "sas", e->event_type,
- e->properties);
- else
- dbind_method_call_reentrant (_atspi_bus (), atspi_bus_registry,
- atspi_path_registry,
- atspi_interface_registry,
- "RegisterEvent",
- NULL, "s", e->event_type);
+ dbind_method_call_reentrant (_atspi_bus (), atspi_bus_registry,
+ atspi_path_registry,
+ atspi_interface_registry,
+ "RegisterEvent",
+ NULL, "sass", e->event_type,
+ e->properties, app_path);
return TRUE;
}
@@ -588,11 +626,11 @@ atspi_event_listener_register_from_callback (AtspiEventListenerCB callback,
const gchar *event_type,
GError **error)
{
- return atspi_event_listener_register_from_callback_full (callback,
- user_data,
- callback_destroyed,
- event_type, NULL,
- error);
+ return atspi_event_listener_register_from_callback_with_app (callback,
+ user_data,
+ callback_destroyed,
+ event_type, NULL,
+ NULL, error);
}
static GArray *
@@ -632,6 +670,35 @@ atspi_event_listener_register_from_callback_full (AtspiEventListenerCB callback,
GArray *properties,
GError **error)
{
+ return atspi_event_listener_register_from_callback_with_app (callback,
+ user_data,
+ callback_destroyed,
+ event_type, NULL,
+ NULL, error);
+}
+
+/**
+ * atspi_event_listener_register_from_callback_with_app:
+ * @callback: (scope async): an #AtspiEventListenerCB function pointer.
+ * @user_data: (closure callback)
+ * @callback_destroyed: (destroy callback)
+ * @event_type:
+ * @properties: (element-type utf8)
+* @app: (allow-none)
+ * @error:
+ *
+ * Returns: #TRUE if successful, otherwise #FALSE.
+ *
+ **/
+gboolean
+atspi_event_listener_register_from_callback_with_app (AtspiEventListenerCB callback,
+ void *user_data,
+ GDestroyNotify callback_destroyed,
+ const gchar *event_type,
+ GArray *properties,
+ AtspiAccessible *app,
+ GError **error)
+{
EventListenerEntry *e;
DBusError d_error;
GPtrArray *matchrule_array;
@@ -648,19 +715,21 @@ atspi_event_listener_register_from_callback_full (AtspiEventListenerCB callback,
return FALSE;
}
- e = g_new (EventListenerEntry, 1);
+ e = g_new0 (EventListenerEntry, 1);
e->event_type = g_strdup (event_type);
e->callback = callback;
e->user_data = user_data;
e->callback_destroyed = callback_destroyed;
callback_ref (callback == remove_datum ? (gpointer)user_data : (gpointer)callback,
callback_destroyed);
- if (!convert_event_type_to_dbus (event_type, &e->category, &e->name, &e->detail, &matchrule_array))
+ if (!convert_event_type_to_dbus (event_type, &e->category, &e->name, &e->detail, app, &matchrule_array))
{
g_free (e->event_type);
g_free (e);
return FALSE;
}
+ if (app)
+ e->app = g_object_ref (app);
e->properties = copy_event_properties (properties);
event_listeners = g_list_prepend (event_listeners, e);
for (i = 0; i < matchrule_array->len; i++)
@@ -778,7 +847,7 @@ atspi_event_listener_deregister_from_callback (AtspiEventListenerCB callback,
gint i;
GList *l;
- if (!convert_event_type_to_dbus (event_type, &category, &name, &detail, &matchrule_array))
+ if (!convert_event_type_to_dbus (event_type, &category, &name, &detail, NULL, &matchrule_array))
{
return FALSE;
}
@@ -920,7 +989,8 @@ _atspi_send_event (AtspiEvent *e)
g_value_set_int (&e->any_data, 0);
}
- if (!convert_event_type_to_dbus (e->type, &category, &name, &detail, NULL))
+ if (!convert_event_type_to_dbus (e->type, &category, &name, &detail, NULL,
+ NULL))
{
g_warning ("AT-SPI: Couldn't parse event: %s\n", e->type);
return;
@@ -931,7 +1001,9 @@ _atspi_send_event (AtspiEvent *e)
EventListenerEntry *entry = l->data;
if (!strcmp (category, entry->category) &&
(entry->name == NULL || !strcmp (name, entry->name)) &&
- detail_matches_listener (detail, entry->detail))
+ detail_matches_listener (detail, entry->detail) &&
+ (entry->app == NULL || !strcmp (entry->app->parent.app->bus_name,
+ e->source->parent.app->bus_name)))
{
GList *l2;
for (l2 = called_listeners; l2; l2 = l2->next)
diff --git a/atspi/atspi-event-listener.h b/atspi/atspi-event-listener.h
index b7ad3277..687e1e78 100644
--- a/atspi/atspi-event-listener.h
+++ b/atspi/atspi-event-listener.h
@@ -99,6 +99,13 @@ atspi_event_listener_register_full (AtspiEventListener *listener,
GError **error);
gboolean
+atspi_event_listener_register_with_app (AtspiEventListener *listener,
+ const gchar *event_type,
+ GArray *properties,
+ AtspiAccessible *app,
+ GError **error);
+
+gboolean
atspi_event_listener_register_from_callback (AtspiEventListenerCB callback,
void *user_data,
GDestroyNotify callback_destroyed,
@@ -114,6 +121,15 @@ atspi_event_listener_register_from_callback_full (AtspiEventListenerCB callback,
GError **error);
gboolean
+atspi_event_listener_register_from_callback_with_app (AtspiEventListenerCB callback,
+ void *user_data,
+ GDestroyNotify callback_destroyed,
+ const gchar *event_type,
+ GArray *properties,
+ AtspiAccessible *app,
+ GError **error);
+
+gboolean
atspi_event_listener_register_no_data (AtspiEventListenerSimpleCB callback,
GDestroyNotify callback_destroyed,
const gchar *event_type,
diff --git a/doc/libatspi/libatspi-sections.txt b/doc/libatspi/libatspi-sections.txt
index f8c407fb..b99b9046 100644
--- a/doc/libatspi/libatspi-sections.txt
+++ b/doc/libatspi/libatspi-sections.txt
@@ -447,6 +447,7 @@ atspi_event_listener_register_from_callback
atspi_event_listener_register_from_callback_full
atspi_event_listener_register_no_data
atspi_event_listener_register_full
+atspi_event_listener_register_with_app
atspi_event_listener_deregister
atspi_event_listener_deregister_from_callback
atspi_event_listener_deregister_no_data
diff --git a/registryd/registry.c b/registryd/registry.c
index e22fbcbc..b09c0e31 100644
--- a/registryd/registry.c
+++ b/registryd/registry.c
@@ -33,7 +33,8 @@
typedef struct event_data event_data;
struct event_data
{
- gchar *bus_name;
+ gchar *listener_bus_name;
+ gchar *app_bus_name;
gchar **data;
GSList *properties;
};
@@ -242,11 +243,12 @@ remove_events (SpiRegistry *registry, const char *bus_name, const char *event)
{
event_data *evdata = list->data;
list = list->next;
- if (!g_strcmp0 (evdata->bus_name, bus_name) &&
+ if (!g_strcmp0 (evdata->listener_bus_name, bus_name) &&
event_is_subtype (evdata->data, remove_data))
{
g_strfreev (evdata->data);
- g_free (evdata->bus_name);
+ g_free (evdata->listener_bus_name);
+ g_free (evdata->app_bus_name);
g_slist_free_full (evdata->properties, g_free);
registry->events = g_list_remove (registry->events, evdata);
g_free (evdata);
@@ -840,7 +842,8 @@ impl_register_event (DBusConnection *bus, DBusMessage *message, void *user_data)
const char *signature = dbus_message_get_signature (message);
if (strcmp (signature, "sas") != 0 &&
- strcmp (signature, "s") != 0)
+ strcmp (signature, "s") != 0 &&
+ strcmp (signature, "sass") != 0)
{
g_warning ("got RegisterEvent with invalid signature '%s'", signature);
return NULL;
@@ -853,7 +856,7 @@ impl_register_event (DBusConnection *bus, DBusMessage *message, void *user_data)
evdata = g_new0 (event_data, 1);
data = g_strsplit (name, ":", 3);
- evdata->bus_name = g_strdup (sender);
+ evdata->listener_bus_name = g_strdup (sender);
evdata->data = data;
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY)
@@ -867,7 +870,18 @@ impl_register_event (DBusConnection *bus, DBusMessage *message, void *user_data)
g_strdup (property));
dbus_message_iter_next (&iter_array);
}
+ dbus_message_iter_next (&iter);
}
+
+ if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
+ {
+ const char *app;
+ dbus_message_iter_get_basic (&iter, &app);
+ if (app[0])
+ evdata->app_bus_name = g_strdup (app);
+ dbus_message_iter_next (&iter);
+ }
+
registry->events = g_list_append (registry->events, evdata);
if (needs_mouse_poll (evdata->data))
@@ -881,6 +895,8 @@ impl_register_event (DBusConnection *bus, DBusMessage *message, void *user_data)
if (signal)
{
GSList *ls = evdata->properties;
+ if (evdata->app_bus_name)
+ dbus_message_set_destination (message, evdata->app_bus_name);
dbus_message_iter_init_append (signal, &iter);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &sender);
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &name);
@@ -926,6 +942,7 @@ impl_get_registered_events (DBusConnection *bus, DBusMessage *message, void *use
DBusMessage *reply;
DBusMessageIter iter, iter_struct, iter_array;
GList *list;
+ const char *sender = dbus_message_get_sender (message);
reply = dbus_message_new_method_return (message);
if (!reply)
@@ -937,11 +954,14 @@ impl_get_registered_events (DBusConnection *bus, DBusMessage *message, void *use
{
gchar *str;
evdata = list->data;
+ if (evdata->app_bus_name && strcmp (evdata->app_bus_name, sender) != 0)
+ continue;
+
str = g_strconcat (evdata->data [0],
":", (evdata->data [1]? evdata->data [1]: ""),
":", (evdata->data [1] && evdata->data [2]? evdata->data [2]: ""), NULL);
dbus_message_iter_open_container (&iter_array, DBUS_TYPE_STRUCT, NULL, &iter_struct);
- dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &evdata->bus_name);
+ dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &evdata->listener_bus_name);
dbus_message_iter_append_basic (&iter_struct, DBUS_TYPE_STRING, &str);
dbus_message_iter_close_container (&iter_array, &iter_struct);
g_free (str);
diff --git a/xml/Registry.xml b/xml/Registry.xml
index 65737bdc..1161794d 100644
--- a/xml/Registry.xml
+++ b/xml/Registry.xml
@@ -4,6 +4,8 @@
<method name="RegisterEvent">
<arg direction="in" name="event" type="s">
+ <arg direction="in" name="properties" type="as">
+ <arg direction="in" name="app_bus_name" type="s">
</arg>
</method>