[mutter] launcher: Replace mutter-launch with logind integration
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] launcher: Replace mutter-launch with logind integration
- Date: Tue, 20 May 2014 11:56:39 +0000 (UTC)
commit dcf64ca1678a2950842708bee146f09a063ed828
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Tue Dec 31 17:44:45 2013 -0500
launcher: 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 requires systemd v210, at least.
https://bugzilla.gnome.org/show_bug.cgi?id=724604
.gitignore | 2 +-
configure.ac | 3 +-
src/Makefile.am | 25 +-
src/backends/native/dbus-utils.c | 107 ++++++
src/backends/native/dbus-utils.h | 32 ++
src/backends/native/meta-launcher.c | 433 ++++++++++-----------
src/backends/native/weston-launch.c | 711 -----------------------------------
src/backends/native/weston-launch.h | 68 ----
src/mutter-wayland.desktop.in | 2 +-
src/org.freedesktop.login1.xml | 44 +++
10 files changed, 406 insertions(+), 1021 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 1b238e1..446c092 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,7 +48,6 @@ po/*.pot
50-metacity-key.xml
libmutter.pc
mutter
-mutter-launch
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
org.gnome.mutter.wayland.gschema.valid
@@ -78,6 +77,7 @@ src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/meta-dbus-display-config.[ch]
src/meta-dbus-idle-monitor.[ch]
+src/meta-dbus-login1.[ch]
src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h
src/xdg-shell-protocol.c
diff --git a/configure.ac b/configure.ac
index 7a8d1b9..c8c92f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,7 +127,6 @@ AM_GLIB_GNU_GETTEXT
## here we get the flags we'll actually use
# GRegex requires Glib-2.14.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
-PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
@@ -200,7 +199,7 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
AC_SUBST([WAYLAND_SCANNER])
AC_SUBST(XWAYLAND_PATH)
-MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0
wayland-server >= 1.4.93 libdrm"
+MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0
wayland-server >= 1.4.93 libdrm libsystemd"
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
diff --git a/src/Makefile.am b/src/Makefile.am
index 5e6b710..c71697f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -35,6 +35,7 @@ INCLUDES= \
mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_display_config_built_sources) \
+ $(dbus_login1_built_sources) \
mutter-enum-types.h \
mutter-enum-types.c \
gtk-shell-protocol.c \
@@ -80,6 +81,8 @@ libmutter_la_SOURCES = \
backends/native/meta-monitor-manager-kms.h \
backends/native/meta-launcher.c \
backends/native/meta-launcher.h \
+ backends/native/dbus-utils.c \
+ backends/native/dbus-utils.h \
backends/x11/meta-backend-x11.c \
backends/x11/meta-backend-x11.h \
backends/x11/meta-cursor-renderer-x11.c \
@@ -293,19 +296,6 @@ bin_PROGRAMS=mutter
mutter_SOURCES = core/mutter.c
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
-bin_PROGRAMS+=mutter-launch
-
-mutter_launch_SOURCES = \
- backends/native/weston-launch.c \
- backends/native/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)
@@ -442,6 +432,15 @@ $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml
--c-generate-object-manager \
$(srcdir)/org.gnome.Mutter.IdleMonitor.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
+
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
diff --git a/src/backends/native/dbus-utils.c b/src/backends/native/dbus-utils.c
new file mode 100644
index 0000000..6a63b92
--- /dev/null
+++ b/src/backends/native/dbus-utils.c
@@ -0,0 +1,107 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2014 Red Hat
+ *
+ * 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.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#include "config.h"
+
+#include "dbus-utils.h"
+
+#include <glib.h>
+
+/* Stolen from tp_escape_as_identifier, from tp-glib,
+ * which follows the same escaping convention as systemd.
+ */
+static inline gboolean
+_esc_ident_bad (gchar c, gboolean is_first)
+{
+ return ((c < 'a' || c > 'z') &&
+ (c < 'A' || c > 'Z') &&
+ (c < '0' || c > '9' || is_first));
+}
+
+static gchar *
+escape_dbus_component (const gchar *name)
+{
+ gboolean bad = FALSE;
+ size_t len = 0;
+ GString *op;
+ const gchar *ptr, *first_ok;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ /* fast path for empty name */
+ if (name[0] == '\0')
+ return g_strdup ("_");
+
+ for (ptr = name; *ptr; ptr++)
+ {
+ if (_esc_ident_bad (*ptr, ptr == name))
+ {
+ bad = TRUE;
+ len += 3;
+ }
+ else
+ len++;
+ }
+
+ /* fast path if it's clean */
+ if (!bad)
+ return g_strdup (name);
+
+ /* If strictly less than ptr, first_ok is the first uncopied safe character.
+ */
+ first_ok = name;
+ op = g_string_sized_new (len);
+ for (ptr = name; *ptr; ptr++)
+ {
+ if (_esc_ident_bad (*ptr, ptr == name))
+ {
+ /* copy preceding safe characters if any */
+ if (first_ok < ptr)
+ {
+ g_string_append_len (op, first_ok, ptr - first_ok);
+ }
+ /* escape the unsafe character */
+ g_string_append_printf (op, "_%02x", (unsigned char)(*ptr));
+ /* restart after it */
+ first_ok = ptr + 1;
+ }
+ }
+ /* copy trailing safe characters if any */
+ if (first_ok < ptr)
+ {
+ g_string_append_len (op, first_ok, ptr - first_ok);
+ }
+ return g_string_free (op, FALSE);
+}
+
+char *
+get_escaped_dbus_path (const char *prefix,
+ const char *component)
+{
+ char *escaped_component = escape_dbus_component (component);
+ char *path = g_strconcat (prefix, "/", escaped_component, NULL);
+
+ g_free (escaped_component);
+ return path;
+}
diff --git a/src/backends/native/dbus-utils.h b/src/backends/native/dbus-utils.h
new file mode 100644
index 0000000..ee56c45
--- /dev/null
+++ b/src/backends/native/dbus-utils.h
@@ -0,0 +1,32 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2014 Red Hat
+ *
+ * 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.
+ *
+ * Written by:
+ * Jasper St. Pierre <jstpierre mecheye net>
+ */
+
+#ifndef DBUS_UTILS_H
+#define DBUS_UTILS_H
+
+char *
+get_escaped_dbus_path (const char *prefix,
+ const char *component);
+
+#endif /* DBUS_UTILS_H */
diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c
index 6675508..7519194 100644
--- a/src/backends/native/meta-launcher.c
+++ b/src/backends/native/meta-launcher.c
@@ -20,9 +20,8 @@
#include "config.h"
#include "meta-launcher.h"
-#include "weston-launch.h"
-#include <gio/gunixfdmessage.h>
+#include <gio/gunixfdlist.h>
#include <clutter/clutter.h>
#include <clutter/egl/clutter-egl.h>
@@ -30,10 +29,17 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <malloc.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+
+#include <systemd/sd-login.h>
+
+#include "dbus-utils.h"
+#include "meta-dbus-login1.h"
#include "wayland/meta-wayland-private.h"
#include "backends/meta-backend.h"
@@ -41,153 +47,44 @@
struct _MetaLauncher
{
- GSocket *weston_launch;
- GSource *weston_launch_source;
+ Login1Session *session_proxy;
+ Login1Seat *seat_proxy;
- gboolean vt_switched;
+ gboolean session_active;
};
/* AAA BBB CCC */
-static void handle_request_vt_switch (MetaLauncher *self);
-
-static gboolean
-request_vt_switch_idle (gpointer user_data)
+static Login1Session *
+get_session_proxy (GCancellable *cancellable)
{
- handle_request_vt_switch (user_data);
+ char *proxy_path;
+ char *session_id;
+ Login1Session *session_proxy;
- return FALSE;
-}
+ if (sd_pid_get_session (getpid (), &session_id) < 0)
+ return NULL;
-static gboolean
-send_message_to_wl (MetaLauncher *self,
- void *message,
- gsize size,
- GSocketControlMessage *out_cmsg,
- GSocketControlMessage **in_cmsg,
- GError **error)
-{
- struct weston_launcher_reply reply;
- GInputVector in_iov = { &reply, sizeof (reply) };
- GOutputVector out_iov = { message, size };
- GSocketControlMessage *out_all_cmsg[2];
- GSocketControlMessage **in_all_cmsg;
- int flags = 0;
- int i;
-
- out_all_cmsg[0] = out_cmsg;
- out_all_cmsg[1] = NULL;
- if (g_socket_send_message (self->weston_launch, NULL,
- &out_iov, 1,
- out_all_cmsg, -1,
- flags, NULL, error) != (gssize)size)
- return FALSE;
-
- if (g_socket_receive_message (self->weston_launch, NULL,
- &in_iov, 1,
- &in_all_cmsg, NULL,
- &flags, NULL, error) != sizeof (reply))
- return FALSE;
+ proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
- while (reply.header.opcode != ((struct weston_launcher_message*)message)->opcode)
- {
- guint id;
-
- /* There were events queued */
- g_assert ((reply.header.opcode & WESTON_LAUNCHER_EVENT) == WESTON_LAUNCHER_EVENT);
-
- /* This can never happen, because the only time mutter-launch can queue
- this event is after confirming a VT switch, and we don't make requests
- during that time.
-
- Note that getting this event would be really bad, because we would be
- in the wrong loop/context.
- */
- g_assert (reply.header.opcode != WESTON_LAUNCHER_SERVER_VT_ENTER);
-
- switch (reply.header.opcode)
- {
- case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
- id = g_idle_add (request_vt_switch_idle, self);
- g_source_set_name_by_id (id, "[mutter] request_vt_switch_idle");
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- if (g_socket_receive_message (self->weston_launch, NULL,
- &in_iov, 1,
- NULL, NULL,
- &flags, NULL, error) != sizeof (reply))
- return FALSE;
- }
+ session_proxy = login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.freedesktop.login1",
+ proxy_path,
+ cancellable, NULL);
+ free (proxy_path);
- if (reply.ret != 0)
- {
- if (reply.ret == -1)
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Got failure from weston-launch");
- else
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-reply.ret),
- "Got failure from weston-launch: %s", strerror (-reply.ret));
-
- for (i = 0; in_all_cmsg && in_all_cmsg[i]; i++)
- g_object_unref (in_all_cmsg[i]);
- g_free (in_all_cmsg);
-
- return FALSE;
- }
-
- if (in_all_cmsg && in_all_cmsg[0])
- {
- for (i = 1; in_all_cmsg[i]; i++)
- g_object_unref (in_all_cmsg[i]);
- *in_cmsg = in_all_cmsg[0];
- }
-
- g_free (in_all_cmsg);
- return TRUE;
+ return session_proxy;
}
-static int
-meta_launcher_open_device (MetaLauncher *self,
- const char *name,
- int flags,
- GError **error)
+static Login1Seat *
+get_seat_proxy (GCancellable *cancellable)
{
- struct weston_launcher_open *message;
- GSocketControlMessage *cmsg;
- gboolean ok;
- gsize size;
- int *fds, n_fd;
- int ret;
-
- size = sizeof (struct weston_launcher_open) + strlen (name) + 1;
- message = g_malloc (size);
- message->header.opcode = WESTON_LAUNCHER_OPEN;
- message->flags = flags;
- strcpy (message->path, name);
- message->path[strlen(name)] = 0;
-
- ok = send_message_to_wl (self, message, size, NULL, &cmsg, error);
-
- if (ok)
- {
- g_assert (G_IS_UNIX_FD_MESSAGE (cmsg));
-
- fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (cmsg), &n_fd);
- g_assert (n_fd == 1);
-
- ret = fds[0];
- g_free (fds);
- g_object_unref (cmsg);
- }
- else
- ret = -1;
-
- g_free (message);
- return ret;
+ return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/seat/self",
+ cancellable, NULL);
}
/* QQQ RRR SSS */
@@ -228,107 +125,190 @@ session_pause (void)
clutter_egl_freeze_master_clock ();
}
+static gboolean
+take_device (Login1Session *session_proxy,
+ 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 (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_from_path (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 gboolean
+get_device_info_from_fd (int fd,
+ int *out_major,
+ int *out_minor)
+{
+ gboolean ret = FALSE;
+ int r;
+ struct stat st;
+
+ r = fstat (fd, &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)
{
- MetaLauncher *launcher = user_data;
+ MetaLauncher *self = user_data;
+ int fd;
+ int major, minor;
+
+ if (!get_device_info_from_path (path, &major, &minor))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_FOUND,
+ "Could not get device info for path %s: %m", path);
+ return -1;
+ }
+
+ if (!take_device (self->session_proxy, major, minor, &fd, NULL, error))
+ return -1;
- return meta_launcher_open_device (launcher, path, flags, error);
+ return fd;
}
static void
on_evdev_device_close (int fd,
gpointer user_data)
{
- close (fd);
+ MetaLauncher *self = user_data;
+ int major, minor;
+ GError *error = NULL;
+
+ if (!get_device_info_from_fd (fd, &major, &minor))
+ {
+ g_warning ("Could not get device info for fd %d: %m", fd);
+ return;
+ }
+
+ if (!login1_session_call_release_device_sync (self->session_proxy,
+ major, minor,
+ NULL, &error))
+ {
+ g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
+ }
}
/* TTT UUU VVV */
static void
-handle_vt_enter (MetaLauncher *launcher)
+sync_active (MetaLauncher *self)
{
- g_assert (launcher->vt_switched);
- launcher->vt_switched = FALSE;
+ gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
+
+ if (active == self->session_active)
+ return;
- session_unpause ();
+ self->session_active = active;
+
+ if (active)
+ session_unpause ();
+ else
+ session_pause ();
}
static void
-handle_request_vt_switch (MetaLauncher *launcher)
+on_active_changed (Login1Session *session,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- struct weston_launcher_message message;
- GError *error;
- gboolean ok;
-
- session_pause ();
-
- message.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
-
- error = NULL;
- ok = send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, &error);
- if (!ok) {
- g_warning ("Failed to acknowledge VT switch: %s", error->message);
- g_error_free (error);
- return;
- }
-
- g_assert (!launcher->vt_switched);
- launcher->vt_switched = TRUE;
-
- session_unpause ();
+ MetaLauncher *self = user_data;
+ sync_active (self);
}
static gboolean
-on_socket_readable (GSocket *socket,
- GIOCondition condition,
- gpointer user_data)
+get_kms_fd (Login1Session *session_proxy,
+ int *fd_out)
{
- MetaLauncher *launcher = user_data;
- struct weston_launcher_event event;
- gssize read;
- GError *error;
-
- if ((condition & G_IO_IN) == 0)
- return TRUE;
+ int major, minor;
+ int fd;
+ GError *error = NULL;
- error = NULL;
- read = g_socket_receive (socket, (char*)&event, sizeof(event), NULL, &error);
- if (read < (gssize)sizeof(event))
+ /* XXX -- use udev to find the DRM master device */
+ if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
{
- g_warning ("Error reading from weston-launcher socket: %s", error->message);
- g_error_free (error);
- return TRUE;
+ g_warning ("Could not stat /dev/dri/card0: %m");
+ return FALSE;
}
- switch (event.header.opcode)
+ if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
{
- case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
- handle_request_vt_switch (launcher);
- break;
-
- case WESTON_LAUNCHER_SERVER_VT_ENTER:
- handle_vt_enter (launcher);
- break;
+ g_warning ("Could not open DRM device: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
}
- return TRUE;
-}
-
-static int
-env_get_fd (const char *env)
-{
- const char *value;
-
- value = g_getenv (env);
+ *fd_out = fd;
- if (value == NULL)
- return -1;
- else
- return g_ascii_strtoll (value, NULL, 10);
+ return TRUE;
}
/* XXX YYY ZZZ */
@@ -336,47 +316,55 @@ env_get_fd (const char *env)
MetaLauncher *
meta_launcher_new (void)
{
- MetaLauncher *self = g_slice_new0 (MetaLauncher);
+ MetaLauncher *self;
+ Login1Session *session_proxy;
GError *error = NULL;
- int launch_fd;
int kms_fd;
- launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK");
- if (launch_fd < 0)
- g_error ("Invalid mutter-launch socket");
+ 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->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
+ if (!get_kms_fd (session_proxy, &kms_fd))
+ return NULL;
- self->weston_launch_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
- g_source_set_callback (self->weston_launch_source, (GSourceFunc)on_socket_readable, self, NULL);
- g_source_attach (self->weston_launch_source, NULL);
- g_source_unref (self->weston_launch_source);
+ self = g_slice_new0 (MetaLauncher);
+ self->session_proxy = session_proxy;
+ self->seat_proxy = get_seat_proxy (NULL);
- kms_fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error);
- if (error)
- g_error ("Failed to open /dev/dri/card0: %s", error->message);
+ self->session_active = TRUE;
clutter_egl_set_kms_fd (kms_fd);
clutter_evdev_set_device_callbacks (on_evdev_device_open,
on_evdev_device_close,
self);
+ g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
+
return self;
}
void
-meta_launcher_free (MetaLauncher *launcher)
+meta_launcher_free (MetaLauncher *self)
{
- g_source_destroy (launcher->weston_launch_source);
- g_object_unref (launcher->weston_launch);
- g_slice_free (MetaLauncher, launcher);
+ g_object_unref (self->seat_proxy);
+ g_object_unref (self->session_proxy);
+ g_slice_free (MetaLauncher, self);
}
gboolean
meta_launcher_activate_session (MetaLauncher *launcher,
GError **error)
{
- return meta_launcher_activate_vt (launcher, -1, error);
+ if (!login1_session_call_activate_sync (launcher->session_proxy, NULL, error))
+ return FALSE;
+
+ sync_active (launcher);
+ return TRUE;
}
gboolean
@@ -384,10 +372,5 @@ meta_launcher_activate_vt (MetaLauncher *launcher,
signed char vt,
GError **error)
{
- struct weston_launcher_activate_vt message;
-
- message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
- message.vt = vt;
-
- return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error);
+ return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error);
}
diff --git a/src/mutter-wayland.desktop.in b/src/mutter-wayland.desktop.in
index fb51a17..8502089 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 --display-server
+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..924e397
--- /dev/null
+++ b/src/org.freedesktop.login1.xml
@@ -0,0 +1,44 @@
+<!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>
+ </interface>
+
+ <interface name="org.freedesktop.login1.Seat">
+ <method name="SwitchTo">
+ <arg name="vt" type="u"/>
+ </method>
+ </interface>
+</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]