diff options
author | Mike Gorse <mgorse@suse.com> | 2022-07-01 21:14:14 -0500 |
---|---|---|
committer | Mike Gorse <mgorse@suse.com> | 2022-07-02 02:50:03 -0500 |
commit | 7b4d74532e39a2c6a473945506b1cfebbbd1666e (patch) | |
tree | 9b6e5f04babee2ca7e4e6c84d2d89bf21f9edf27 | |
parent | 28d732a20180b5b3f07cb0079b9d9943b881b929 (diff) | |
download | at-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.c | 122 | ||||
-rw-r--r-- | atspi/atspi-event-listener.h | 16 | ||||
-rw-r--r-- | doc/libatspi/libatspi-sections.txt | 1 | ||||
-rw-r--r-- | registryd/registry.c | 32 | ||||
-rw-r--r-- | xml/Registry.xml | 2 |
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> |