X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=blobdiff_plain;f=atk-adaptor%2Fbridge.c;h=cb14c8a6c98696db42d8c0e393f51d90c69e73de;hp=08288fd27a21e0e6e9d7f8c7d2ff2d2ab8b521c0;hb=62ef943cbe84b8293bd99910a6a01d432d122eb5;hpb=01fb83c0ba436a54fd5450c04b8511b2409b90e2 diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c index 08288fd..cb14c8a 100644 --- a/atk-adaptor/bridge.c +++ b/atk-adaptor/bridge.c @@ -31,27 +31,25 @@ #include #include #include +#include #include #include #include "bridge.h" #include "event.h" -#include "accessible-register.h" #include "adaptors.h" +#include "object.h" -#include "common/spi-dbus.h" +#include "accessible-register.h" +#include "accessible-leasing.h" +#include "accessible-cache.h" -/* - * Provides the path for the introspection directory. - */ -#if !defined ATSPI_INTROSPECTION_PATH - #error "No introspection XML directory defined" -#endif +#include "common/spi-dbus.h" /*---------------------------------------------------------------------------*/ -SpiAppData *atk_adaptor_app_data = NULL; +SpiBridge *spi_global_app_data = NULL; static const AtkMisc *atk_misc = NULL; @@ -64,36 +62,36 @@ static const AtkMisc *atk_misc = NULL; * with the screen number stripped off if present. * */ -static const gchar* +static const gchar * spi_display_name (void) { - static const char *canonical_display_name = NULL; - if (!canonical_display_name) - { - const gchar *display_env = g_getenv ("AT_SPI_DISPLAY"); - if (!display_env) - { - display_env = g_getenv ("DISPLAY"); - if (!display_env || !display_env[0]) - canonical_display_name = ":0"; - else - { - gchar *display_p, *screen_p; - canonical_display_name = g_strdup (display_env); - display_p = strrchr (canonical_display_name, ':'); - screen_p = strrchr (canonical_display_name, '.'); - if (screen_p && display_p && (screen_p > display_p)) - { - *screen_p = '\0'; - } - } - } - else - { - canonical_display_name = display_env; - } - } - return canonical_display_name; + static const char *canonical_display_name = NULL; + if (!canonical_display_name) + { + const gchar *display_env = g_getenv ("AT_SPI_DISPLAY"); + if (!display_env) + { + display_env = g_getenv ("DISPLAY"); + if (!display_env || !display_env[0]) + canonical_display_name = ":0"; + else + { + gchar *display_p, *screen_p; + canonical_display_name = g_strdup (display_env); + display_p = strrchr (canonical_display_name, ':'); + screen_p = strrchr (canonical_display_name, '.'); + if (screen_p && display_p && (screen_p > display_p)) + { + *screen_p = '\0'; + } + } + } + else + { + canonical_display_name = display_env; + } + } + return canonical_display_name; } /*---------------------------------------------------------------------------*/ @@ -108,89 +106,137 @@ spi_display_name (void) static DBusConnection * spi_atk_bridge_get_bus (void) { - Atom AT_SPI_BUS; - Atom actual_type; - Display *bridge_display; - int actual_format; - unsigned char *data = NULL; - unsigned long nitems; - unsigned long leftover; - - 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_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: 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; + Atom AT_SPI_BUS; + Atom actual_type; + Display *bridge_display; + int actual_format; + unsigned char *data = NULL; + unsigned long nitems; + unsigned long leftover; + + 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_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: 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", error.message); + } + } + + return bus; +} + +static void +set_reply (DBusPendingCall *pending, void *user_data) +{ + void **replyptr = (void **)user_data; + + *replyptr = dbus_pending_call_steal_reply (pending); } +static DBusMessage * +send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, DBusError *error) +{ + DBusPendingCall *pending; + DBusMessage *reply = NULL; + + if (!dbus_connection_send_with_reply (bus, message, &pending, -1)) + { + return NULL; + } + dbus_pending_call_set_notify (pending, set_reply, (void *)&reply, NULL); + while (!reply) + { + if (!dbus_connection_read_write_dispatch (bus, -1)) return NULL; + } + return reply; +} /*---------------------------------------------------------------------------*/ -static void -register_application (SpiAppData *app) +static gboolean +register_application (SpiBridge * app) { - DBusMessage *message; + DBusMessage *message, *reply; DBusMessageIter iter; DBusError error; - 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"); - dbus_message_set_no_reply (message, TRUE); + SPI_DBUS_PATH_ROOT, + SPI_DBUS_INTERFACE_SOCKET, + "Embed"); + + dbus_message_iter_init_append (message, &iter); + spi_object_append_reference (&iter, app->root); + + reply = send_and_allow_reentry (app->bus, message, &error); - uname = dbus_bus_get_unique_name(app->bus); - if (!uname) - { - g_error ("AT-SPI: Couldn't get unique name for this connection"); - } + if (message) + dbus_message_unref (message); - dbus_message_iter_init_append(message, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uname); - dbus_connection_send (app->bus, message, NULL); - if (message) dbus_message_unref (message); + if (reply) + { + DBusMessageIter iter, iter_struct; + gchar *app_name, *obj_path; + + if (strcmp (dbus_message_get_signature (reply), "(so)") != 0) + { + g_warning ("AT-SPI: Could not obtain desktop path or name\n"); + return FALSE; + } + + dbus_message_iter_init (reply, &iter); + dbus_message_iter_recurse (&iter, &iter_struct); + dbus_message_iter_get_basic (&iter_struct, &app_name); + dbus_message_iter_next (&iter_struct); + dbus_message_iter_get_basic (&iter_struct, &obj_path); + + app->desktop_name = g_strdup (app_name); + app->desktop_path = g_strdup (obj_path); + } + else + { + g_warning ("AT-SPI: Could not embed inside desktop: %s\n", error.message); + return FALSE; + } + return TRUE; } /*---------------------------------------------------------------------------*/ static void -deregister_application (SpiAppData *app) +deregister_application (SpiBridge * app) { DBusMessage *message; DBusMessageIter iter; @@ -205,12 +251,13 @@ deregister_application (SpiAppData *app) "DeregisterApplication"); dbus_message_set_no_reply (message, TRUE); - uname = dbus_bus_get_unique_name(app->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_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &uname); dbus_connection_send (app->bus, message, NULL); - if (message) dbus_message_unref (message); + if (message) + dbus_message_unref (message); } /*---------------------------------------------------------------------------*/ @@ -218,17 +265,17 @@ deregister_application (SpiAppData *app) static void exit_func (void) { - if (!atk_adaptor_app_data) + if (!spi_global_app_data) { return; } spi_atk_tidy_windows (); - spi_atk_deregister_event_listeners(); - deregister_application (atk_adaptor_app_data); + spi_atk_deregister_event_listeners (); + deregister_application (spi_global_app_data); - g_free(atk_adaptor_app_data); - atk_adaptor_app_data = NULL; + g_free (spi_global_app_data); + spi_global_app_data = NULL; /* Not currently creating an XDisplay */ #if 0 @@ -239,32 +286,30 @@ exit_func (void) /*---------------------------------------------------------------------------*/ -#ifdef __ATK_PLUG_H__ static AtkPlugClass *plug_class; static AtkSocketClass *socket_class; static gchar * -get_plug_id (AtkPlug *plug) +get_plug_id (AtkPlug * plug) { - const char *uname = dbus_bus_get_unique_name(atk_adaptor_app_data->bus); + const char *uname = dbus_bus_get_unique_name (spi_global_app_data->bus); gchar *path; GString *str = g_string_new (NULL); - path = atk_dbus_object_to_path (ATK_OBJECT(plug), TRUE); + path = spi_register_object_to_path (spi_global_register, G_OBJECT (plug)); 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) +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); + gchar *path = spi_register_object_to_path (spi_global_register, G_OBJECT (accessible)); /* Let the plug know that it has been embedded */ plug_name = g_strdup (plug_id); if (!plug_name) @@ -277,9 +322,9 @@ socket_embed_hook (AtkSocket *socket, gchar *plug_id) { DBusMessage *message; *(plug_path++) = '\0'; - message = dbus_message_new_method_call (plug_name, plug_path, "org.freedesktop.atspi.Accessible", "Embedded"); + message = dbus_message_new_method_call (plug_name, plug_path, SPI_DBUS_INTERFACE_SOCKET, "Embedded"); dbus_message_append_args (message, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); - dbus_connection_send (atk_adaptor_app_data->bus, message, NULL); + dbus_connection_send (spi_global_app_data->bus, message, NULL); } g_free (plug_name); g_free (path); @@ -289,7 +334,7 @@ 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); @@ -297,15 +342,15 @@ install_plug_hooks () 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[] = -{ - {"atspi-dbus-name", 0, 0, G_OPTION_ARG_STRING, &atspi_dbus_name, "D-Bus bus name to register as", NULL}, - {"atspi-no-register", 0, 0, G_OPTION_ARG_NONE, &atspi_no_register, "Do not register with Registry Daemon", NULL}, +static GOptionEntry atspi_option_entries[] = { + {"atspi-dbus-name", 0, 0, G_OPTION_ARG_STRING, &atspi_dbus_name, + "D-Bus bus name to register as", NULL}, + {"atspi-no-register", 0, 0, G_OPTION_ARG_NONE, &atspi_no_register, + "Do not register with Registry Daemon", NULL}, {NULL} }; @@ -320,7 +365,7 @@ static GOptionEntry atspi_option_entries[] = * */ static int -adaptor_init (gint *argc, gchar **argv[]) +adaptor_init (gint * argc, gchar ** argv[]) { GOptionContext *opt; GError *err = NULL; @@ -341,64 +386,82 @@ adaptor_init (gint *argc, gchar **argv[]) g_return_val_if_fail (root, 0); /* Parse command line options */ - opt = g_option_context_new(NULL); - g_option_context_add_main_entries(opt, atspi_option_entries, NULL); - g_option_context_set_ignore_unknown_options(opt, TRUE); - if (!g_option_context_parse(opt, argc, argv, &err)) - g_warning("AT-SPI Option parsing failed: %s\n", err->message); + opt = g_option_context_new (NULL); + g_option_context_add_main_entries (opt, atspi_option_entries, NULL); + g_option_context_set_ignore_unknown_options (opt, TRUE); + if (!g_option_context_parse (opt, argc, argv, &err)) + g_warning ("AT-SPI Option parsing failed: %s\n", err->message); /* Allocate global data and do ATK initializations */ - atk_adaptor_app_data = g_new0 (SpiAppData, 1); + spi_global_app_data = g_new0 (SpiBridge, 1); atk_misc = atk_misc_get_instance (); - atk_adaptor_app_data->root = root; + spi_global_app_data->root = g_object_ref (root); /* Set up D-Bus connection and register bus name */ dbus_error_init (&error); - atk_adaptor_app_data->bus = spi_atk_bridge_get_bus (); - if (!atk_adaptor_app_data->bus) - { - g_free(atk_adaptor_app_data); - atk_adaptor_app_data = NULL; - return 0; - } - - if (atspi_dbus_name != NULL) - { - if (dbus_bus_request_name(atk_adaptor_app_data->bus, atspi_dbus_name, 0, &error)) + spi_global_app_data->bus = spi_atk_bridge_get_bus (); + if (!spi_global_app_data->bus) { - g_print("AT-SPI Recieved D-Bus name - %s\n", atspi_dbus_name); + g_free (spi_global_app_data); + spi_global_app_data = NULL; + return 0; } - else + + if (atspi_dbus_name != NULL) { - g_print("AT-SPI D-Bus name requested but could not be allocated - %s\n", atspi_dbus_name); + if (dbus_bus_request_name + (spi_global_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); + } } - } - dbus_connection_setup_with_g_main(atk_adaptor_app_data->bus, g_main_context_default()); + dbus_connection_setup_with_g_main (spi_global_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; + /* Hook our plug-and socket functions */ + install_plug_hooks (); + + /* + * Create the leasing, register and cache objects. + * The order is important here, the cache depends on the + * register object. + */ + spi_global_register = g_object_new (SPI_REGISTER_TYPE, NULL); + spi_global_leasing = g_object_new (SPI_LEASING_TYPE, NULL); + spi_global_cache = g_object_new (SPI_CACHE_TYPE, NULL); /* Register droute for routing AT-SPI messages */ - atk_adaptor_app_data->droute = droute_new (atk_adaptor_app_data->bus, introspection_directory); + spi_global_app_data->droute = + droute_new (spi_global_app_data->bus); - treepath = droute_add_one (atk_adaptor_app_data->droute, - "/org/freedesktop/atspi/tree", - NULL); + treepath = droute_add_one (spi_global_app_data->droute, + "/org/a11y/atspi/cache", spi_global_cache); - accpath = droute_add_many (atk_adaptor_app_data->droute, - "/org/freedesktop/atspi/accessible", + if (!treepath) + { + g_warning ("atk-bridge: Error in droute_add_one(). Already running?"); + return 0; + } + + accpath = droute_add_many (spi_global_app_data->droute, + "/org/a11y/atspi/accessible", NULL, - (DRouteGetDatumFunction) atk_dbus_path_to_gobject); + (DRouteGetDatumFunction) + spi_global_register_path_to_object); - /* Register all interfaces with droute and set up application accessible db */ - spi_initialize_tree (treepath); + /* Register all interfaces with droute and set up application accessible db */ + spi_initialize_cache (treepath); spi_initialize_accessible (accpath); spi_initialize_application (accpath); - spi_initialize_action(accpath); + spi_initialize_action (accpath); spi_initialize_collection (accpath); spi_initialize_component (accpath); spi_initialize_document (accpath); @@ -407,24 +470,17 @@ adaptor_init (gint *argc, gchar **argv[]) spi_initialize_hypertext (accpath); spi_initialize_image (accpath); spi_initialize_selection (accpath); + spi_initialize_socket (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 */ - if (!atspi_no_register) - register_application (atk_adaptor_app_data); + if (!atspi_no_register && (!root || !ATK_IS_PLUG (root))) + register_application (spi_global_app_data); g_atexit (exit_func); @@ -434,13 +490,13 @@ adaptor_init (gint *argc, gchar **argv[]) /*---------------------------------------------------------------------------*/ int -gtk_module_init (gint *argc, gchar **argv[]) +gtk_module_init (gint * argc, gchar ** 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 adaptor_init (argc, argv); } return 0; } @@ -456,7 +512,7 @@ gnome_accessibility_module_init (void) if (g_getenv ("AT_SPI_DEBUG")) { - g_print("Atk Accessibility bridge initialized\n"); + g_print ("Atk Accessibility bridge initialized\n"); } } } @@ -467,4 +523,5 @@ gnome_accessibility_module_shutdown (void) spi_atk_deregister_event_listeners (); exit_func (); } + /*END------------------------------------------------------------------------*/