X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=atspi%2Fatspi-misc.c;h=a7efb66dfc4755ef0eeeef94114a1b0a44deb1cd;hb=5016c77a44ff9bb5ce595a32429319d189839063;hp=89fe9e7554f92d65889675779d875ec7df584ae5;hpb=085444aede5f0990d069efc00916b14a1944c71a;p=platform%2Fupstream%2Fat-spi2-core.git diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index 89fe9e7..a7efb66 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -7,19 +7,19 @@ * Copyright 2010, 2011 Novell, Inc. * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public + * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. */ /* @@ -110,7 +110,7 @@ _atspi_get_iface_num (const char *iface) GHashTable * _atspi_get_live_refs (void) { - if (!live_refs) + if (!live_refs) { live_refs = g_hash_table_new (g_direct_hash, g_direct_equal); } @@ -159,7 +159,8 @@ cleanup () for (i = desktop->children->len - 1; i >= 0; i--) { AtspiAccessible *child = g_ptr_array_index (desktop->children, i); - g_object_run_dispose (G_OBJECT (child->parent.app)); + if (child->parent.app) + g_object_run_dispose (G_OBJECT (child->parent.app)); g_object_run_dispose (G_OBJECT (child)); } @@ -180,6 +181,7 @@ handle_get_bus_address (DBusPendingCall *pending, void *user_data) DBusMessage *message; const char *address; DBusPendingCall *new_pending; + dbus_bool_t result; if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) { @@ -203,7 +205,7 @@ handle_get_bus_address (DBusPendingCall *pending, void *user_data) else { if (!strcmp (error.name, DBUS_ERROR_FILE_NOT_FOUND)) - g_warning ("Unable to open bus connection: %s", error.message); + g_warning ("AT-SPI: Unable to open bus connection: %s", error.message); dbus_error_free (&error); } } @@ -218,9 +220,9 @@ handle_get_bus_address (DBusPendingCall *pending, void *user_data) "/org/a11y/atspi/cache", atspi_interface_cache, "GetItems"); - dbus_connection_send_with_reply (app->bus, message, &new_pending, 2000); + result = dbus_connection_send_with_reply (app->bus, message, &new_pending, 2000); dbus_message_unref (message); - if (!new_pending) + if (!result || !new_pending) return; dbus_pending_call_set_notify (new_pending, handle_get_items, app, NULL); } @@ -232,6 +234,7 @@ get_application (const char *bus_name) char *bus_name_dup; DBusMessage *message; DBusPendingCall *pending = NULL; + dbus_bool_t result; if (!app_hash) { @@ -252,9 +255,9 @@ get_application (const char *bus_name) message = dbus_message_new_method_call (bus_name, atspi_path_root, atspi_interface_application, "GetApplicationBusAddress"); - dbus_connection_send_with_reply (app->bus, message, &pending, 2000); + result = dbus_connection_send_with_reply (app->bus, message, &pending, 2000); dbus_message_unref (message); - if (!pending) + if (!result || !pending) { g_hash_table_remove (app_hash, bus_name_dup); return NULL; @@ -263,7 +266,7 @@ get_application (const char *bus_name) return app; } -static AtspiAccessible * +AtspiAccessible * ref_accessible (const char *app_name, const char *path) { AtspiApplication *app; @@ -390,7 +393,7 @@ handle_name_owner_changed (DBusConnection *bus, DBusMessage *message, void *user else if (app_hash) { AtspiApplication *app = g_hash_table_lookup (app_hash, old); - if (app && !strcmp (app->bus_name, old)) + if (app && app->bus_name && !strcmp(app->bus_name, name)) g_object_run_dispose (G_OBJECT (app)); } return DBUS_HANDLER_RESULT_HANDLED; @@ -531,8 +534,9 @@ handle_get_items (DBusPendingCall *pending, void *user_data) { const char *sender = dbus_message_get_sender (reply); const char *error = NULL; - if (!strcmp (dbus_message_get_error_name (reply), - DBUS_ERROR_SERVICE_UNKNOWN)) + const char *error_name = dbus_message_get_error_name (reply); + if (!strcmp (error_name, DBUS_ERROR_SERVICE_UNKNOWN) + || !strcmp (error_name, DBUS_ERROR_NO_REPLY)) { } else @@ -672,7 +676,7 @@ _atspi_dbus_return_hyperlink_from_message (DBusMessage *message) DBusMessageIter iter; AtspiHyperlink *retval = NULL; const char *signature; - + if (!message) return NULL; @@ -887,7 +891,7 @@ spi_display_name (void) * * Connects to the accessibility registry and initializes the SPI. * - * Returns: 0 on success, 1 if already initialized, or an integer error code. + * Returns: 0 on success, 1 if already initialized, or an integer error code. **/ int atspi_init (void) @@ -907,7 +911,8 @@ atspi_init (void) bus = atspi_get_a11y_bus (); if (!bus) return 2; - dbus_bus_register (bus, NULL); + if (!dbus_bus_register (bus, NULL)) + return 2; atspi_dbus_connection_setup_with_g_main(bus, g_main_context_default()); dbus_connection_add_filter (bus, atspi_dbus_filter, NULL, NULL); match = g_strdup_printf ("type='signal',interface='%s',member='AddAccessible'", atspi_interface_cache); @@ -984,7 +989,7 @@ atspi_event_quit (void) /** * atspi_exit: * - * Disconnects from #AtspiRegistry instances and releases + * Disconnects from #AtspiRegistry instances and releases * any floating resources. Call only once at exit. * * Returns: 0 if there were no leaks, otherwise other integer values. @@ -1035,6 +1040,7 @@ check_for_hang (DBusMessage *message, DBusError *error, DBusConnection *bus, con DBusMessage *message; gchar *bus_name_dup; DBusPendingCall *pending = NULL; + dbus_bool_t result; for (l = hung_processes; l; l = l->next) if (!strcmp (l->data, bus_name)) return; @@ -1043,9 +1049,9 @@ check_for_hang (DBusMessage *message, DBusError *error, DBusConnection *bus, con "Ping"); if (!message) return; - dbus_connection_send_with_reply (bus, message, &pending, -1); + result = dbus_connection_send_with_reply (bus, message, &pending, -1); dbus_message_unref (message); - if (!pending) + if (!result || !pending) return; bus_name_dup = g_strdup (bus_name); hung_processes = g_slist_append (hung_processes, bus_name_dup); @@ -1142,9 +1148,11 @@ _atspi_dbus_call_partial (gpointer obj, const char *type, ...) { va_list args; - + DBusMessage * result; va_start (args, type); - return _atspi_dbus_call_partial_va (obj, interface, method, error, type, args); + result = _atspi_dbus_call_partial_va (obj, interface, method, error, type, args); + va_end (args); + return result; } @@ -1158,9 +1166,9 @@ _atspi_dbus_call_partial_va (gpointer obj, { AtspiObject *aobj = ATSPI_OBJECT (obj); DBusError err; - DBusMessage *msg = NULL, *reply = NULL; - DBusMessageIter iter; - const char *p; + DBusMessage *msg = NULL, *reply = NULL; + DBusMessageIter iter; + const char *p; dbus_error_init (&err); @@ -1185,11 +1193,13 @@ out: process_deferred_messages (); if (dbus_error_is_set (&err)) { - /* TODO: Set gerror */ + g_set_error_literal(error, ATSPI_ERROR, ATSPI_ERROR_IPC, err.message); dbus_error_free (&err); + if (reply) + dbus_message_unref(reply); + return NULL; } - - if (reply && dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) + else if (reply && dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { const char *err_str = NULL; dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_str, DBUS_TYPE_INVALID); @@ -1198,7 +1208,6 @@ out: dbus_message_unref (reply); return NULL; } - return reply; } @@ -1258,7 +1267,7 @@ _atspi_dbus_get_property (gpointer obj, const char *interface, const char *name, dbus_message_iter_init (reply, &iter); if (dbus_message_iter_get_arg_type (&iter) != 'v') { - g_warning ("AT-SPI: expected a variant when fetching %s from interface %s; got %s\n", name, interface, dbus_message_get_signature (reply)); + g_warning ("atspi_dbus_get_property: expected a variant when fetching %s from interface %s; got %s\n", name, interface, dbus_message_get_signature (reply)); goto done; } dbus_message_iter_recurse (&iter, &iter_variant); @@ -1487,7 +1496,7 @@ get_accessibility_bus_address_x11 (void) g_warning ("Could not open X display"); return NULL; } - + AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False); XGetWindowProperty (bridge_display, XDefaultRootWindow (bridge_display), @@ -1530,12 +1539,12 @@ get_accessibility_bus_address_dbus (void) if (!reply) { - g_warning ("Error retrieving accessibility bus address: %s: %s", + g_warning ("AT-SPI: Error retrieving accessibility bus address: %s: %s", error.name, error.message); dbus_error_free (&error); - return NULL; + goto out; } - + { const char *tmp_address; if (!dbus_message_get_args (reply, @@ -1545,12 +1554,14 @@ get_accessibility_bus_address_dbus (void) DBUS_TYPE_INVALID)) { dbus_message_unref (reply); - return NULL; + goto out; } address = g_strdup (tmp_address); dbus_message_unref (reply); } +out: + dbus_connection_unref (session_bus); return address; } @@ -1575,16 +1586,22 @@ atspi_get_a11y_bus (void) { DBusError error; char *address = NULL; + const char *address_env = NULL; if (a11y_bus && dbus_connection_get_is_connected (a11y_bus)) return a11y_bus; if (a11y_dbus_slot == -1) if (!dbus_connection_allocate_data_slot (&a11y_dbus_slot)) - g_warning ("at-spi: Unable to allocate D-Bus slot"); + g_warning ("AT-SPI: Unable to allocate D-Bus slot"); + address_env = g_getenv ("AT_SPI_BUS_ADDRESS"); + if (address_env != NULL && *address_env != 0) + address = g_strdup (address_env); #ifdef HAVE_X11 - address = get_accessibility_bus_address_x11 (); + if (!address && g_getenv ("DISPLAY") != NULL && + g_getenv ("WAYLAND_DISPLAY") == NULL) + address = get_accessibility_bus_address_x11 (); #endif if (!address) address = get_accessibility_bus_address_dbus (); @@ -1614,7 +1631,7 @@ atspi_get_a11y_bus (void) return NULL; } } - + /* Simulate a weak ref on the bus */ dbus_connection_set_data (a11y_bus, a11y_dbus_slot, a11y_bus, a11y_bus_free); @@ -1814,7 +1831,7 @@ _atspi_dbus_update_cache_from_dict (AtspiAccessible *accessible, DBusMessageIter g_value_set_boxed (val, &extents); } if (val) - g_hash_table_insert (cache, g_strdup (key), val); + g_hash_table_insert (cache, g_strdup (key), val); dbus_message_iter_next (&iter_dict); } @@ -1842,3 +1859,50 @@ _atspi_set_error_no_sync (GError **error) g_set_error_literal (error, ATSPI_ERROR, ATSPI_ERROR_SYNC_NOT_ALLOWED, _("Attempted synchronous call where prohibited")); } + +static const char *sr_introspection = "\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +""; + +static DBusHandlerResult +screen_reader_filter (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE, + "Introspect")) + { + DBusMessage *reply = dbus_message_new_method_return (message); + dbus_message_append_args (reply, DBUS_TYPE_STRING, &sr_introspection, + DBUS_TYPE_INVALID); + dbus_connection_send (bus, reply, NULL); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +gboolean +_atspi_prepare_screen_reader_interface () +{ + static gint initialized = 0; + DBusConnection *a11y_bus = _atspi_bus (); + + if (initialized) + return (initialized > 0); + + if (dbus_bus_request_name (a11y_bus, "org.a11y.Atspi.ScreenReader", 0, NULL) < 0) + { + initialized = -1; + return FALSE; + } + + initialized = 1; + dbus_connection_add_filter (a11y_bus, screen_reader_filter, NULL, NULL); + return TRUE; +}