2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2008 Codethink Ltd.
6 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.,
7 * Copyright 2001, 2002, 2003 Ximian, Inc.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 #include "dbus/dbus-glib-lowlevel.h"
29 #include <X11/Xatom.h>
36 #include <atk/atkobject.h>
37 #include <atk/atknoopobject.h>
38 #include "accessible.h"
42 void spi_atk_register_event_listeners (void);
43 void spi_atk_deregister_event_listeners (void);
44 void spi_atk_tidy_windows (void);
46 /*---------------------------------------------------------------------------*/
48 SpiAppData *app_data = NULL;
50 static const AtkMisc *atk_misc = NULL;
52 /*static Display *bridge_display = NULL;*/
54 /*---------------------------------------------------------------------------*/
57 * Returns a 'canonicalized' value for DISPLAY,
58 * with the screen number stripped off if present.
60 * Not currently used in D-Bus version but may be
61 * useful in future if we make use of XAtom.
65 spi_display_name (void)
67 static const char *canonical_display_name = NULL;
68 if (!canonical_display_name)
70 const gchar *display_env = g_getenv ("AT_SPI_DISPLAY");
73 display_env = g_getenv ("DISPLAY");
74 if (!display_env || !display_env[0])
75 canonical_display_name = ":0";
78 gchar *display_p, *screen_p;
79 canonical_display_name = g_strdup (display_env);
80 display_p = strrchr (canonical_display_name, ':');
81 screen_p = strrchr (canonical_display_name, '.');
82 if (screen_p && display_p && (screen_p > display_p))
90 canonical_display_name = display_env;
93 return canonical_display_name;
97 /*---------------------------------------------------------------------------*/
100 * Gets the IOR from the XDisplay.
101 * Not currently used in D-Bus version, but something similar
102 * may be employed in the future for accessing the registry daemon
107 spi_atk_bridge_get_registry_ior (void)
112 unsigned char *data = NULL;
113 unsigned long nitems;
114 unsigned long leftover;
116 bridge_display = XOpenDisplay (spi_display_name ());
118 AT_SPI_IOR = XInternAtom (bridge_display, "AT_SPI_IOR", False);
119 XGetWindowProperty(bridge_display,
120 XDefaultRootWindow (bridge_display),
123 (Atom) 31, &actual_type, &actual_format,
124 &nitems, &leftover, &data);
126 g_warning (_("AT_SPI_REGISTRY was not started at session startup."));
127 return (gchar *) data;
131 /*---------------------------------------------------------------------------*/
134 register_application (SpiAppData *app)
136 DBusMessage *message;
137 DBusMessageIter iter;
141 dbus_error_init (&error);
143 message = dbus_message_new_method_call (SPI_DBUS_NAME_REGISTRY,
144 SPI_DBUS_PATH_REGISTRY,
145 SPI_DBUS_INTERFACE_REGISTRY,
146 "registerApplication");
147 dbus_message_set_no_reply (message, TRUE);
149 uname = dbus_bus_get_unique_name(app->droute.bus);
151 dbus_message_iter_init_append(message, &iter);
152 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uname);
153 dbus_connection_send (app->droute.bus, message, NULL);
154 if (message) dbus_message_unref (message);
157 /*---------------------------------------------------------------------------*/
160 deregister_application (SpiAppData *app)
162 DBusMessage *message;
163 DBusMessageIter iter;
167 dbus_error_init (&error);
169 message = dbus_message_new_method_call (SPI_DBUS_NAME_REGISTRY,
170 SPI_DBUS_PATH_REGISTRY,
171 SPI_DBUS_INTERFACE_REGISTRY,
172 "deregisterApplication");
173 dbus_message_set_no_reply (message, TRUE);
175 uname = dbus_bus_get_unique_name(app->droute.bus);
177 dbus_message_iter_init_append(message, &iter);
178 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &uname);
179 dbus_connection_send (app->droute.bus, message, NULL);
180 if (message) dbus_message_unref (message);
183 /*---------------------------------------------------------------------------*/
193 spi_atk_tidy_windows ();
194 spi_atk_deregister_event_listeners();
195 deregister_application (app_data);
200 /* Not currently creating an XDisplay */
203 XCloseDisplay (bridge_display);
207 /*---------------------------------------------------------------------------*/
209 static DBusObjectPathVTable droute_vtable =
213 NULL, NULL, NULL, NULL
216 static gchar *atspi_dbus_name;
217 static gboolean atspi_no_register;
219 static GOptionEntry atspi_option_entries[] =
221 {"atspi-dbus-name", 0, 0, G_OPTION_ARG_STRING, &atspi_dbus_name, "D-Bus bus name to register as", NULL},
222 {"atspi-no-register", 0, 0, G_OPTION_ARG_NONE, &atspi_no_register, "Do not register with Registry Daemon", NULL},
229 * The following needs to be initialized.
231 * - DRoute for routing message to their accessible objects.
232 * - Event handlers for emmitting signals on specific ATK events.
233 * - Application registration with the AT-SPI registry.
237 adaptor_init (gint *argc, gchar **argv[])
243 if (app_data != NULL)
246 /* Parse command line options */
247 opt = g_option_context_new(NULL);
248 g_option_context_add_main_entries(opt, atspi_option_entries, NULL);
249 g_option_context_set_ignore_unknown_options(opt, TRUE);
250 if (!g_option_context_parse(opt, argc, argv, &err))
251 g_warning("AT-SPI Option parsing failed: %s\n", err->message);
253 /* Allocate global data and do ATK initializations */
254 app_data = g_new0 (SpiAppData, 1);
255 atk_misc = atk_misc_get_instance ();
257 /* Get D-Bus connection, register D-Bus name*/
258 dbus_error_init (&error);
259 app_data->root = atk_get_root();
260 app_data->droute.bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
261 if (!app_data->droute.bus)
263 g_warning ("AT-SPI Couldn't connect to D-Bus: %s\n", error.message);
268 if (atspi_dbus_name != NULL &&
269 dbus_bus_request_name(app_data->droute.bus, atspi_dbus_name, 0, &error))
271 g_print("AT-SPI Recieved D-Bus name - %s\n", atspi_dbus_name);
274 /* Finish setting up D-Bus */
275 dbus_connection_setup_with_g_main(app_data->droute.bus, g_main_context_default());
277 /* Register droute for routing AT-SPI messages */
278 spi_register_tree_object(app_data->droute.bus, &app_data->droute, "/org/freedesktop/atspi/tree");
280 if (!dbus_connection_register_fallback (app_data->droute.bus,
281 "/org/freedesktop/atspi/accessible",
285 g_warning("AT-SPI Couldn't register droute.\n");
291 /* Register all interfaces with droute and set up application accessible db */
292 atk_dbus_initialize (&app_data->droute);
294 /* Register methods to send D-Bus signals on certain ATK events */
295 spi_atk_register_event_listeners ();
297 /* Register this app by sending a signal out to AT-SPI registry daemon */
298 register_application (app_data);
300 g_atexit (exit_func);
305 /*---------------------------------------------------------------------------*/
308 gtk_module_init (gint *argc, gchar **argv[])
310 return adaptor_init (argc, argv);
313 /*END------------------------------------------------------------------------*/