[mutter/wip/login1] Replace mutter-launch with logind integration
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/login1] Replace mutter-launch with logind integration
- Date: Tue, 18 Feb 2014 03:09:33 +0000 (UTC)
commit 6c7a47d32e58da6acc7d1c89451cafc674bdab63
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Tue Dec 31 17:44:45 2013 -0500
Replace mutter-launch with logind integration
This uses David Herrmann's new logind sessions interface to retrieve
fds for input devices, rather than using a custom setuid helper to do
the management. This vastly simplifies the interface.
This does require systemd from git, as systemd v209 has not been
released yet.
.gitignore | 2 +-
src/Makefile.am | 25 +-
src/core/main.c | 35 ++-
src/meta/main.h | 1 +
src/mutter-wayland.desktop.in | 2 +-
src/org.freedesktop.login1.xml | 42 ++
src/wayland/meta-login1.c | 227 +++++++++++
src/wayland/meta-login1.h | 35 ++
src/wayland/meta-wayland-private.h | 6 +-
src/wayland/meta-wayland.c | 41 +-
src/wayland/meta-weston-launch.c | 401 ------------------
src/wayland/meta-weston-launch.h | 46 ---
src/wayland/weston-launch.c | 788 ------------------------------------
src/wayland/weston-launch.h | 69 ----
14 files changed, 379 insertions(+), 1341 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index ba75840..6970ca4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,7 +48,6 @@ po/*.pot
50-metacity-key.xml
libmutter-wayland.pc
mutter-wayland
-mutter-launch
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
org.gnome.mutter.wayland.gschema.valid
@@ -77,6 +76,7 @@ src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/meta-dbus-xrandr.[ch]
src/meta-dbus-idle-monitor.[ch]
+src/meta-dbus-login1.[ch]
src/mutter-plugins.pc
src/wayland/gtk-shell-protocol.c
src/wayland/gtk-shell-server-protocol.h
diff --git a/src/Makefile.am b/src/Makefile.am
index ae8f7c1..a3a339b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,7 @@ INCLUDES += \
mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_xrandr_built_sources) \
+ $(dbus_login1_built_sources) \
mutter-enum-types.h \
mutter-enum-types.c \
wayland/gtk-shell-protocol.c \
@@ -207,8 +208,8 @@ libmutter_wayland_la_SOURCES = \
wayland/meta-wayland-surface.h \
wayland/meta-wayland-types.h \
wayland/meta-wayland-versions.h \
- wayland/meta-weston-launch.c \
- wayland/meta-weston-launch.h
+ wayland/meta-login1.c \
+ wayland/meta-login1.h
nodist_libmutter_wayland_la_SOURCES = \
$(mutter_built_sources)
@@ -263,17 +264,6 @@ bin_PROGRAMS=mutter-wayland
mutter_wayland_SOURCES = core/mutter.c
mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la
-bin_PROGRAMS+=mutter-launch
-
-mutter_launch_SOURCES = wayland/weston-launch.c wayland/weston-launch.h
-
-mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\"
-mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam
-
-install-exec-hook:
- -chown root $(DESTDIR)$(bindir)/mutter-launch
- -chmod u+s $(DESTDIR)$(bindir)/mutter-launch
-
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
@@ -409,6 +399,15 @@ $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
--c-generate-object-manager \
$(srcdir)/idle-monitor.xml
+dbus_login1_built_sources = meta-dbus-login1.c meta-dbus-login1.h
+
+$(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
+ $(AM_V_GEN)gdbus-codegen \
+ --interface-prefix org.freedesktop.login1 \
+ --c-namespace Login1 \
+ --generate-c-code meta-dbus-login1 \
+ $(srcdir)/org.freedesktop.login1.xml
+
wayland/%-protocol.c : $(top_builddir)/protocol/%.xml
mkdir -p wayland
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
diff --git a/src/core/main.c b/src/core/main.c
index c4bdeee..2103d88 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -190,6 +190,7 @@ static gboolean opt_replace_wm;
static gboolean opt_disable_sm;
static gboolean opt_sync;
static gboolean opt_wayland;
+static gboolean opt_display_server;
static GOptionEntry meta_options[] = {
{
@@ -233,6 +234,11 @@ static GOptionEntry meta_options[] = {
N_("Run as a wayland compositor"),
NULL
},
+ {
+ "display-server", 0, 0, G_OPTION_ARG_NONE,
+ &opt_display_server,
+ N_("Run as a full display server, rather than nested")
+ },
{NULL}
};
@@ -400,8 +406,7 @@ meta_init (void)
if (g_getenv ("MUTTER_DEBUG"))
meta_set_debugging (TRUE);
- /* We consider running from mutter-launch equivalent to running from bare metal. */
- if (getenv ("WESTON_LAUNCHER_SOCK"))
+ if (opt_display_server)
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
meta_set_is_wayland_compositor (opt_wayland);
@@ -497,6 +502,32 @@ meta_register_with_session (void)
}
/**
+ * meta_activate_session:
+ *
+ * Tells mutter to activate the session. When mutter is a
+ * Wayland compositor, this tells logind to switch over to
+ * the new session.
+ */
+gboolean
+meta_activate_session (void)
+{
+ if (meta_is_wayland_compositor ())
+ {
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+ GError *error = NULL;
+
+ if (!meta_wayland_compositor_activate_session (compositor, &error))
+ {
+ g_warning ("Could not activate session: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
* meta_run: (skip)
*
* Runs mutter. Call this after completing initialization that doesn't require
diff --git a/src/meta/main.h b/src/meta/main.h
index 35eb73d..9a74809 100644
--- a/src/meta/main.h
+++ b/src/meta/main.h
@@ -28,6 +28,7 @@ GOptionContext *meta_get_option_context (void);
void meta_init (void);
int meta_run (void);
void meta_register_with_session (void);
+gboolean meta_activate_session (void);
gboolean meta_get_replace_current_wm (void); /* Actually defined in util.c */
void meta_set_wm_name (const char *wm_name);
diff --git a/src/mutter-wayland.desktop.in b/src/mutter-wayland.desktop.in
index ebf1447..3bf5f23 100644
--- a/src/mutter-wayland.desktop.in
+++ b/src/mutter-wayland.desktop.in
@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
_Name=Mutter (wayland compositor)
-Exec=mutter-launch -- mutter --wayland
+Exec=mutter --wayland --display-server
NoDisplay=true
# name of loadable control center module
X-GNOME-WMSettingsModule=metacity
diff --git a/src/org.freedesktop.login1.xml b/src/org.freedesktop.login1.xml
new file mode 100644
index 0000000..9aad8ca
--- /dev/null
+++ b/src/org.freedesktop.login1.xml
@@ -0,0 +1,42 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.login1.Session">
+ <property name="Active" type="b" access="read" />
+
+ <method name="Activate">
+ </method>
+ <method name="TakeControl">
+ <arg name="force" type="b"/>
+ </method>
+ <method name="TakeDevice">
+ <annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
+ <arg name="major" type="u" direction="in"/>
+ <arg name="minor" type="u" direction="in"/>
+ <arg name="fd" type="h" direction="out"/>
+ <arg name="paused" type="b" direction="out"/>
+ </method>
+ <method name="ReleaseDevice">
+ <arg name="major" type="u"/>
+ <arg name="minor" type="u"/>
+ </method>
+ <method name="PauseDeviceComplete">
+ <arg name="major" type="u"/>
+ <arg name="minor" type="u"/>
+ </method>
+ <signal name="PauseDevice">
+ <arg name="major" type="u"/>
+ <arg name="minor" type="u"/>
+ <arg name="type" type="s"/>
+ </signal>
+ <signal name="ResumeDevice">
+ <arg name="major" type="u"/>
+ <arg name="minor" type="u"/>
+ <arg name="fd" type="h"/>
+ </signal>
+
+ <method name="SwitchTo">
+ <arg name="vt" type="u"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/wayland/meta-login1.c b/src/wayland/meta-login1.c
new file mode 100644
index 0000000..6fd0dc0
--- /dev/null
+++ b/src/wayland/meta-login1.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "meta-login1.h"
+
+#include "meta-dbus-login1.h"
+
+#include <gio/gunixfdlist.h>
+
+#include <clutter/clutter.h>
+#include <clutter/evdev/clutter-evdev.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+struct _MetaLogin1
+{
+ Login1Session *session_proxy;
+};
+
+static Login1Session *
+get_session_proxy (GCancellable *cancellable)
+{
+ return login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ cancellable, NULL);
+}
+
+static void
+session_enter (void)
+{
+ ClutterBackend *backend;
+ CoglContext *cogl_context;
+ CoglDisplay *cogl_display;
+
+ backend = clutter_get_default_backend ();
+ cogl_context = clutter_backend_get_cogl_context (backend);
+ cogl_display = cogl_context_get_display (cogl_context);
+ cogl_kms_display_queue_modes_reset (cogl_display);
+
+ clutter_evdev_reclaim_devices ();
+}
+
+static void
+session_leave (void)
+{
+ clutter_evdev_release_devices ();
+}
+
+static void
+sync_active (MetaLogin1 *self)
+{
+ gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
+
+ if (active)
+ session_enter ();
+ else
+ session_leave ();
+}
+
+static void
+on_active_changed (Login1Session *session,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ MetaLogin1 *self = user_data;
+ sync_active (self);
+}
+
+static gboolean
+meta_login1_take_device (MetaLogin1 *self,
+ int dev_major,
+ int dev_minor,
+ int *out_fd,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GVariant *fd_variant = NULL;
+ int fd = -1;
+ GUnixFDList *fd_list;
+
+ if (!login1_session_call_take_device_sync (self->session_proxy,
+ dev_major,
+ dev_minor,
+ NULL,
+ &fd_variant,
+ NULL, /* paused */
+ &fd_list,
+ cancellable,
+ error))
+ goto out;
+
+ fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
+ if (fd == -1)
+ goto out;
+
+ *out_fd = fd;
+ ret = TRUE;
+
+ out:
+ if (fd_variant)
+ g_variant_unref (fd_variant);
+ if (fd_list)
+ g_object_unref (fd_list);
+ return ret;
+}
+
+static gboolean
+get_device_info (const char *path,
+ int *out_major,
+ int *out_minor)
+{
+ gboolean ret = FALSE;
+ int r;
+ struct stat st;
+
+ r = stat (path, &st);
+ if (r < 0)
+ goto out;
+ if (!S_ISCHR (st.st_mode))
+ goto out;
+
+ *out_major = major (st.st_rdev);
+ *out_minor = minor (st.st_rdev);
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+
+static int
+on_evdev_device_open (const char *path,
+ int flags,
+ gpointer user_data,
+ GError **error)
+{
+ MetaLogin1 *self = user_data;
+ int fd;
+ int major, minor;
+
+ if (!get_device_info (path, &major, &minor))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ "Could not get device info for path: %s", path);
+ return -1;
+ }
+
+ if (!meta_login1_take_device (self, major, minor, &fd, NULL, error))
+ return -1;
+
+ return fd;
+}
+
+MetaLogin1 *
+meta_login1_new (void)
+{
+ MetaLogin1 *self;
+ Login1Session *session_proxy;
+ GError *error = NULL;
+
+ session_proxy = get_session_proxy (NULL);
+ if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
+ {
+ g_warning ("Could not take control: %s", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ self = g_slice_new0 (MetaLogin1);
+ self->session_proxy = session_proxy;
+
+ clutter_evdev_set_open_callback (on_evdev_device_open, self);
+
+ g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
+
+ return self;
+}
+
+void
+meta_login1_free (MetaLogin1 *self)
+{
+ g_object_unref (self->session_proxy);
+ g_slice_free (MetaLogin1, self);
+}
+
+gboolean
+meta_login1_activate_session (MetaLogin1 *self,
+ GError **error)
+{
+ if (!login1_session_call_activate_sync (self->session_proxy, NULL, error))
+ return FALSE;
+
+ sync_active (self);
+ return TRUE;
+}
+
+gboolean
+meta_login1_activate_vt (MetaLogin1 *self,
+ int vt,
+ GError **error)
+{
+ return login1_session_call_switch_to_sync (self->session_proxy, vt, NULL, error);
+}
diff --git a/src/wayland/meta-login1.h b/src/wayland/meta-login1.h
new file mode 100644
index 0000000..0fed205
--- /dev/null
+++ b/src/wayland/meta-login1.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_LOGIN1_H
+#define META_LOGIN1_H
+
+#include <glib-object.h>
+
+typedef struct _MetaLogin1 MetaLogin1;
+
+MetaLogin1 *meta_login1_new (void);
+void meta_login1_free (MetaLogin1 *self);
+gboolean meta_login1_activate_session (MetaLogin1 *self,
+ GError **error);
+gboolean meta_login1_activate_vt (MetaLogin1 *self,
+ int vt,
+ GError **error);
+
+#endif
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index 69de1b8..201f3ac 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -28,7 +28,7 @@
#include <cairo.h>
#include "window-private.h"
-#include "meta-weston-launch.h"
+#include "meta-login1.h"
#include <meta/meta-cursor-tracker.h>
#include "meta-wayland-types.h"
@@ -86,7 +86,7 @@ struct _MetaWaylandCompositor
MetaXWaylandManager xwayland_manager;
- MetaLauncher *launcher;
+ MetaLogin1 *login1;
MetaWaylandSeat *seat;
};
@@ -116,5 +116,7 @@ void meta_wayland_compositor_paint_finished (MetaWaylandComp
gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
int vt,
GError **error);
+gboolean meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
+ GError **error);
#endif /* META_WAYLAND_PRIVATE_H */
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 3a32dee..4edf5d5 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -52,7 +52,7 @@
#include <meta/main.h>
#include "frame.h"
#include "meta-idle-monitor-private.h"
-#include "meta-weston-launch.h"
+#include "meta-login1.h"
#include "monitor-private.h"
static MetaWaylandCompositor _meta_wayland_compositor;
@@ -643,25 +643,16 @@ meta_wayland_init (void)
clutter_wayland_set_compositor_display (compositor->wayland_display);
+ /* If we're running on bare metal, we're a display server,
+ * so start talking to logind. */
#if defined(CLUTTER_WINDOWING_EGL)
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
- compositor->launcher = meta_launcher_new ();
+ compositor->login1 = meta_login1_new ();
#endif
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
g_error ("Failed to initialize Clutter");
-#if defined(CLUTTER_WINDOWING_EGL)
- if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
- {
- ClutterBackend *backend = clutter_get_default_backend ();
- CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
- CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context));
- int drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
- meta_launcher_set_drm_fd (compositor->launcher, drm_fd, NULL);
- }
-#endif
-
meta_monitor_manager_initialize ();
monitors = meta_monitor_manager_get ();
g_signal_connect (monitors, "monitors-changed",
@@ -713,8 +704,7 @@ meta_wayland_finalize (void)
meta_xwayland_stop (&compositor->xwayland_manager);
- if (compositor->launcher)
- meta_launcher_free (compositor->launcher);
+ meta_login1_free (compositor->login1);
}
gboolean
@@ -722,13 +712,28 @@ meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
int vt,
GError **error)
{
- if (compositor->launcher)
+ if (compositor->login1)
+ {
+ return meta_login1_activate_vt (compositor->login1, vt, error);
+ }
+ else
+ {
+ g_debug ("Ignoring VT switch keybinding, not running as display server");
+ return TRUE;
+ }
+}
+
+gboolean
+meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
+ GError **error)
+{
+ if (compositor->login1)
{
- return meta_launcher_activate_vt (compositor->launcher, vt, error);
+ return meta_login1_activate_session (compositor->login1, error);
}
else
{
- g_debug ("Ignoring VT switch keybinding, not running as VT manager");
+ g_debug ("Ignoring activate_session, not running as display server");
return TRUE;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]