2009-06-18 Li Yuan <liyuan@liyuan-desktop.(none)>
authorMark Doffman <mdoff@altair-voyager.(none)>
Wed, 22 Jul 2009 12:50:03 +0000 (13:50 +0100)
committerMark Doffman <mdoff@altair-voyager.(none)>
Wed, 22 Jul 2009 12:50:03 +0000 (13:50 +0100)
        This patch implements DBus activition for atspi-dbus. And also lets
        gnome-session manage at-spi-registryd. Plus some changes merging work.

configure.ac
dbind/Makefile.am
dbind/org.freedesktop.atspi.Registry.service.in [new file with mode: 0644]
registryd/Makefile.am
registryd/at-spi-registryd.desktop.in.in [new file with mode: 0644]
registryd/deviceeventcontroller.c
registryd/deviceeventcontroller.h
registryd/reentrant-list.h
registryd/registry-main.c
spi-common/keymasks.h

index d56aeff..31b3ca4 100644 (file)
@@ -140,6 +140,20 @@ 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
+
+
 AC_ARG_VAR([DEFAULT_ATSPI_INTROSPECTION_PATH],
           [Set the default path for the install ofDBus introspection XML
            relative to the pkgdatadir.])
@@ -153,6 +167,16 @@ if test -z "$GTK_MODULE_DIR"; then
          GTK_MODULE_DIR=gtk-2.0/modules
 fi
 
+AC_ARG_WITH(dbus-services,
+           [AC_HELP_STRING([--with-dbus-services=<dir>],
+           [where D-BUS services directory is])])
+if ! test -z "$with_dbus_services" ; then
+           DBUS_SERVICES_DIR="$with_dbus_services"
+else
+           DBUS_SERVICES_DIR="$datadir/dbus-1/services"
+fi
+AC_SUBST(DBUS_SERVICES_DIR)
+
 dnl find sizes & alignments
 orig_CPPFLAGS=$CPPFLAGS
 CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
@@ -181,6 +205,7 @@ AC_CONFIG_FILES([Makefile
                 droute/Makefile
                 spi-common/Makefile
                 registryd/Makefile
+                registryd/at-spi-registryd.desktop.in.in
                 atk-adaptor/Makefile
                 login-helper/Makefile
                 tests/dummyatk/Makefile
index cc2849e..bd0f314 100644 (file)
@@ -22,3 +22,10 @@ TESTS = dbtest
 check_PROGRAMS = dbtest
 dbtest_SOURCES = dbtest.c
 dbtest_LDFLAGS = libdbind.la
+
+servicedir       = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.atspi.Registry.service.in
+service_DATA     = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+       @sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@
diff --git a/dbind/org.freedesktop.atspi.Registry.service.in b/dbind/org.freedesktop.atspi.Registry.service.in
new file mode 100644 (file)
index 0000000..e1c0151
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.atspi.Registry
+Exec=@LIBEXECDIR@/at-spi-registryd
index 19b745b..6ae2ce2 100644 (file)
@@ -12,6 +12,7 @@ at_spi_registryd_LDADD = $(DBUS_GLIB_LIBS)    \
                         $(ATK_LIBS)            \
                         $(GDK_LIBS)            \
                         $(X_LIBS)              \
+                        $(SM_LIBS)             \
                         $(XTST_LIBS)           \
                         $(XEVIE_LIBS)          \
                         $(top_builddir)/droute/libdroute.la\
@@ -26,3 +27,23 @@ at_spi_registryd_SOURCES =   \
        reentrant-list.c        \
        reentrant-list.h        \
        ucs2keysym.c
+
+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)
+
+%.desktop: %.desktop.in Makefile.am
+       sed -e "s,\@registryddir\@,$(libexecdir)," \
+       < $< > $@
+%.desktop.in: %.desktop.in.in Makefile.am
+       sed -e "s,\@registryddir\@,$(libexecdir)," \
+       < $< > $@
+
+CLEANFILES =                   \
+       $(default_session_DATA) \
+       $(default_session_in_files)
+
+DISTCLEANFILES =               \
+       $(default_session_in_in_files)
diff --git a/registryd/at-spi-registryd.desktop.in.in b/registryd/at-spi-registryd.desktop.in.in
new file mode 100644 (file)
index 0000000..6065e7d
--- /dev/null
@@ -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=1.9.0
index 6b67e78..0f3e158 100644 (file)
@@ -51,7 +51,6 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h> /* TODO: hide dependency (wrap in single porting file) */
 #include <gdk/gdkkeysyms.h>
-#include <gdk/gdkwindow.h>
 
 #include <spi-common/keymasks.h>
 #include <spi-common/spi-dbus.h>
@@ -89,6 +88,9 @@ static unsigned int _numlock_physical_mask = Mod2Mask; /* a guess, will be reset
 static GQuark spi_dec_private_quark = 0;
 static XModifierKeymap* xmkeymap = NULL;
 
+static gboolean have_mouse_listener = FALSE;
+static gboolean have_mouse_event_listener = FALSE;
+
 static int (*x_default_error_handler) (Display *display, XErrorEvent *error_event);
 
 typedef enum {
@@ -602,7 +604,9 @@ spi_dec_poll_mouse_moved (gpointer data)
 static gboolean
 spi_dec_poll_mouse_idle (gpointer data)
 {
-  if (! spi_dec_poll_mouse_moved (data))
+  if (!have_mouse_event_listener && !have_mouse_listener)
+    return FALSE;
+  else if (!spi_dec_poll_mouse_moved (data))
     return TRUE;
   else
     {
@@ -614,7 +618,9 @@ spi_dec_poll_mouse_idle (gpointer data)
 static gboolean
 spi_dec_poll_mouse_moving (gpointer data)
 {
-  if (spi_dec_poll_mouse_moved (data))
+  if (!have_mouse_event_listener && !have_mouse_listener)
+    return FALSE;
+  else if (spi_dec_poll_mouse_moved (data))
     return TRUE;
   else
     {
@@ -642,10 +648,7 @@ spi_dec_init_mouse_listener (SpiDEController *dec)
 {
 #ifdef GRAB_BUTTON
   Display *display = spi_get_display ();
-#endif
-  g_timeout_add (100, spi_dec_poll_mouse_idle, dec);
 
-#ifdef GRAB_BUTTON
   if (display)
     {
       if (XGrabButton (display, AnyButton, AnyModifier,
@@ -964,6 +967,12 @@ spi_controller_register_device_listener (SpiDEController      *controller,
       break;
   case SPI_DEVICE_TYPE_MOUSE:
       controller->mouse_listeners = g_list_prepend (controller->mouse_listeners, listener);
+      if (!have_mouse_listener)
+        {
+          have_mouse_listener = TRUE;
+          if (!have_mouse_event_listener)
+            g_timeout_add (100, spi_dec_poll_mouse_idle, controller->registry);
+        }
       spi_dbus_add_disconnect_match (controller->bus, listener->bus_name);
       break;
   default:
@@ -1388,7 +1397,9 @@ spi_key_set_contains_key (GSList                          *key_set,
 
   if (!key_set)
     {
+#ifdef SPI_DEBUG
       g_print ("null key set!\n");
+#endif
       return TRUE;
     }
 
@@ -1977,6 +1988,8 @@ spi_controller_deregister_device_listener (SpiDEController            *controlle
 
   spi_re_entrant_list_foreach (&controller->mouse_listeners,
                               remove_listener_cb, &ctx);
+  if (!controller->mouse_listeners)
+    have_mouse_listener = FALSE;
 }
 
 static void
@@ -2780,3 +2793,20 @@ spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus, DRouteContext *drou
 
   return dec;
 }
+
+void
+spi_device_event_controller_start_poll_mouse (SpiRegistry *registry)
+{
+  if (!have_mouse_event_listener)
+    {
+      have_mouse_event_listener = TRUE;
+      if (!have_mouse_listener)
+      g_timeout_add (100, spi_dec_poll_mouse_idle, registry);
+    }
+}
+
+void
+spi_device_event_controller_stop_poll_mouse (void)
+{
+  have_mouse_event_listener = FALSE;
+}
index 392cc5e..e36c193 100644 (file)
@@ -60,6 +60,9 @@ SpiDEController *spi_device_event_controller_new      (SpiRegistry    *registry,
                                                        DBusConnection *bus,
                                                        DRouteContext  *droute);
 
+void spi_device_event_controller_start_poll_mouse (SpiRegistry *registry);
+void spi_device_event_controller_stop_poll_mouse (void);
+
 void spi_remove_device_listeners (SpiDEController *controller, const char *bus_name);
 
 SpiDEController *spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus, DRouteContext *droute);
index 88e37e4..901561b 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef REENTRANT_LIST_H_
 #define REENTRANT_LIST_H_
 
-#include <glib/glist.h>
+#include <glib.h>
 
 G_BEGIN_DECLS
 
index 3b738af..da9e91a 100644 (file)
@@ -24,7 +24,7 @@
 #include <stdlib.h>
 #include <config.h>
 #include <string.h>
-#include <glib/gmain.h>
+#include <glib.h>
 
 #include <spi-common/spi-dbus.h>
 #include <droute/droute.h>
     #error "No introspection XML directory defined"
 #endif
 
+#ifdef HAVE_SM
+#include <X11/SM/SMlib.h>
+#endif
+
+
 static gchar *dbus_name = NULL;
 
+static void registry_session_init (const char *previous_client_id, const char *exe);
 static GOptionEntry optentries[] =
 {
   {"dbus-name", 0, 0, G_OPTION_ARG_STRING, &dbus_name, "Well-known name to register with D-Bus", NULL},
@@ -107,6 +113,106 @@ main (int argc, char **argv)
   registry = spi_registry_new (bus, droute);
   dec = spi_registry_dec_new (registry, bus, droute);
 
+
+      /* 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);
+      }
+
+
   g_main_loop_run (mainloop);
   return 0;
 }
+
+void
+registry_session_init (const char *previous_client_id, const char *exe)
+{
+#ifdef HAVE_SM
+  char buf[256];
+  char *client_id;
+
+  SmcConn session_connection =
+  SmcOpenConnection (NULL, /* use SESSION_MANAGER env */
+                     NULL, /* means use existing ICE connection */
+                     SmProtoMajor,
+                     SmProtoMinor,
+                     0,
+                     NULL,
+                     (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
+}
+
index 34a3e30..8bf09d1 100644 (file)
@@ -25,7 +25,7 @@
 #define _SPI_KEYMASKS_H_
 
 #include <X11/Xlib.h>
-#include <glib/gmacros.h>
+#include <glib.h>
 
 G_BEGIN_DECLS