PageRenderTime 55ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/at-spi-1.32.0/registryd/registry-main.c

#
C | 440 lines | 349 code | 65 blank | 26 comment | 48 complexity | 73e6f2ef9fabb14f3c2b2da0981299e5 MD5 | raw file
Possible License(s): LGPL-2.0
  1. /*
  2. * AT-SPI - Assistive Technology Service Provider Interface
  3. * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
  4. *
  5. * Copyright 2001, 2002 Sun Microsystems Inc.,
  6. * Copyright 2001, 2002 Ximian, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Library General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Library General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Library General Public
  19. * License along with this library; if not, write to the
  20. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21. * Boston, MA 02111-1307, USA.
  22. */
  23. #ifdef AT_SPI_DEBUG
  24. #include <stdlib.h>
  25. #endif
  26. #include <config.h>
  27. #include <string.h>
  28. #include <gdk/gdkx.h>
  29. #include <libbonobo.h>
  30. #include <glib.h>
  31. #include "registry.h"
  32. #include <dbus/dbus-glib.h>
  33. #include <gconf/gconf-client.h>
  34. #define spi_get_display() GDK_DISPLAY()
  35. static void registry_set_ior (SpiRegistry *registry);
  36. #ifdef RELOCATE
  37. static void set_gtk_path (DBusGProxy *gsm);
  38. #endif
  39. static void set_gtk_modules (DBusGProxy *gsm);
  40. #ifdef RELOCATE
  41. #define CORBA_GCONF_KEY "/desktop/gnome/interface/at-spi-corba"
  42. #else
  43. #define DBUS_GCONF_KEY "/desktop/gnome/interface/at-spi-dbus"
  44. #endif
  45. #define SM_DBUS_NAME "org.gnome.SessionManager"
  46. #define SM_DBUS_PATH "/org/gnome/SessionManager"
  47. #define SM_DBUS_INTERFACE "org.gnome.SessionManager"
  48. #define SM_CLIENT_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate"
  49. static DBusGConnection *bus_connection = NULL;
  50. static DBusGProxy *sm_proxy = NULL;
  51. static char *client_id = NULL;
  52. static DBusGProxy *client_proxy = NULL;
  53. static gboolean
  54. session_manager_connect (void)
  55. {
  56. if (bus_connection == NULL) {
  57. GError *error;
  58. error = NULL;
  59. bus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
  60. if (bus_connection == NULL) {
  61. g_message ("Failed to connect to the session bus: %s",
  62. error->message);
  63. g_error_free (error);
  64. exit (1);
  65. }
  66. }
  67. sm_proxy = dbus_g_proxy_new_for_name (bus_connection,
  68. SM_DBUS_NAME,
  69. SM_DBUS_PATH,
  70. SM_DBUS_INTERFACE);
  71. return (sm_proxy != NULL);
  72. }
  73. static void
  74. stop_cb (gpointer data)
  75. {
  76. bonobo_main_quit ();
  77. }
  78. static gboolean
  79. end_session_response (gboolean is_okay, const gchar *reason)
  80. {
  81. gboolean ret;
  82. GError *error = NULL;
  83. ret = dbus_g_proxy_call (client_proxy, "EndSessionResponse",
  84. &error,
  85. G_TYPE_BOOLEAN, is_okay,
  86. G_TYPE_STRING, reason,
  87. G_TYPE_INVALID,
  88. G_TYPE_INVALID);
  89. if (!ret) {
  90. g_warning ("Failed to send session response %s", error->message);
  91. g_error_free (error);
  92. }
  93. return ret;
  94. }
  95. static void
  96. query_end_session_cb (guint flags, gpointer data)
  97. {
  98. end_session_response (TRUE, NULL);
  99. }
  100. static void
  101. end_session_cb (guint flags, gpointer data)
  102. {
  103. Atom AT_SPI_IOR = XInternAtom (spi_get_display (), "AT_SPI_IOR", TRUE);
  104. XDeleteProperty (spi_get_display(),
  105. XDefaultRootWindow (spi_get_display ()),
  106. AT_SPI_IOR);
  107. XFlush (spi_get_display());
  108. end_session_response (TRUE, NULL);
  109. bonobo_main_quit ();
  110. }
  111. static gboolean
  112. register_client (void)
  113. {
  114. GError *error;
  115. gboolean res;
  116. const char *startup_id;
  117. const char *app_id;
  118. startup_id = g_getenv ("DESKTOP_AUTOSTART_ID");
  119. app_id = "at-spi-registryd.desktop";
  120. error = NULL;
  121. res = dbus_g_proxy_call (sm_proxy,
  122. "RegisterClient",
  123. &error,
  124. G_TYPE_STRING, app_id,
  125. G_TYPE_STRING, startup_id,
  126. G_TYPE_INVALID,
  127. DBUS_TYPE_G_OBJECT_PATH, &client_id,
  128. G_TYPE_INVALID);
  129. if (! res) {
  130. g_warning ("Failed to register client: %s", error->message);
  131. g_error_free (error);
  132. return FALSE;
  133. }
  134. g_debug ("Client registered with session manager: %s", client_id);
  135. client_proxy = dbus_g_proxy_new_for_name (bus_connection,
  136. SM_DBUS_NAME,
  137. client_id,
  138. SM_CLIENT_DBUS_INTERFACE);
  139. dbus_g_proxy_add_signal (client_proxy, "Stop", G_TYPE_INVALID);
  140. dbus_g_proxy_connect_signal (client_proxy, "Stop",
  141. G_CALLBACK (stop_cb), NULL, NULL);
  142. dbus_g_proxy_add_signal (client_proxy, "QueryEndSession", G_TYPE_UINT, G_TYPE_INVALID);
  143. dbus_g_proxy_connect_signal (client_proxy, "QueryEndSession",
  144. G_CALLBACK (query_end_session_cb), NULL, NULL);
  145. dbus_g_proxy_add_signal (client_proxy, "EndSession", G_TYPE_UINT, G_TYPE_INVALID);
  146. dbus_g_proxy_connect_signal (client_proxy, "EndSession",
  147. G_CALLBACK (end_session_cb), NULL, NULL);
  148. g_unsetenv ("DESKTOP_AUTOSTART_ID");
  149. return TRUE;
  150. }
  151. int
  152. main (int argc, char **argv)
  153. {
  154. int ret;
  155. char *obj_id;
  156. const char *display_name;
  157. char *cp, *dp;
  158. SpiRegistry *registry;
  159. DBusGConnection *connection;
  160. DBusGProxy *gsm;
  161. GError *error;
  162. GConfClient *gconf_client;
  163. gboolean need_to_quit;
  164. /* If we've been relocated, we will only run if the at-spi-corba gconf key
  165. * has been set. If we have not been relocated, we will exit if the
  166. * at-spi-dbus key has been set.
  167. */
  168. gconf_client = gconf_client_get_default ();
  169. #ifdef RELOCATE
  170. need_to_quit = !gconf_client_get_bool (gconf_client, CORBA_GCONF_KEY, NULL);
  171. #else
  172. need_to_quit = gconf_client_get_bool (gconf_client, DBUS_GCONF_KEY, NULL);
  173. #endif
  174. g_object_unref (gconf_client);
  175. if (need_to_quit)
  176. return 0;
  177. if (!bonobo_init (&argc, argv))
  178. {
  179. g_error ("Could not initialize oaf / Bonobo");
  180. }
  181. obj_id = "OAFIID:Accessibility_Registry:1.0";
  182. registry = spi_registry_new ();
  183. display_name = g_getenv ("AT_SPI_DISPLAY");
  184. if (!display_name)
  185. {
  186. display_name = g_getenv ("DISPLAY");
  187. cp = strrchr (display_name, '.');
  188. dp = strrchr (display_name, ':');
  189. if (cp && dp && (cp > dp)) *cp = '\0';
  190. }
  191. ret = bonobo_activation_register_active_server (
  192. obj_id,
  193. bonobo_object_corba_objref (bonobo_object (registry)),
  194. NULL);
  195. if (ret != Bonobo_ACTIVATION_REG_SUCCESS)
  196. {
  197. #ifdef AT_SPI_DEBUG
  198. fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon was already running.\n");
  199. #endif
  200. }
  201. else
  202. {
  203. #ifdef AT_SPI_DEBUG
  204. fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
  205. #endif
  206. error = NULL;
  207. connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
  208. if (connection == NULL)
  209. {
  210. g_error ("couldn't get D-Bus connection: %s", error->message);
  211. }
  212. gsm = dbus_g_proxy_new_for_name (connection,
  213. "org.gnome.SessionManager",
  214. "/org/gnome/SessionManager",
  215. "org.gnome.SessionManager");
  216. #ifdef RELOCATE
  217. set_gtk_path (gsm);
  218. #endif
  219. set_gtk_modules (gsm);
  220. registry_set_ior (registry);
  221. if (!session_manager_connect ())
  222. {
  223. g_warning ("Unable to connect to session manager");
  224. }
  225. if (!register_client ())
  226. {
  227. g_warning ("Unable to register client with session manager");
  228. }
  229. bonobo_main ();
  230. }
  231. return 0;
  232. }
  233. static void
  234. registry_set_ior (SpiRegistry *registry){
  235. CORBA_Environment ev;
  236. Atom AT_SPI_IOR = XInternAtom (spi_get_display (), "AT_SPI_IOR", FALSE);
  237. char *iorstring = NULL;
  238. CORBA_exception_init (&ev);
  239. iorstring = CORBA_ORB_object_to_string (bonobo_activation_orb_get (),
  240. bonobo_object_corba_objref (bonobo_object (registry)),
  241. &ev);
  242. XChangeProperty (spi_get_display(),
  243. XDefaultRootWindow (spi_get_display ()),
  244. AT_SPI_IOR, (Atom) 31, 8,
  245. PropModeReplace,
  246. (unsigned char *) iorstring,
  247. iorstring ? strlen (iorstring) : 0);
  248. if (ev._major != CORBA_NO_EXCEPTION)
  249. {
  250. g_error ("Error setting IOR %s",
  251. CORBA_exception_id (&ev));
  252. CORBA_exception_free (&ev);
  253. }
  254. CORBA_exception_free (&ev);
  255. }
  256. #ifdef RELOCATE
  257. static void
  258. set_gtk_path (DBusGProxy *gsm)
  259. {
  260. const char *old;
  261. char *corba_path;
  262. char *value;
  263. gboolean found;
  264. GError *error;
  265. int i, j;
  266. corba_path = g_build_filename (GTK_LIBDIR,
  267. "gtk-2.0",
  268. "modules",
  269. "at-spi-corba",
  270. NULL);
  271. old = g_getenv ("GTK_PATH");
  272. if (old != NULL) {
  273. char **old_path;
  274. char **path;
  275. old_path = g_strsplit (old, ":", -1);
  276. found = FALSE;
  277. for (i = 0; old_path[i]; i++) {
  278. if (!strcmp (old_path[i], corba_path)) {
  279. found = TRUE;
  280. }
  281. }
  282. path = g_new (char *, i + (found ? 0 : 1) + 1);
  283. if (!found) {
  284. path[0] = corba_path;
  285. for (i = 0; old_path[i]; i++) {
  286. path[i + 1] = old_path[i];
  287. }
  288. path[i + 1] = NULL;
  289. } else {
  290. for (i = 0; old_path[i]; i++) {
  291. path[i] = old_path[i];
  292. }
  293. path[i] = NULL;
  294. }
  295. value = g_strjoinv (":", path);
  296. g_free (path);
  297. g_strfreev (old_path);
  298. } else {
  299. value = g_strdup (corba_path);
  300. }
  301. if (gsm != NULL) {
  302. error = NULL;
  303. if (!dbus_g_proxy_call (gsm, "Setenv", &error,
  304. G_TYPE_STRING, "GTK_PATH",
  305. G_TYPE_STRING, value,
  306. G_TYPE_INVALID,
  307. G_TYPE_INVALID)) {
  308. g_warning ("Could not set GTK_PATH: %s", error->message);
  309. g_error_free (error);
  310. }
  311. } else {
  312. g_setenv ("GTK_PATH", value, TRUE);
  313. }
  314. g_free (value);
  315. g_free (corba_path);
  316. return;
  317. }
  318. #endif
  319. static void
  320. set_gtk_modules (DBusGProxy *gsm)
  321. {
  322. const char *old;
  323. char *value;
  324. gboolean found_gail;
  325. gboolean found_atk_bridge;
  326. GError *error;
  327. int i;
  328. found_gail = FALSE;
  329. found_atk_bridge = FALSE;
  330. old = g_getenv ("GTK_MODULES");
  331. if (old != NULL) {
  332. char **old_modules;
  333. char **modules;
  334. old_modules = g_strsplit (old, ":", -1);
  335. for (i = 0; old_modules[i]; i++) {
  336. if (!strcmp (old_modules[i], "gail")) {
  337. found_gail = TRUE;
  338. } else if (!strcmp (old_modules[i], "atk-bridge")) {
  339. found_atk_bridge = TRUE;
  340. }
  341. }
  342. modules = g_new (char *, i + (found_gail ? 0 : 1) +
  343. (found_atk_bridge ? 0 : 1) + 1);
  344. for (i = 0; old_modules[i]; i++) {
  345. modules[i] = old_modules[i];
  346. }
  347. if (!found_gail) {
  348. modules[i++] = "gail";
  349. }
  350. if (!found_atk_bridge) {
  351. modules[i++] = "atk-bridge";
  352. }
  353. modules[i] = NULL;
  354. value = g_strjoinv (":", modules);
  355. g_free (modules);
  356. g_strfreev (old_modules);
  357. } else {
  358. value = g_strdup ("gail:atk-bridge");
  359. }
  360. if (gsm != NULL) {
  361. error = NULL;
  362. if (!dbus_g_proxy_call (gsm, "Setenv", &error,
  363. G_TYPE_STRING, "GTK_MODULES",
  364. G_TYPE_STRING, value,
  365. G_TYPE_INVALID,
  366. G_TYPE_INVALID)) {
  367. g_warning ("Could not set GTK_MODULES: %s", error->message);
  368. g_error_free (error);
  369. }
  370. } else {
  371. g_setenv ("GTK_MODULES", value, TRUE);
  372. }
  373. g_free (value);
  374. return;
  375. }