X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=atk-adaptor%2Fevent.c;h=0430271c45f068730efc902e663af3d7e6d22ab7;hb=0d5406c910195ab9869f055d6a5ae8efb333c8a2;hp=61387b0d31ee29ef6b904b017049cd4d140ceaeb;hpb=024cd9555c052466010b8bae10c76851f5559d88;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c index 61387b0..0430271 100644 --- a/atk-adaptor/event.c +++ b/atk-adaptor/event.c @@ -64,10 +64,10 @@ switch_main_context (GMainContext *cnx) { GList *list; -#ifndef DISABLE_P2P - atspi_dbus_server_setup_with_g_main (spi_global_app_data->server, cnx); -#endif + if (spi_global_app_data->server) + atspi_dbus_server_setup_with_g_main (spi_global_app_data->server, cnx); atspi_dbus_connection_setup_with_g_main (spi_global_app_data->bus, cnx); + atspi_set_main_context (cnx); for (list = spi_global_app_data->direct_connections; list; list = list->next) atspi_dbus_connection_setup_with_g_main (list->data, cnx); } @@ -88,8 +88,8 @@ timeout_reply (void *data) { SpiReentrantCallClosure *closure = data; - if (!dbus_connection_get_is_connected (closure->bus)) - g_main_loop_quit (closure->loop); + switch_main_context (NULL); + g_main_loop_quit (closure->loop); closure->timeout = -1; return FALSE; } @@ -99,15 +99,12 @@ send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) { DBusPendingCall *pending; SpiReentrantCallClosure closure; - GMainContext *main_context; GSource *source; - main_context = (g_getenv ("AT_SPI_CLIENT") ? NULL : - spi_global_app_data->main_context); closure.bus = bus; - closure.loop = g_main_loop_new (main_context, FALSE); + closure.loop = g_main_loop_new (spi_global_app_data->main_context, FALSE); closure.reply = NULL; - switch_main_context (main_context); + switch_main_context (spi_global_app_data->main_context); if (!dbus_connection_send_with_reply (bus, message, &pending, 9000) || !pending) { @@ -117,13 +114,15 @@ send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL); source = g_timeout_source_new (500); g_source_set_callback (source, timeout_reply, &closure, NULL); - closure.timeout = g_source_attach (source, main_context); + closure.timeout = g_source_attach (source, spi_global_app_data->main_context); g_source_unref (source); g_main_loop_run (closure.loop); if (closure.timeout != -1) g_source_destroy (source); g_main_loop_unref (closure.loop); + if (!closure.reply) + dbus_pending_call_cancel (pending); return closure.reply; } @@ -141,7 +140,6 @@ Accessibility_DeviceEventController_NotifyListenersSync (const * key_event) { DBusMessage *message; - DBusError error; dbus_bool_t consumed = FALSE; message = @@ -150,7 +148,6 @@ Accessibility_DeviceEventController_NotifyListenersSync (const ATSPI_DBUS_INTERFACE_DEC, "NotifyListenersSync"); - dbus_error_init (&error); if (spi_dbus_marshal_deviceEvent (message, key_event)) { DBusMessage *reply = @@ -159,8 +156,12 @@ Accessibility_DeviceEventController_NotifyListenersSync (const { DBusError error; dbus_error_init (&error); - dbus_message_get_args (reply, &error, DBUS_TYPE_BOOLEAN, &consumed, - DBUS_TYPE_INVALID); + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_BOOLEAN, + &consumed, DBUS_TYPE_INVALID)) + { + /* TODO: print a warning */ + dbus_error_free (&error); + } dbus_message_unref (reply); } } @@ -233,23 +234,6 @@ spi_atk_bridge_key_listener (AtkKeyEventStruct * event, gpointer data) /*---------------------------------------------------------------------------*/ -static gchar * -convert_signal_name (const gchar * s) -{ - gchar *ret = g_strdup (s); - gchar *t; - - if (!ret) - return NULL; - ret[0] = toupper (ret[0]); - while ((t = strchr (ret, '-')) != NULL) - { - memmove (t, t + 1, strlen (t)); - *t = toupper (*t); - } - return ret; -} - static const void * validate_for_dbus (const gint type, const void *val) @@ -369,14 +353,37 @@ ensure_proper_format (const char *name) return ret; } +void +append_properties (GArray *properties, event_data *evdata) +{ + GSList *ls; + gint i; + + for (ls = evdata->properties; ls; ls = ls->next) + { + gboolean dup = FALSE; + for (i = 0; i < properties->len; i++) + { + if (ls->data == g_array_index (properties, AtspiPropertyDefinition *, i)) + { + dup = TRUE; + break; + } + } + if (!dup) + g_array_append_val (properties, ls->data); + } +} + static gboolean -signal_is_needed (const gchar *klass, const gchar *major, const gchar *minor) +signal_is_needed (const gchar *klass, const gchar *major, const gchar *minor, + GArray **properties) { gchar *data [4]; - GList *iter; event_data *evdata; gboolean ret = FALSE; GList *list; + GArray *props = NULL; if (!spi_global_app_data->events_initialized) return TRUE; @@ -390,41 +397,41 @@ signal_is_needed (const gchar *klass, const gchar *major, const gchar *minor) * TODO: FOr 2.2, have at-spi2-core define a special "cache listener" for * this instead, so that we don't send these if no one is listening */ if (!g_strcmp0 (data [1], "ChildrenChanged") || - !g_strcmp0 (data [1], "PropertyChange") || + ((!g_strcmp0 (data [1], "PropertyChange")) && + (!g_strcmp0 (data [2], "accessible-name") || + !g_strcmp0 (data [2], "accessible-description") || + !g_strcmp0 (data [2], "accessible-parent") || + !g_strcmp0 (data [2], "accessible-role"))) || !g_strcmp0 (data [1], "StateChanged")) - { - g_free (data [2]); - g_free (data [1]); - g_free (data [0]); - return TRUE; - } + ret = TRUE; /* Hack: events such as "object::text-changed::insert:system" as generated by Gecko */ data [2][strcspn (data [2], ":")] = '\0'; + for (list = spi_global_app_data->events; list; list = list->next) { evdata = list->data; if (spi_event_is_subtype (data, evdata->data)) { ret = TRUE; - break; + if (!props) + props = g_array_new (TRUE, TRUE, sizeof (AtspiPropertyDefinition *)); + append_properties (props, evdata); } } -#if 0 - g_print("event: %s %s %s: %d\n", data[0], data[1], data[2], ret); -#endif g_free (data [2]); g_free (data [1]); g_free (data [0]); + *properties = props; return ret; } /* Convert a : to a / so that listeners can use arg0path to match only * * the prefix */ static char * -adapt_minor_for_dbus (char *source) +adapt_minor_for_dbus (const char *source) { gchar *ret = g_strdup (source); int i = strcspn (ret, ":"); @@ -433,6 +440,14 @@ adapt_minor_for_dbus (char *source) return ret; } +static void +open_variant (DBusMessageIter *iter, const char *name, const char *type, + DBusMessageIter *out) +{ + dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &name); + dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, type, out); +} + /* * Emits an AT-SPI event. * AT-SPI events names are split into three parts: @@ -455,22 +470,24 @@ emit_event (AtkObject *obj, void (*append_variant) (DBusMessageIter *, const char *, const void *)) { DBusConnection *bus = spi_global_app_data->bus; - const char *path; + char *path; char *minor_dbus; - gchar *cname, *t; + gchar *cname; DBusMessage *sig; - DBusMessageIter iter, iter_struct; + DBusMessageIter iter, iter_dict, iter_dict_entry, iter_variant, iter_array; + GArray *properties = NULL; if (!klass) klass = ""; if (!major) major = ""; if (!minor) minor = ""; if (!type) type = "u"; - if (!signal_is_needed (klass, major, minor)) + if (!signal_is_needed (klass, major, minor, &properties)) return; path = spi_register_object_to_path (spi_global_register, G_OBJECT (obj)); + g_return_if_fail (path != NULL); /* * This is very annoying, but as '-' isn't a legal signal @@ -488,7 +505,28 @@ emit_event (AtkObject *obj, dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail1); dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &detail2); append_variant (&iter, type, val); - spi_object_append_reference (&iter, spi_global_app_data->root); + + dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &iter_dict); + /* Add requested properties, unless the object is being marked defunct, in + which case it's safest not to touch it */ + if (minor == NULL || strcmp (minor, "defunct") != 0 || detail1 == 0) + { + if (properties) + { + gint i; + for (i = 0; i < properties->len; i++) + { + AtspiPropertyDefinition *prop = g_array_index (properties, AtspiPropertyDefinition *, i); + dbus_message_iter_open_container (&iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, + &iter_dict_entry); + dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &prop->name); + prop->func (&iter_dict_entry, obj); + dbus_message_iter_close_container (&iter_dict, &iter_dict_entry); + } + g_array_free (properties, TRUE); + } + } + dbus_message_iter_close_container (&iter, &iter_dict); dbus_connection_send(bus, sig, NULL); dbus_message_unref(sig); @@ -536,7 +574,7 @@ property_event_listener (GSignalInvocationHint * signal_hint, const gchar *pname = NULL; AtkObject *otemp; - const gchar *s1, s2; + const gchar *s1; gint i; accessible = g_value_get_object (¶m_values[0]); @@ -640,7 +678,7 @@ state_event_listener (GSignalInvocationHint * signal_hint, const GValue * param_values, gpointer data) { AtkObject *accessible; - gchar *pname; + const gchar *pname; guint detail1; accessible = ATK_OBJECT (g_value_get_object (¶m_values[0])); @@ -650,7 +688,7 @@ state_event_listener (GSignalInvocationHint * signal_hint, emit_event (accessible, ITF_EVENT_OBJECT, STATE_CHANGED, pname, detail1, 0, DBUS_TYPE_INT32_AS_STRING, 0, append_basic); - if (!g_strcmp0 (pname, "defunct")) + if (!g_strcmp0 (pname, "defunct") && detail1) spi_register_deregister_object (spi_global_register, G_OBJECT (accessible), TRUE); return TRUE; @@ -698,6 +736,7 @@ window_event_listener (GSignalInvocationHint * signal_hint, * Gtk:AtkDocument:load-complete -> document:load-complete * Gtk:AtkDocument:load-stopped -> document:load-stopped * Gtk:AtkDocument:reload -> document:reload + * Gtk:AtkDocument:page-changed -> document:page-changed */ static gboolean document_event_listener (GSignalInvocationHint * signal_hint, @@ -707,13 +746,18 @@ document_event_listener (GSignalInvocationHint * signal_hint, AtkObject *accessible; GSignalQuery signal_query; const gchar *name, *s; + gint detail1 = 0; g_signal_query (signal_hint->signal_id, &signal_query); name = signal_query.signal_name; + if (n_param_values > 0) // on the case of page-changed + if (G_VALUE_TYPE (¶m_values[1]) == G_TYPE_INT) + detail1 = g_value_get_int (¶m_values[1]); + accessible = ATK_OBJECT (g_value_get_object (¶m_values[0])); s = atk_object_get_name (accessible); - emit_event (accessible, ITF_EVENT_DOCUMENT, name, "", 0, 0, + emit_event (accessible, ITF_EVENT_DOCUMENT, name, "", detail1, 0, DBUS_TYPE_STRING_AS_STRING, s, append_basic); return TRUE; @@ -733,7 +777,7 @@ bounds_event_listener (GSignalInvocationHint * signal_hint, AtkObject *accessible; AtkRectangle *atk_rect; GSignalQuery signal_query; - const gchar *name, *s; + const gchar *name; g_signal_query (signal_hint->signal_id, &signal_query); name = signal_query.signal_name; @@ -765,7 +809,7 @@ active_descendant_event_listener (GSignalInvocationHint * signal_hint, AtkObject *accessible; AtkObject *child; GSignalQuery signal_query; - const gchar *name, *minor; + const gchar *name; gint detail1; g_signal_query (signal_hint->signal_id, &signal_query); @@ -774,7 +818,6 @@ active_descendant_event_listener (GSignalInvocationHint * signal_hint, accessible = ATK_OBJECT (g_value_get_object (¶m_values[0])); child = ATK_OBJECT (g_value_get_pointer (¶m_values[1])); g_return_val_if_fail (ATK_IS_OBJECT (child), TRUE); - minor = g_quark_to_string (signal_hint->detail); detail1 = atk_object_get_index_in_parent (child); @@ -870,7 +913,8 @@ text_insert_event_listener (GSignalInvocationHint * signal_hint, guint text_changed_signal_id; GSignalQuery signal_query; const gchar *name; - gchar *minor, *text; + const gchar *minor_raw, *text; + gchar *minor; gint detail1 = 0, detail2 = 0; accessible = ATK_OBJECT (g_value_get_object (¶m_values[0])); @@ -883,9 +927,9 @@ text_insert_event_listener (GSignalInvocationHint * signal_hint, /* Add the insert and keep any detail coming from atk */ - minor = g_quark_to_string (signal_hint->detail); - if (minor) - minor = g_strconcat ("insert:", minor, NULL); + minor_raw = g_quark_to_string (signal_hint->detail); + if (minor_raw) + minor = g_strconcat ("insert:", minor_raw, NULL); else minor = g_strdup ("insert"); @@ -918,7 +962,8 @@ text_remove_event_listener (GSignalInvocationHint * signal_hint, guint text_changed_signal_id; GSignalQuery signal_query; const gchar *name; - gchar *minor, *text; + const gchar *minor_raw, *text; + gchar *minor; gint detail1 = 0, detail2 = 0; accessible = ATK_OBJECT (g_value_get_object (¶m_values[0])); @@ -929,12 +974,11 @@ text_remove_event_listener (GSignalInvocationHint * signal_hint, g_signal_query (text_changed_signal_id, &signal_query); name = signal_query.signal_name; - minor = g_quark_to_string (signal_hint->detail); + minor_raw = g_quark_to_string (signal_hint->detail); /* Add the delete and keep any detail coming from atk */ - minor = g_quark_to_string (signal_hint->detail); - if (minor) - minor = g_strconcat ("delete:", minor, NULL); + if (minor_raw) + minor = g_strconcat ("delete:", minor_raw, NULL); else minor = g_strdup ("delete"); @@ -1034,6 +1078,7 @@ children_changed_event_listener (GSignalInvocationHint * signal_hint, detail1); emit_event (accessible, ITF_EVENT_OBJECT, name, minor, detail1, detail2, "(so)", ao, append_object); + g_object_unref (ao); } else { @@ -1046,24 +1091,6 @@ children_changed_event_listener (GSignalInvocationHint * signal_hint, /*---------------------------------------------------------------------------*/ -static void -toplevel_added_event_listener (AtkObject * accessible, - guint index, AtkObject * child) -{ - emit_event (accessible, ITF_EVENT_OBJECT, "children-changed", "add", index, 0, - "(so)", child, append_object); -} - -static void -toplevel_removed_event_listener (AtkObject * accessible, - guint index, AtkObject * child) -{ - emit_event (accessible, ITF_EVENT_OBJECT, "children-changed", "remove", index, 0, - "(so)", child, append_object); -} - -/*---------------------------------------------------------------------------*/ - /* * Generic signal converter and forwarder. * @@ -1188,6 +1215,8 @@ spi_atk_register_event_listeners (void) add_signal_listener (document_event_listener, "Gtk:AtkDocument:reload"); add_signal_listener (document_event_listener, "Gtk:AtkDocument:load-stopped"); + add_signal_listener (document_event_listener, + "Gtk:AtkDocument:page-changed"); /* TODO Fake this event on the client side */ add_signal_listener (state_event_listener, "Gtk:AtkObject:state-change"); /* TODO */