[mutter/wip/wayland-display: 89/93] MetaWayland: implement spawning dbus and gnome-session



commit 5cea94401e33b0ebb306bc2aeeb59cf4981f61fd
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Thu Aug 8 17:07:54 2013 +0200

    MetaWayland: implement spawning dbus and gnome-session
    
    If we launch gnome-session ourselves after setting up XWayland,
    we then get gnome-settings-daemon and all the required session
    stuff, which means we can run a full regular gnome session.

 src/core/monitor-private.h |    7 ++++
 src/core/monitor.c         |   28 +++++++++++---
 src/core/screen.c          |    5 +++
 src/wayland/meta-wayland.c |   85 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 119 insertions(+), 6 deletions(-)
---
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index b1dcc0e..f3792b3 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -299,6 +299,13 @@ GType meta_monitor_manager_get_type (void);
 void                meta_monitor_manager_initialize (void);
 MetaMonitorManager *meta_monitor_manager_get  (void);
 
+void                meta_monitor_manager_init_dbus         (MetaMonitorManager *manager,
+                                                            GAsyncReadyCallback callback,
+                                                            gpointer            user_data);
+gboolean            meta_monitor_manager_init_dbus_finish  (MetaMonitorManager *manager,
+                                                            GAsyncResult       *result,
+                                                            GError            **error);
+
 MetaMonitorInfo    *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
                                                            unsigned int       *n_infos);
 
diff --git a/src/core/monitor.c b/src/core/monitor.c
index ea592c4..ecfb9d8 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -61,7 +61,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYP
 static void free_output_array (MetaOutput *old_outputs,
                                int         n_old_outputs);
 static void invalidate_logical_config (MetaMonitorManager *manager);
-static void initialize_dbus_interface (MetaMonitorManager *manager);
 
 static void
 read_current_dummy (MetaMonitorManager *manager)
@@ -525,7 +524,6 @@ meta_monitor_manager_constructed (GObject *object)
     }
 
   make_logical_config (manager);
-  initialize_dbus_interface (manager);
 
   manager->in_init = FALSE;
 }
@@ -1321,7 +1319,8 @@ on_bus_acquired (GDBusConnection *connection,
                  const char      *name,
                  gpointer         user_data)
 {
-  MetaMonitorManager *manager = user_data;
+  GTask *task = user_data;
+  MetaMonitorManager *manager = g_task_get_task_data (task);
 
   g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (manager),
                                     connection,
@@ -1334,7 +1333,11 @@ on_name_acquired (GDBusConnection *connection,
                   const char      *name,
                   gpointer         user_data)
 {
+  GTask *task = user_data;
+
   meta_topic (META_DEBUG_DBUS, "Acquired name %s\n", name);
+
+  g_task_return_boolean (task, TRUE);
 }
 
 static void
@@ -1345,9 +1348,14 @@ on_name_lost (GDBusConnection *connection,
   meta_topic (META_DEBUG_DBUS, "Lost or failed to acquire name %s\n", name);
 }
 
-static void
-initialize_dbus_interface (MetaMonitorManager *manager)
+void
+meta_monitor_manager_init_dbus (MetaMonitorManager   *manager,
+                                GAsyncReadyCallback   callback,
+                                gpointer              user_data)
 {
+  GTask *task = g_task_new (manager, NULL, callback, user_data);
+  g_task_set_task_data (task, g_object_ref (manager), g_object_unref);
+
   manager->dbus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
                                           "org.gnome.Mutter.DisplayConfig",
                                           G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
@@ -1356,10 +1364,18 @@ initialize_dbus_interface (MetaMonitorManager *manager)
                                           on_bus_acquired,
                                           on_name_acquired,
                                           on_name_lost,
-                                          g_object_ref (manager),
+                                          task,
                                           g_object_unref);
 }
 
+gboolean
+meta_monitor_manager_init_dbus_finish (MetaMonitorManager  *manager,
+                                       GAsyncResult        *result,
+                                       GError             **error)
+{
+  return g_task_propagate_boolean (G_TASK (result), error);
+}
+
 static MetaMonitorManager *global_manager;
 
 void
diff --git a/src/core/screen.c b/src/core/screen.c
index 9deb488..db71e97 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -689,6 +689,11 @@ meta_screen_new (MetaDisplay *display,
                                         &screen->rect.width,
                                         &screen->rect.height);
 
+#ifdef HAVE_WAYLAND
+  if (!meta_is_wayland_compositor ())
+#endif
+    meta_monitor_manager_init_dbus (manager, NULL, NULL);
+
   screen->current_cursor = -1; /* invalid/unset */
   screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
   screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index b575b1f..5f39794 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -32,6 +32,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include <sys/wait.h>
 
 #include <wayland-server.h>
@@ -1270,6 +1272,55 @@ bind_shell (struct wl_client *client,
 }
 
 static void
+gnome_session_died (GPid     pid,
+                   gint     status,
+                   gpointer user_data)
+{
+  if (!WIFEXITED (status))
+    g_error ("gnome-session crashed; aborting");
+  else
+    {
+      /* A clean exit of gnome-session implies a logout, exit cleanly */
+      meta_quit (META_EXIT_SUCCESS);
+    }
+}
+
+static void
+start_gnome_session (MetaWaylandCompositor *compositor)
+{
+  GPid pid;
+  char *args[6];
+  GError *error;
+
+  args[0] = "setsid";
+  args[1] = "gnome-session";
+  args[2] = "--session";
+  args[3] = "gnome-wayland";
+  args[4] = "--debug";
+  args[5] = NULL;
+
+  error = NULL;
+  if (g_spawn_async (NULL, /* cwd */
+                    args,
+                    NULL,
+                    G_SPAWN_SEARCH_PATH |
+                    G_SPAWN_DO_NOT_REAP_CHILD,
+                    NULL,
+                    NULL,
+                    &pid,
+                    &error))
+    {
+      g_message ("forked gnome-session, pid %d\n", pid);
+
+      g_child_watch_add (pid, gnome_session_died, NULL);
+    }
+  else
+    {
+      g_error ("Failed to fork gnome-session server: %s", error->message);
+    }
+}
+
+static void
 stage_destroy_cb (void)
 {
   meta_quit (META_EXIT_SUCCESS);
@@ -1574,6 +1625,21 @@ on_monitors_changed (MetaMonitorManager    *monitors,
   compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
 }
 
+static void
+on_display_config_ready (GObject      *object,
+                        GAsyncResult *result,
+                        gpointer      user_data)
+{
+  gboolean ok;
+
+  ok = meta_monitor_manager_init_dbus_finish (META_MONITOR_MANAGER (object), result, NULL);
+  g_assert (ok);
+
+  /* Now we have X and DBus, and our stuff is on the bus.
+     The only thing missing is gnome-session! */
+  start_gnome_session (user_data);
+}
+
 void
 meta_wayland_init (void)
 {
@@ -1584,6 +1650,8 @@ meta_wayland_init (void)
   CoglRenderer *cogl_renderer;
   int weston_launch_fd;
   MetaMonitorManager *monitors;
+  GDBusConnection *session_bus;
+  char *session_bus_address;
 
   memset (compositor, 0, sizeof (MetaWaylandCompositor));
 
@@ -1737,6 +1805,23 @@ meta_wayland_init (void)
     g_error ("Failed to start X Wayland");
 
   putenv (g_strdup_printf ("DISPLAY=:%d", compositor->xwayland_display_index));
+
+  /* Now xwayland is ready. Get ourselves a dbus daemon. This will autolaunch
+     if no bus is found.
+  */
+  session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+  if (!session_bus)
+    meta_fatal ("Could not connect to the session bus\n");
+
+  session_bus_address = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+  putenv (g_strdup_printf ("DBUS_SESSION_BUS_ADDRESS=%s", session_bus_address));
+  g_free (session_bus_address);
+
+  /* Now get our interface on the dbus (or gnome-settings-daemon will refuse
+     to start, which in turn will stall gnome-session from launching the rest
+     of the session)
+  */
+  meta_monitor_manager_init_dbus (monitors, on_display_config_ready, compositor);
 }
 
 void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]