X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=atk-adaptor%2Fbridge.c;h=08288fd27a21e0e6e9d7f8c7d2ff2d2ab8b521c0;hb=01fb83c0ba436a54fd5450c04b8511b2409b90e2;hp=3e5fba4d22dea3b9b0fe18a3b66503cfeaca3b6e;hpb=f01ffde94695198fe9e68df3b07eea59d563c495;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c index 3e5fba4..08288fd 100644 --- a/atk-adaptor/bridge.c +++ b/atk-adaptor/bridge.c @@ -2,7 +2,7 @@ * AT-SPI - Assistive Technology Service Provider Interface * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) * - * Copyright 2008 Codethink Ltd. + * Copyright 2008, 2009 Codethink Ltd. * Copyright 2001, 2002, 2003 Sun Microsystems Inc., * Copyright 2001, 2002, 2003 Ximian, Inc. * @@ -27,25 +27,31 @@ #include #include -#include -#include #include #include +#include #include #include -#include -#include -#include "accessible.h" + +#include + #include "bridge.h" -#include "atk-dbus.h" +#include "event.h" +#include "accessible-register.h" +#include "adaptors.h" -void spi_atk_register_event_listeners (void); -void spi_atk_deregister_event_listeners (void); -void spi_atk_tidy_windows (void); +#include "common/spi-dbus.h" + +/* + * Provides the path for the introspection directory. + */ +#if !defined ATSPI_INTROSPECTION_PATH + #error "No introspection XML directory defined" +#endif /*---------------------------------------------------------------------------*/ -SpiAppData *app_data = NULL; +SpiAppData *atk_adaptor_app_data = NULL; static const AtkMisc *atk_misc = NULL; @@ -57,10 +63,7 @@ static const AtkMisc *atk_misc = NULL; * Returns a 'canonicalized' value for DISPLAY, * with the screen number stripped off if present. * - * Not currently used in D-Bus version but may be - * useful in future if we make use of XAtom. */ -#if 0 static const gchar* spi_display_name (void) { @@ -92,7 +95,6 @@ spi_display_name (void) } return canonical_display_name; } -#endif /*---------------------------------------------------------------------------*/ @@ -102,31 +104,58 @@ spi_display_name (void) * may be employed in the future for accessing the registry daemon * bus name. */ -#if 0 -static gchar * -spi_atk_bridge_get_registry_ior (void) + +static DBusConnection * +spi_atk_bridge_get_bus (void) { - Atom AT_SPI_IOR; + Atom AT_SPI_BUS; Atom actual_type; + Display *bridge_display; int actual_format; unsigned char *data = NULL; unsigned long nitems; unsigned long leftover; - if (!bridge_display) - bridge_display = XOpenDisplay (spi_display_name ()); - AT_SPI_IOR = XInternAtom (bridge_display, "AT_SPI_IOR", False); + DBusConnection *bus = NULL; + DBusError error; + + bridge_display = XOpenDisplay (spi_display_name ()); + if (!bridge_display) + g_error ("AT_SPI: Could not get the display\n"); + + AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False); XGetWindowProperty(bridge_display, XDefaultRootWindow (bridge_display), - AT_SPI_IOR, 0L, + AT_SPI_BUS, 0L, (long)BUFSIZ, False, (Atom) 31, &actual_type, &actual_format, &nitems, &leftover, &data); + + dbus_error_init (&error); + if (data == NULL) - g_warning (_("AT_SPI_REGISTRY was not started at session startup.")); - return (gchar *) data; + { + g_warning ("AT-SPI: Accessibility bus not found - Using session bus.\n"); + bus = dbus_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + g_error ("AT-SPI: Couldn't connect to bus: %s\n", error.message); + } + else + { + bus = dbus_connection_open (data, &error); + if (!bus) + { + g_error ("AT-SPI: Couldn't connect to bus: %s\n", error.message); + } + else + { + if (!dbus_bus_register (bus, &error)) + g_error ("AT-SPI: Couldn't register with bus: %s\n"); + } + } + + return bus; } -#endif /*---------------------------------------------------------------------------*/ @@ -136,21 +165,25 @@ register_application (SpiAppData *app) DBusMessage *message; DBusMessageIter iter; DBusError error; - const char *uname; + const char *uname = NULL; dbus_error_init (&error); message = dbus_message_new_method_call (SPI_DBUS_NAME_REGISTRY, SPI_DBUS_PATH_REGISTRY, SPI_DBUS_INTERFACE_REGISTRY, - "registerApplication"); + "RegisterApplication"); dbus_message_set_no_reply (message, TRUE); - uname = dbus_bus_get_unique_name(app->droute.bus); + uname = dbus_bus_get_unique_name(app->bus); + if (!uname) + { + g_error ("AT-SPI: Couldn't get unique name for this connection"); + } dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uname); - dbus_connection_send (app->droute.bus, message, NULL); + dbus_connection_send (app->bus, message, NULL); if (message) dbus_message_unref (message); } @@ -169,14 +202,14 @@ deregister_application (SpiAppData *app) message = dbus_message_new_method_call (SPI_DBUS_NAME_REGISTRY, SPI_DBUS_PATH_REGISTRY, SPI_DBUS_INTERFACE_REGISTRY, - "deregisterApplication"); + "DeregisterApplication"); dbus_message_set_no_reply (message, TRUE); - uname = dbus_bus_get_unique_name(app->droute.bus); + uname = dbus_bus_get_unique_name(app->bus); dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uname); - dbus_connection_send (app->droute.bus, message, NULL); + dbus_connection_send (app->bus, message, NULL); if (message) dbus_message_unref (message); } @@ -185,17 +218,17 @@ deregister_application (SpiAppData *app) static void exit_func (void) { - if (!app_data) + if (!atk_adaptor_app_data) { return; } spi_atk_tidy_windows (); spi_atk_deregister_event_listeners(); - deregister_application (app_data); + deregister_application (atk_adaptor_app_data); - g_free(app_data); - app_data = NULL; + g_free(atk_adaptor_app_data); + atk_adaptor_app_data = NULL; /* Not currently creating an XDisplay */ #if 0 @@ -206,15 +239,68 @@ exit_func (void) /*---------------------------------------------------------------------------*/ -static DBusObjectPathVTable droute_vtable = +#ifdef __ATK_PLUG_H__ +static AtkPlugClass *plug_class; +static AtkSocketClass *socket_class; + +static gchar * +get_plug_id (AtkPlug *plug) { - NULL, - &droute_message, - NULL, NULL, NULL, NULL -}; + const char *uname = dbus_bus_get_unique_name(atk_adaptor_app_data->bus); + gchar *path; + GString *str = g_string_new (NULL); + + path = atk_dbus_object_to_path (ATK_OBJECT(plug), TRUE); + g_string_printf (str, "%s:%s", uname, path); + g_free (path); + return g_string_free (str, FALSE); +} + +static void +socket_embed_hook (AtkSocket *socket, gchar *plug_id) +{ + AtkObject *accessible = ATK_OBJECT(socket); + gchar *plug_name, *plug_path; + + /* Force registration */ + gchar *path = atk_dbus_object_to_path (accessible, TRUE); + spi_emit_cache_update (accessible, atk_adaptor_app_data->bus); + /* Let the plug know that it has been embedded */ + plug_name = g_strdup (plug_id); + if (!plug_name) + { + g_free (path); + return; + } + plug_path = g_utf8_strchr (plug_name + 1, -1, ':'); + if (plug_path) + { + DBusMessage *message; + *(plug_path++) = '\0'; + message = dbus_message_new_method_call (plug_name, plug_path, "org.freedesktop.atspi.Accessible", "Embedded"); + dbus_message_append_args (message, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); + dbus_connection_send (atk_adaptor_app_data->bus, message, NULL); + } + g_free (plug_name); + g_free (path); +} -static gchar *atspi_dbus_name; -static gboolean atspi_no_register; +static void +install_plug_hooks () +{ + gpointer data; + + data = g_type_class_ref (ATK_TYPE_PLUG); + plug_class = ATK_PLUG_CLASS (data); + data = g_type_class_ref (ATK_TYPE_SOCKET); + socket_class = ATK_SOCKET_CLASS (data); + plug_class->get_object_id = get_plug_id; + socket_class->embed = socket_embed_hook; +} +#endif + +gchar *atspi_dbus_name = NULL; +static gboolean atspi_no_register = FALSE; static GOptionEntry atspi_option_entries[] = { @@ -239,9 +325,20 @@ adaptor_init (gint *argc, gchar **argv[]) GOptionContext *opt; GError *err = NULL; DBusError error; + DBusConnection *bus; + AtkObject *root; + gchar *introspection_directory; + static gboolean inited = FALSE; + + if (inited) + return 0; + + inited = TRUE; + + DRoutePath *treepath, *accpath; - if (app_data != NULL) - return 0; + root = atk_get_root (); + g_return_val_if_fail (root, 0); /* Parse command line options */ opt = g_option_context_new(NULL); @@ -251,51 +348,83 @@ adaptor_init (gint *argc, gchar **argv[]) g_warning("AT-SPI Option parsing failed: %s\n", err->message); /* Allocate global data and do ATK initializations */ - app_data = g_new0 (SpiAppData, 1); + atk_adaptor_app_data = g_new0 (SpiAppData, 1); atk_misc = atk_misc_get_instance (); + atk_adaptor_app_data->root = root; - /* Get D-Bus connection, register D-Bus name*/ + /* Set up D-Bus connection and register bus name */ dbus_error_init (&error); - app_data->root = atk_get_root(); - app_data->droute.bus = dbus_bus_get (DBUS_BUS_SESSION, &error); - if (!app_data->droute.bus) + atk_adaptor_app_data->bus = spi_atk_bridge_get_bus (); + if (!atk_adaptor_app_data->bus) { - g_warning ("AT-SPI Couldn't connect to D-Bus: %s\n", error.message); - g_free(app_data); - app_data = NULL; + g_free(atk_adaptor_app_data); + atk_adaptor_app_data = NULL; return 0; } - if (atspi_dbus_name != NULL && - dbus_bus_request_name(app_data->droute.bus, atspi_dbus_name, 0, &error)) + + if (atspi_dbus_name != NULL) { - g_print("AT-SPI Recieved D-Bus name - %s\n", atspi_dbus_name); + if (dbus_bus_request_name(atk_adaptor_app_data->bus, atspi_dbus_name, 0, &error)) + { + g_print("AT-SPI Recieved D-Bus name - %s\n", atspi_dbus_name); + } + else + { + g_print("AT-SPI D-Bus name requested but could not be allocated - %s\n", atspi_dbus_name); + } } - /* Finish setting up D-Bus */ - dbus_connection_setup_with_g_main(app_data->droute.bus, g_main_context_default()); + dbus_connection_setup_with_g_main(atk_adaptor_app_data->bus, g_main_context_default()); + + /* Get D-Bus introspection directory */ + introspection_directory = (char *) g_getenv("ATSPI_INTROSPECTION_PATH"); + if (introspection_directory == NULL) + introspection_directory = ATSPI_INTROSPECTION_PATH; /* Register droute for routing AT-SPI messages */ - spi_register_tree_object(app_data->droute.bus, &app_data->droute, "/org/freedesktop/atspi/tree"); + atk_adaptor_app_data->droute = droute_new (atk_adaptor_app_data->bus, introspection_directory); - if (!dbus_connection_register_fallback (app_data->droute.bus, - "/org/freedesktop/atspi/accessible", - &droute_vtable, - &app_data->droute)) - { - g_warning("AT-SPI Couldn't register droute.\n"); - g_free(app_data); - app_data = NULL; - return 0; - } + treepath = droute_add_one (atk_adaptor_app_data->droute, + "/org/freedesktop/atspi/tree", + NULL); + + accpath = droute_add_many (atk_adaptor_app_data->droute, + "/org/freedesktop/atspi/accessible", + NULL, + (DRouteGetDatumFunction) atk_dbus_path_to_gobject); /* Register all interfaces with droute and set up application accessible db */ - atk_dbus_initialize (&app_data->droute); + spi_initialize_tree (treepath); + + spi_initialize_accessible (accpath); + spi_initialize_application (accpath); + spi_initialize_action(accpath); + spi_initialize_collection (accpath); + spi_initialize_component (accpath); + spi_initialize_document (accpath); + spi_initialize_editabletext (accpath); + spi_initialize_hyperlink (accpath); + spi_initialize_hypertext (accpath); + spi_initialize_image (accpath); + spi_initialize_selection (accpath); + spi_initialize_table (accpath); + spi_initialize_text (accpath); + spi_initialize_value (accpath); + + /* Initialize the AtkObject registration */ + atk_dbus_initialize (atk_adaptor_app_data->root); /* Register methods to send D-Bus signals on certain ATK events */ spi_atk_register_event_listeners (); +#ifdef __ATK_PLUG_H__ + /* Hook our plug-and socket functions */ + install_plug_hooks (); +#endif + /* Register this app by sending a signal out to AT-SPI registry daemon */ - register_application (app_data); + if (!atspi_no_register) + register_application (atk_adaptor_app_data); g_atexit (exit_func); @@ -307,7 +436,35 @@ adaptor_init (gint *argc, gchar **argv[]) int gtk_module_init (gint *argc, gchar **argv[]) { - return adaptor_init (argc, argv); + const gchar *load_bridge = g_getenv ("NO_AT_BRIDGE"); + + if (!load_bridge || g_ascii_strtod (load_bridge, NULL) == 0) + { + return adaptor_init (argc, argv); + } + return 0; } +void +gnome_accessibility_module_init (void) +{ + const gchar *load_bridge = g_getenv ("NO_AT_BRIDGE"); + + if (!load_bridge || g_ascii_strtod (load_bridge, NULL) == 0) + { + adaptor_init (NULL, NULL); + + if (g_getenv ("AT_SPI_DEBUG")) + { + g_print("Atk Accessibility bridge initialized\n"); + } + } +} + +void +gnome_accessibility_module_shutdown (void) +{ + spi_atk_deregister_event_listeners (); + exit_func (); +} /*END------------------------------------------------------------------------*/