[at-spi] Make at-spi-registryd managed by gnome-session.
- From: Li Yuan <liyuan src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [at-spi] Make at-spi-registryd managed by gnome-session.
- Date: Fri, 21 Aug 2009 07:58:34 +0000 (UTC)
commit 22a0d9a3caa235dad52d6cab467d2146bed5dd62
Author: Li Yuan <li yuan sun com>
Date: Fri Aug 21 15:49:43 2009 +0800
Make at-spi-registryd managed by gnome-session.
Bug #578334. Original patch from Tomislav Vujec.
configure.in | 14 ++
po/POTFILES.in | 1 +
po/POTFILES.skip | 2 +
registryd/Makefile.am | 25 +++-
registryd/at-spi-registryd.desktop.in.in.in | 12 ++
registryd/registry-main.c | 251 ++++++++++++++++++++++++++-
6 files changed, 302 insertions(+), 3 deletions(-)
---
diff --git a/configure.in b/configure.in
index b174904..844cee8 100644
--- a/configure.in
+++ b/configure.in
@@ -194,6 +194,19 @@ if test x$enable_xevie = xyes ; then
AC_SUBST(XEVIE_LIBS)
fi
+dnl Allow disabling SMlib
+AC_ARG_ENABLE(sm, [ --enable-sm Enable session management support [default=yes]], enable_sm="$enableval", enable_sm=yes)
+
+if test x$enable_sm = xyes ; then
+ have_sm=
+ AC_CHECK_LIB(SM, SmcSaveYourselfDone, have_sm="yes")
+ if test x$have_sm = xyes ; then
+ SM_LIBS="-lSM -lICE"
+ AC_DEFINE(HAVE_SM, , [Building with SM support])
+ fi
+ AC_SUBST(SM_LIBS)
+fi
+
dnl CFLAGS="$CFLAGS -Wall"
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
@@ -243,6 +256,7 @@ docs/reference/idl/Makefile
idl/Makefile
libspi/Makefile
registryd/Makefile
+registryd/at-spi-registryd.desktop.in.in
atk-bridge/Makefile
login-helper/Makefile
test/Makefile
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 482d3f2..4db7f22 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,3 +2,4 @@
# Please keep this file sorted alphabetically.
at-spi.schemas.in
registryd/Accessibility_Registry.server.in.in
+registryd/at-spi-registryd-wrapper.desktop.in.in.in
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 0357969..3ac70be 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -2,3 +2,5 @@
# Please keep this file sorted alphabetically.
atk-bridge/bridge.c
registryd/Accessibility_Registry.server.in
+registryd/at-spi-registryd-wrapper.desktop.in
+registryd/at-spi-registryd-wrapper.desktop.in.in
diff --git a/registryd/Makefile.am b/registryd/Makefile.am
index 0495b5d..68828db 100644
--- a/registryd/Makefile.am
+++ b/registryd/Makefile.am
@@ -22,12 +22,33 @@ at_spi_registryd_SOURCES = \
registry.h \
ucs2keysym.c
-LDADD = $(top_builddir)/libspi/libspi.la $(X_LIBS) $(XTST_LIBS) $(XEVIE_LIBS) $(REGISTRYD_LIBS)
+LDADD = $(top_builddir)/libspi/libspi.la $(X_LIBS) $(SM_LIBS) $(XTST_LIBS) $(XEVIE_LIBS) $(REGISTRYD_LIBS)
serverinfodir = $(libdir)/bonobo/servers
serverinfo_DATA = Accessibility_Registry.server
+default_sessiondir = $(sysconfdir)/xdg/autostart
+default_session_in_in_files = \
+ at-spi-registryd.desktop.in.in
+default_session_in_files = $(default_session_in_in_files:.desktop.in.in=.desktop.in)
+default_session_DATA = $(default_session_in_files:.desktop.in=.desktop)
+
+ INTLTOOL_DESKTOP_RULE@
+
+%.desktop.in: %.desktop.in.in Makefile.am
+ sed -e "s,\ registryddir\@,$(libexecdir)," \
+ < $< > $@
+
@INTLTOOL_SERVER_RULE@
EXTRA_DIST = Accessibility_Registry.server.in.in
-CLEANFILES = $(serverinfo_DATA) $(server_dot_in)
+CLEANFILES = \
+ $(serverinfo_DATA) \
+ $(server_dot_in) \
+ $(default_session_DATA) \
+ $(default_session_in_files)
+
+DISTCLEANFILES = \
+ $(default_session_in_in_files)
+
+
diff --git a/registryd/at-spi-registryd.desktop.in.in.in b/registryd/at-spi-registryd.desktop.in.in.in
new file mode 100644
index 0000000..0e414a7
--- /dev/null
+++ b/registryd/at-spi-registryd.desktop.in.in.in
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Type=Application
+_Name=AT SPI Registry Wrapper
+Exec= registryddir@/at-spi-registryd
+OnlyShowIn=GNOME;
+NoDisplay=true
+AutostartCondition=GNOME /desktop/gnome/interface/accessibility
+X-GNOME-Autostart-Phase=Initialization
+X-GNOME-Bugzilla-Bugzilla=GNOME
+X-GNOME-Bugzilla-Product=at-spi
+X-GNOME-Bugzilla-Component=general
+X-GNOME-Bugzilla-Version= VERSION@
diff --git a/registryd/registry-main.c b/registryd/registry-main.c
index 1be5b69..bd98740 100644
--- a/registryd/registry-main.c
+++ b/registryd/registry-main.c
@@ -32,9 +32,27 @@
#include <glib.h>
#include "registry.h"
+#ifdef HAVE_SM
+#include <X11/SM/SMlib.h>
+#include <X11/ICE/ICElib.h>
+#include <fcntl.h>
+#endif
+
#define spi_get_display() GDK_DISPLAY()
static void registry_set_ior (SpiRegistry *registry);
+static void registry_session_init (const char *previous_client_id, const char *exe);
+#ifdef HAVE_SM
+static void die_callback (SmcConn smc_conn, SmPointer client_data);
+static void save_yourself_callback (SmcConn smc_conn,
+ SmPointer client_data,
+ int save_style,
+ Bool shutdown,
+ int interact_style,
+ Bool fast);
+
+static SmcConn session_connection;
+#endif
int
main (int argc, char **argv)
@@ -62,7 +80,6 @@ main (int argc, char **argv)
dp = strrchr (display_name, ':');
if (cp && dp && (cp > dp)) *cp = '\0';
}
-
ret = bonobo_activation_register_active_server (
obj_id,
bonobo_object_corba_objref (bonobo_object (registry)),
@@ -80,6 +97,19 @@ main (int argc, char **argv)
fprintf (stderr, "SpiRegistry Message: SpiRegistry daemon is running.\n");
#endif
registry_set_ior (registry);
+
+ /* If DESKTOP_AUTOSTART_ID exists, assume we're started by session
+ * manager and connect to it. */
+ const char *desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+ if (desktop_autostart_id != NULL) {
+ char *client_id = g_strdup (desktop_autostart_id);
+ /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
+ * use the same client id. */
+ g_unsetenv ("DESKTOP_AUTOSTART_ID");
+ registry_session_init (client_id, argv[0]);
+ g_free (client_id);
+ }
+
bonobo_main ();
}
@@ -115,3 +145,222 @@ registry_set_ior (SpiRegistry *registry){
CORBA_exception_free (&ev);
}
+
+#ifdef HAVE_SM
+/* This is called when data is available on an ICE connection. */
+static gboolean
+process_ice_messages (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer client_data)
+{
+ IceConn connection = (IceConn) client_data;
+ IceProcessMessagesStatus status;
+
+ /* This blocks infinitely sometimes. I don't know what
+ * to do about it. Checking "condition" just breaks
+ * session management.
+ */
+ status = IceProcessMessages (connection, NULL, NULL);
+
+ if (status == IceProcessMessagesIOError)
+ {
+#if 0
+ IcePointer context = IceGetConnectionContext (connection);
+#endif
+
+ /* We were disconnected */
+ IceSetShutdownNegotiation (connection, False);
+ IceCloseConnection (connection);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* This is called when a new ICE connection is made. It arranges for
+ the ICE connection to be handled via the event loop. */
+static void
+new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
+ IcePointer *watch_data)
+{
+ guint input_id;
+
+ if (opening)
+ {
+ /* Make sure we don't pass on these file descriptors to any
+ * exec'ed children
+ */
+ GIOChannel *channel;
+
+ fcntl (IceConnectionNumber (connection), F_SETFD,
+ fcntl (IceConnectionNumber (connection), F_GETFD, 0) | FD_CLOEXEC);
+
+ channel = g_io_channel_unix_new (IceConnectionNumber (connection));
+
+ input_id = g_io_add_watch (channel,
+ G_IO_IN | G_IO_ERR,
+ process_ice_messages,
+ connection);
+
+ g_io_channel_unref (channel);
+
+ *watch_data = (IcePointer) GUINT_TO_POINTER (input_id);
+ }
+ else
+ {
+ input_id = GPOINTER_TO_UINT ((gpointer) *watch_data);
+
+ g_source_remove (input_id);
+ }
+}
+
+static IceIOErrorHandler ice_installed_handler;
+
+/* We call any handler installed before (or after) gnome_ice_init but
+ avoid calling the default libICE handler which does an exit() */
+static void
+ice_io_error_handler (IceConn connection)
+{
+ if (ice_installed_handler)
+ (*ice_installed_handler) (connection);
+}
+
+static void
+ice_init (void)
+{
+ static gboolean ice_initted = FALSE;
+
+ if (! ice_initted)
+ {
+ IceIOErrorHandler default_handler;
+
+ ice_installed_handler = IceSetIOErrorHandler (NULL);
+ default_handler = IceSetIOErrorHandler (ice_io_error_handler);
+
+ if (ice_installed_handler == default_handler)
+ ice_installed_handler = NULL;
+
+ IceAddConnectionWatch (new_ice_connection, NULL);
+
+ ice_initted = TRUE;
+ }
+}
+#endif
+
+void
+registry_session_init (const char *previous_client_id, const char *exe)
+{
+#ifdef HAVE_SM
+ char buf[256];
+ char *client_id;
+ unsigned long mask;
+ SmcCallbacks callbacks;
+
+ ice_init();
+
+ callbacks.save_yourself.callback = save_yourself_callback;
+ callbacks.save_yourself.client_data = NULL;
+ callbacks.die.callback = die_callback;
+ callbacks.die.client_data = NULL;
+
+ mask = SmcSaveYourselfProcMask | SmcDieProcMask;
+
+ session_connection =
+ SmcOpenConnection (NULL, /* use SESSION_MANAGER env */
+ NULL, /* means use existing ICE connection */
+ SmProtoMajor,
+ SmProtoMinor,
+ mask,
+ &callbacks,
+ (char*) previous_client_id,
+ &client_id,
+ 255, buf);
+
+ if (session_connection != NULL) {
+ SmProp prop1, prop2, prop3, prop4, prop5, prop6, *props[6];
+ SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val;
+ char pid[32];
+ char hint = SmRestartImmediately;
+ char priority = 1; /* low to run before other apps */
+
+ prop1.name = SmProgram;
+ prop1.type = SmARRAY8;
+ prop1.num_vals = 1;
+ prop1.vals = &prop1val;
+ prop1val.value = exe;
+ prop1val.length = strlen (exe);
+
+ /* twm sets getuid() for this, but the SM spec plainly
+ * says pw_name, twm is on crack
+ */
+ prop2.name = SmUserID;
+ prop2.type = SmARRAY8;
+ prop2.num_vals = 1;
+ prop2.vals = &prop2val;
+ prop2val.value = (char*) g_get_user_name ();
+ prop2val.length = strlen (prop2val.value);
+
+ prop3.name = SmRestartStyleHint;
+ prop3.type = SmCARD8;
+ prop3.num_vals = 1;
+ prop3.vals = &prop3val;
+ prop3val.value = &hint;
+ prop3val.length = 1;
+
+ sprintf (pid, "%d", getpid ());
+ prop4.name = SmProcessID;
+ prop4.type = SmARRAY8;
+ prop4.num_vals = 1;
+ prop4.vals = &prop4val;
+ prop4val.value = pid;
+ prop4val.length = strlen (prop4val.value);
+
+ /* Always start in home directory */
+ prop5.name = SmCurrentDirectory;
+ prop5.type = SmARRAY8;
+ prop5.num_vals = 1;
+ prop5.vals = &prop5val;
+ prop5val.value = (char*) g_get_home_dir ();
+ prop5val.length = strlen (prop5val.value);
+
+ prop6.name = "_GSM_Priority";
+ prop6.type = SmCARD8;
+ prop6.num_vals = 1;
+ prop6.vals = &prop6val;
+ prop6val.value = &priority;
+ prop6val.length = 1;
+
+ props[0] = &prop1;
+ props[1] = &prop2;
+ props[2] = &prop3;
+ props[3] = &prop4;
+ props[4] = &prop5;
+ props[5] = &prop6;
+
+ SmcSetProperties (session_connection, 6, props);
+ }
+
+#endif
+}
+
+#ifdef HAVE_SM
+static void
+die_callback (SmcConn smc_conn, SmPointer client_data)
+{
+ SmcCloseConnection (session_connection, 0, NULL);
+ bonobo_main_quit ();
+}
+
+static void
+save_yourself_callback (SmcConn smc_conn,
+ SmPointer client_data,
+ int save_style,
+ Bool shutdown,
+ int interact_style,
+ Bool fast)
+{
+ SmcSaveYourselfDone (session_connection, TRUE);
+}
+#endif
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]