diff --git a/.gitignore b/.gitignore
index ba75840b6..6970ca455 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/configure.ac b/configure.ac
index 6bc1ab4c2..f30fd062b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -140,7 +140,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"
@@ -213,7 +212,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 libdrm"
+MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server 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 8df85fbd7..d2daf0835 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,6 +39,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/mutter-wayland.desktop.in b/src/mutter-wayland.desktop.in
index 9f213166a..3bf5f2330 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 000000000..924e397a4
--- /dev/null
+++ b/src/org.freedesktop.login1.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/wayland/meta-login1.c b/src/wayland/meta-login1.c
new file mode 100644
index 000000000..024fd0050
--- /dev/null
+++ b/src/wayland/meta-login1.c
@@ -0,0 +1,439 @@
+/*
+ * 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 "meta-wayland-private.h"
+#include "meta-cursor-tracker-private.h"
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+struct _MetaLogin1
+{
+ Login1Session *session_proxy;
+ Login1Seat *seat_proxy;
+
+ gboolean session_active;
+};
+
+/* 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);
+}
+
+static char *
+get_escaped_dbus_path (const char *prefix,
+ const char *component)
+{
+ char *escaped_component = escape_dbus_component (component);
+ char *path = g_strconcat (prefix, "/", component, NULL);
+
+ g_free (escaped_component);
+ return path;
+}
+
+static Login1Session *
+get_session_proxy (GCancellable *cancellable)
+{
+ char *proxy_path;
+ char *session_id;
+ Login1Session *session_proxy;
+
+ if (sd_pid_get_session (getpid (), &session_id) < 0)
+ return NULL;
+
+ proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
+
+ 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);
+
+ return session_proxy;
+}
+
+static Login1Seat *
+get_seat_proxy (GCancellable *cancellable)
+{
+ 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);
+}
+
+static void
+session_unpause (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_set_paused (FALSE);
+ clutter_evdev_reclaim_devices ();
+
+ {
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+
+ /* When we mode-switch back, we need to immediately queue a redraw
+ * in case nothing else quueed one for us, and force the cursor to
+ * update. */
+
+ clutter_actor_queue_redraw (compositor->stage);
+ meta_cursor_tracker_force_update (compositor->seat->cursor_tracker);
+ }
+}
+
+static void
+session_pause (void)
+{
+ clutter_set_paused (TRUE);
+ clutter_evdev_release_devices ();
+}
+
+static void
+sync_active (MetaLogin1 *self)
+{
+ gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
+
+ if (active == self->session_active)
+ return;
+
+ self->session_active = active;
+
+ if (active)
+ session_unpause ();
+ else
+ session_pause ();
+}
+
+static void
+on_active_changed (Login1Session *session,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ MetaLogin1 *self = user_data;
+ sync_active (self);
+}
+
+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
+open_evdev_device (const char *path,
+ int flags,
+ gpointer user_data,
+ GError **error)
+{
+ MetaLogin1 *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 fd;
+}
+
+static void
+close_evdev_device (int fd,
+ gpointer user_data)
+{
+ MetaLogin1 *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);
+ }
+}
+
+static gboolean
+get_kms_fd (Login1Session *session_proxy,
+ int *fd_out)
+{
+ int major, minor;
+ int fd;
+ GError *error = NULL;
+
+ /* XXX -- use udev to find the DRM master device */
+ if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
+ {
+ g_warning ("Could not stat /dev/dri/card0: %m");
+ return FALSE;
+ }
+
+ if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
+ {
+ g_warning ("Could not open DRM device: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ *fd_out = fd;
+
+ return TRUE;
+}
+
+MetaLogin1 *
+meta_login1_new (void)
+{
+ MetaLogin1 *self;
+ Login1Session *session_proxy;
+ GError *error = NULL;
+ int kms_fd;
+
+ 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;
+ }
+
+ if (!get_kms_fd (session_proxy, &kms_fd))
+ return NULL;
+
+ self = g_slice_new0 (MetaLogin1);
+ self->session_proxy = session_proxy;
+ self->seat_proxy = get_seat_proxy (NULL);
+
+ self->session_active = TRUE;
+
+ clutter_egl_native_set_kms_fd (kms_fd);
+ clutter_evdev_set_open_callback (open_evdev_device,
+ close_evdev_device,
+ 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->seat_proxy);
+ 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_seat_call_switch_to_sync (self->seat_proxy, vt, NULL, error);
+}
diff --git a/src/wayland/meta-weston-launch.h b/src/wayland/meta-login1.h
similarity index 58%
rename from src/wayland/meta-weston-launch.h
rename to src/wayland/meta-login1.h
index b70faf88e..0fed20539 100644
--- a/src/wayland/meta-weston-launch.h
+++ b/src/wayland/meta-login1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Red Hat, Inc.
+ * 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
@@ -17,18 +17,19 @@
* 02111-1307, USA.
*/
-#ifndef META_WESTON_LAUNCH_H
-#define META_WESTON_LAUNCH_H
+#ifndef META_LOGIN1_H
+#define META_LOGIN1_H
#include
-#include "weston-launch.h"
-typedef struct _MetaLauncher MetaLauncher;
+typedef struct _MetaLogin1 MetaLogin1;
-MetaLauncher *meta_launcher_new (void);
-void meta_launcher_free (MetaLauncher *self);
+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);
-gboolean meta_launcher_activate_vt (MetaLauncher *self,
- signed char vt,
- GError **error);
#endif
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index a2a2b90a5..d9120b190 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -27,7 +27,7 @@
#include
#include "window-private.h"
-#include "meta-weston-launch.h"
+#include "meta-login1.h"
#include
#include "meta-wayland.h"
@@ -85,7 +85,7 @@ struct _MetaWaylandCompositor
MetaXWaylandManager xwayland_manager;
- MetaLauncher *launcher;
+ MetaLogin1 *login1;
MetaWaylandSeat *seat;
};
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index a13a920ae..d6ff43f9f 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -52,7 +52,7 @@
#include
#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;
@@ -644,10 +644,10 @@ 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 weston-launch. */
+ * 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)
@@ -704,8 +704,8 @@ meta_wayland_finalize (void)
meta_xwayland_stop (&compositor->xwayland_manager);
- if (compositor->launcher)
- meta_launcher_free (compositor->launcher);
+ if (compositor->login1)
+ meta_login1_free (compositor->login1);
}
gboolean
@@ -713,9 +713,9 @@ meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
int vt,
GError **error)
{
- if (compositor->launcher)
+ if (compositor->login1)
{
- return meta_launcher_activate_vt (compositor->launcher, vt, error);
+ return meta_login1_activate_vt (compositor->login1, vt, error);
}
else
{
@@ -728,9 +728,9 @@ gboolean
meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
GError **error)
{
- if (compositor->launcher)
+ if (compositor->login1)
{
- return meta_launcher_activate_vt (compositor->launcher, -1, error);
+ return meta_login1_activate_session (compositor->login1, error);
}
else
{
diff --git a/src/wayland/meta-weston-launch.c b/src/wayland/meta-weston-launch.c
deleted file mode 100644
index 889714dcc..000000000
--- a/src/wayland/meta-weston-launch.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2013 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
-
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "meta-wayland-private.h"
-#include "meta-cursor-tracker-private.h"
-#include "meta-weston-launch.h"
-
-struct _MetaLauncher
-{
- GSocket *weston_launch;
- GSource *weston_launch_source;
-
- gboolean vt_switched;
-};
-
-static void handle_request_vt_switch (MetaLauncher *self);
-
-static gboolean
-request_vt_switch_idle (gpointer user_data)
-{
- handle_request_vt_switch (user_data);
-
- return FALSE;
-}
-
-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;
-
- while (reply.header.opcode != ((struct weston_launcher_message*)message)->opcode)
- {
- /* 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:
- g_idle_add (request_vt_switch_idle, self);
- 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;
- }
-
- 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;
-}
-
-static int
-meta_launcher_open_device (MetaLauncher *self,
- const char *name,
- int flags,
- GError **error)
-{
- 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;
-}
-
-static void
-meta_launcher_enter (MetaLauncher *launcher)
-{
- 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 ();
- clutter_set_paused (FALSE);
-
- {
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
-
- /* When we mode-switch back, we need to immediately queue a redraw
- * in case nothing else queued one for us, and force the cursor to
- * update. */
-
- clutter_actor_queue_redraw (compositor->stage);
- meta_cursor_tracker_force_update (compositor->seat->cursor_tracker);
- }
-}
-
-static void
-meta_launcher_leave (MetaLauncher *launcher)
-{
- clutter_evdev_release_devices ();
- clutter_set_paused (TRUE);
-}
-
-static int
-on_evdev_device_open (const char *path,
- int flags,
- gpointer user_data,
- GError **error)
-{
- MetaLauncher *launcher = user_data;
-
- return meta_launcher_open_device (launcher, path, flags, error);
-}
-
-static void
-on_evdev_device_close (int fd,
- gpointer user_data)
-{
- close (fd);
-}
-
-static void
-handle_vt_enter (MetaLauncher *launcher)
-{
- g_assert (launcher->vt_switched);
- launcher->vt_switched = FALSE;
-
- meta_launcher_enter (launcher);
-}
-
-static void
-handle_request_vt_switch (MetaLauncher *launcher)
-{
- struct weston_launcher_message message;
- GError *error;
- gboolean ok;
-
- meta_launcher_leave (launcher);
-
- 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;
-}
-
-static gboolean
-on_socket_readable (GSocket *socket,
- GIOCondition condition,
- gpointer user_data)
-{
- MetaLauncher *launcher = user_data;
- struct weston_launcher_event event;
- gssize read;
- GError *error;
-
- if ((condition & G_IO_IN) == 0)
- return TRUE;
-
- error = NULL;
- read = g_socket_receive (socket, (char*)&event, sizeof(event), NULL, &error);
- if (read < (gssize)sizeof(event))
- {
- g_warning ("Error reading from weston-launcher socket: %s", error->message);
- g_error_free (error);
- return TRUE;
- }
-
- switch (event.header.opcode)
- {
- case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
- handle_request_vt_switch (launcher);
- break;
-
- case WESTON_LAUNCHER_SERVER_VT_ENTER:
- handle_vt_enter (launcher);
- break;
- }
-
- return TRUE;
-}
-
-static int
-env_get_fd (const char *env)
-{
- const char *value;
-
- value = g_getenv (env);
-
- if (value == NULL)
- return -1;
- else
- return g_ascii_strtoll (value, NULL, 10);
-}
-
-MetaLauncher *
-meta_launcher_new (void)
-{
- MetaLauncher *self = g_slice_new0 (MetaLauncher);
- int launch_fd;
-
- launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK");
- if (launch_fd < 0)
- g_error ("Invalid mutter-launch socket");
-
- self->weston_launch = g_socket_new_from_fd (launch_fd, 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);
-
- clutter_evdev_set_open_callback (on_evdev_device_open,
- on_evdev_device_close,
- self);
-
-#if defined(CLUTTER_WINDOWING_EGL)
- if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
- {
- GError *error = NULL;
- int 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);
-
- clutter_egl_native_set_kms_fd (fd);
- }
-#endif
-
- return self;
-}
-
-void
-meta_launcher_free (MetaLauncher *launcher)
-{
- g_source_destroy (launcher->weston_launch_source);
- g_object_unref (launcher->weston_launch);
- g_slice_free (MetaLauncher, launcher);
-}
-
-gboolean
-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);
-}
-
diff --git a/src/wayland/weston-launch.c b/src/wayland/weston-launch.c
deleted file mode 100644
index ae713ed23..000000000
--- a/src/wayland/weston-launch.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * Copyright © 2012 Benjamin Franzke
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. The copyright holders make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "config.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-
-#include
-
-#include "weston-launch.h"
-
-#define MAX_ARGV_SIZE 256
-#define DRM_MAJOR 226
-
-enum vt_state {
- VT_HAS_VT,
- VT_PENDING_CONFIRM,
- VT_NOT_HAVE_VT,
-};
-
-struct weston_launch {
- int tty;
- int ttynr;
- int sock[2];
- struct passwd *pw;
-
- int signalfd;
-
- pid_t child;
- int verbose;
-
- struct termios terminal_attributes;
- int kb_mode;
- enum vt_state vt_state;
- unsigned vt;
-
- int drm_fd;
-};
-
-union cmsg_data { unsigned char b[4]; int fd; };
-
-static void quit (struct weston_launch *wl, int status);
-
-static int
-weston_launch_allowed(struct weston_launch *wl)
-{
- char *session, *seat;
- int err;
-
- if (getuid() == 0)
- return 1;
-
- err = sd_pid_get_session(getpid(), &session);
- if (err == 0 && session) {
- if (sd_session_is_active(session) &&
- sd_session_get_seat(session, &seat) == 0) {
- free(seat);
- free(session);
- return 1;
- }
- free(session);
- }
-
- return 0;
-}
-
-static int
-setup_launcher_socket(struct weston_launch *wl)
-{
- if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, wl->sock) < 0)
- error(1, errno, "socketpair failed");
-
- fcntl(wl->sock[0], F_SETFD, O_CLOEXEC);
-
- return 0;
-}
-
-static int
-setup_signals(struct weston_launch *wl)
-{
- int ret;
- sigset_t mask;
- struct sigaction sa;
-
- memset(&sa, 0, sizeof sa);
- sa.sa_handler = SIG_DFL;
- sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
- ret = sigaction(SIGCHLD, &sa, NULL);
- assert(ret == 0);
-
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- sigaction(SIGHUP, &sa, NULL);
-
- ret = sigemptyset(&mask);
- assert(ret == 0);
- sigaddset(&mask, SIGCHLD);
- sigaddset(&mask, SIGINT);
- sigaddset(&mask, SIGTERM);
- sigaddset(&mask, SIGUSR1);
- ret = sigprocmask(SIG_BLOCK, &mask, NULL);
- assert(ret == 0);
-
- wl->signalfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
- if (wl->signalfd < 0)
- return -errno;
-
- return 0;
-}
-
-static void
-setenv_fd(const char *env, int fd)
-{
- char buf[32];
-
- snprintf(buf, sizeof buf, "%d", fd);
- setenv(env, buf, 1);
-}
-
-static int
-handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
-{
- struct weston_launcher_reply reply;
-
- reply.header.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
- reply.ret = -1;
-
- if (wl->vt_state != VT_PENDING_CONFIRM) {
- error(0, 0, "unexpected CONFIRM_VT_SWITCH");
- goto out;
- }
-
- if (wl->drm_fd != -1) {
- int ret;
-
- ret = drmDropMaster(wl->drm_fd);
- if (ret < 0) {
- fprintf(stderr, "failed to drop DRM master: %m\n");
- } else if (wl->verbose) {
- fprintf(stderr, "dropped DRM master for VT switch\n");
- }
- }
-
- wl->vt_state = VT_NOT_HAVE_VT;
- ioctl(wl->tty, VT_RELDISP, 1);
-
- if (wl->verbose)
- fprintf(stderr, "mutter-launcher: confirmed VT switch\n");
-
- reply.ret = 0;
-
-out:
- do {
- len = send(wl->sock[0], &reply, sizeof reply, 0);
- } while (len < 0 && errno == EINTR);
- if (len < 0)
- return -1;
-
- return 0;
-}
-
-static int
-handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
-{
- struct weston_launcher_reply reply;
- struct weston_launcher_activate_vt *message;
- unsigned vt;
-
- reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
- reply.ret = -1;
-
- if (len != sizeof(*message)) {
- error(0, 0, "missing value in activate_vt request");
- goto out;
- }
-
- message = msg->msg_iov->iov_base;
-
- /* Negative values mean that we're activating our own VT */
- if (message->vt > 0)
- vt = message->vt;
- else
- vt = wl->vt;
-
- reply.ret = ioctl(wl->tty, VT_ACTIVATE, vt);
- if (reply.ret < 0)
- reply.ret = -errno;
-
- if (wl->verbose)
- fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret);
-
-out:
- do {
- len = send(wl->sock[0], &reply, sizeof reply, 0);
- } while (len < 0 && errno == EINTR);
- if (len < 0)
- return -1;
-
- return 0;
-}
-
-
-static int
-handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
-{
- struct weston_launcher_reply reply;
- int fd = -1;
- char control[CMSG_SPACE(sizeof(fd))];
- struct cmsghdr *cmsg;
- struct stat s;
- struct msghdr nmsg;
- struct iovec iov;
- struct weston_launcher_open *message;
- union cmsg_data *data;
- int dev_major;
-
- reply.header.opcode = WESTON_LAUNCHER_OPEN;
- reply.ret = -1;
-
- message = msg->msg_iov->iov_base;
- if ((size_t)len < sizeof(*message))
- goto err0;
-
- /* Ensure path is null-terminated */
- ((char *) message)[len-1] = '\0';
-
- if (stat(message->path, &s) < 0) {
- reply.ret = -errno;
- goto err0;
- }
-
- dev_major = major(s.st_rdev);
-
- if (dev_major != INPUT_MAJOR ||
- dev_major != DRM_MAJOR) {
- fprintf(stderr, "Device %s is not an input or DRM device\n",
- message->path);
- reply.ret = -EPERM;
- goto err0;
- }
-
- if (dev_major == DRM_MAJOR && wl->drm_fd != -1) {
- fprintf(stderr, "Already have a DRM device open\n");
- reply.ret = -EPERM;
- goto err0;
- }
-
- fd = open(message->path, message->flags);
- if (fd < 0) {
- fprintf(stderr, "Error opening device %s: %m\n",
- message->path);
- reply.ret = -errno;
- goto err0;
- }
-
- if (dev_major == DRM_MAJOR) {
- wl->drm_fd = fd;
- }
-
-err0:
- memset(&nmsg, 0, sizeof nmsg);
- nmsg.msg_iov = &iov;
- nmsg.msg_iovlen = 1;
- if (fd != -1) {
- nmsg.msg_control = control;
- nmsg.msg_controllen = sizeof control;
- cmsg = CMSG_FIRSTHDR(&nmsg);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
- data = (union cmsg_data *) CMSG_DATA(cmsg);
- data->fd = fd;
- nmsg.msg_controllen = cmsg->cmsg_len;
- reply.ret = 0;
- }
- iov.iov_base = &reply;
- iov.iov_len = sizeof reply;
-
- if (wl->verbose)
- fprintf(stderr, "mutter-launch: opened %s: ret: %d, fd: %d\n",
- message->path, reply.ret, fd);
- do {
- len = sendmsg(wl->sock[0], &nmsg, 0);
- } while (len < 0 && errno == EINTR);
-
- close(fd);
-
- if (len < 0)
- return -1;
-
- return 0;
-}
-
-static int
-handle_socket_msg(struct weston_launch *wl)
-{
- char control[CMSG_SPACE(sizeof(int))];
- char buf[BUFSIZ];
- struct msghdr msg;
- struct iovec iov;
- int ret = -1;
- ssize_t len;
- struct weston_launcher_message *message;
-
- memset(&msg, 0, sizeof(msg));
- iov.iov_base = buf;
- iov.iov_len = sizeof buf;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = control;
- msg.msg_controllen = sizeof control;
-
- do {
- len = recvmsg(wl->sock[0], &msg, 0);
- } while (len < 0 && errno == EINTR);
-
- if (len < 1)
- return -1;
-
- message = (void *) buf;
- switch (message->opcode) {
- case WESTON_LAUNCHER_OPEN:
- ret = handle_open(wl, &msg, len);
- break;
- case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
- ret = handle_confirm_vt_switch(wl, &msg, len);
- break;
- case WESTON_LAUNCHER_ACTIVATE_VT:
- ret = handle_activate_vt(wl, &msg, len);
- break;
- }
-
- return ret;
-}
-
-static void
-tty_reset(struct weston_launch *wl)
-{
- struct vt_mode mode = { 0 };
-
- if (ioctl(wl->tty, KDSKBMODE, wl->kb_mode))
- fprintf(stderr, "failed to restore keyboard mode: %m\n");
-
- if (ioctl(wl->tty, KDSETMODE, KD_TEXT))
- fprintf(stderr, "failed to set KD_TEXT mode on tty: %m\n");
-
- if (tcsetattr(wl->tty, TCSANOW, &wl->terminal_attributes) < 0)
- fprintf(stderr, "could not restore terminal to canonical mode\n");
-
- mode.mode = VT_AUTO;
- if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
- fprintf(stderr, "could not reset vt handling\n");
-}
-
-static void
-quit(struct weston_launch *wl, int status)
-{
- if (wl->child > 0)
- kill(wl->child, SIGKILL);
-
- close(wl->signalfd);
- close(wl->sock[0]);
-
- if (wl->drm_fd > 0)
- close(wl->drm_fd);
-
- tty_reset(wl);
-
- exit(status);
-}
-
-static int
-handle_vt_switch(struct weston_launch *wl)
-{
- struct weston_launcher_event message;
- ssize_t len;
-
- if (wl->vt_state == VT_HAS_VT) {
- wl->vt_state = VT_PENDING_CONFIRM;
- message.header.opcode = WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH;
- } else if (wl->vt_state == VT_NOT_HAVE_VT) {
- wl->vt_state = VT_HAS_VT;
- ioctl(wl->tty, VT_RELDISP, VT_ACKACQ);
-
- if (wl->drm_fd != -1) {
- int ret;
-
- ret = drmSetMaster(wl->drm_fd);
- if (ret < 0) {
- fprintf(stderr, "failed to become DRM master: %m\n");
- /* This is very, very bad, and the compositor will crash soon,
- but oh well... */
- } else if (wl->verbose) {
- fprintf(stderr, "became DRM master after VT switch\n");
- }
- }
-
- message.header.opcode = WESTON_LAUNCHER_SERVER_VT_ENTER;
- } else
- return -1;
-
- message.detail = 0;
-
- do {
- len = send(wl->sock[0], &message, sizeof(message), 0);
- } while (len < 0 && errno == EINTR);
-
- return 0;
-}
-
-
-static int
-handle_signal(struct weston_launch *wl)
-{
- struct signalfd_siginfo sig;
- int pid, status, ret;
-
- if (read(wl->signalfd, &sig, sizeof sig) != sizeof sig) {
- error(0, errno, "reading signalfd failed");
- return -1;
- }
-
- switch (sig.ssi_signo) {
- case SIGCHLD:
- pid = waitpid(-1, &status, 0);
- if (pid == wl->child) {
- wl->child = 0;
- if (WIFEXITED(status))
- ret = WEXITSTATUS(status);
- else if (WIFSIGNALED(status))
- /*
- * If weston dies because of signal N, we
- * return 10+N. This is distinct from
- * weston-launch dying because of a signal
- * (128+N).
- */
- ret = 10 + WTERMSIG(status);
- else
- ret = 0;
- quit(wl, ret);
- }
- break;
- case SIGTERM:
- case SIGINT:
- if (wl->child)
- kill(wl->child, sig.ssi_signo);
- break;
- case SIGUSR1:
- return handle_vt_switch(wl);
- default:
- return -1;
- }
-
- return 0;
-}
-
-static int
-setup_tty(struct weston_launch *wl)
-{
- struct stat buf;
- struct termios raw_attributes;
- struct vt_mode mode = { 0 };
- char *session;
- char path[PATH_MAX];
- int ok;
-
- ok = sd_pid_get_session(getpid(), &session);
- if (ok < 0)
- error(1, -ok, "could not determine current session");
-
- ok = sd_session_get_vt(session, &wl->vt);
- if (ok < 0)
- error(1, -ok, "could not determine current TTY");
-
- snprintf(path, PATH_MAX, "/dev/tty%u", wl->vt);
- wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
-
- if (wl->tty < 0)
- error(1, errno, "failed to open tty");
-
- if (fstat(wl->tty, &buf) < 0)
- error(1, errno, "stat %s failed", path);
-
- if (major(buf.st_rdev) != TTY_MAJOR)
- error(1, 0, "invalid tty device: %s", path);
-
- wl->ttynr = minor(buf.st_rdev);
-
- if (tcgetattr(wl->tty, &wl->terminal_attributes) < 0)
- error(1, errno, "could not get terminal attributes");
-
- /* Ignore control characters and disable echo */
- raw_attributes = wl->terminal_attributes;
- cfmakeraw(&raw_attributes);
-
- /* Fix up line endings to be normal (cfmakeraw hoses them) */
- raw_attributes.c_oflag |= OPOST | OCRNL;
- /* Don't generate ttou signals */
- raw_attributes.c_oflag &= ~TOSTOP;
-
- if (tcsetattr(wl->tty, TCSANOW, &raw_attributes) < 0)
- error(1, errno, "could not put terminal into raw mode");
-
- ioctl(wl->tty, KDGKBMODE, &wl->kb_mode);
- ok = ioctl(wl->tty, KDSKBMODE, K_OFF);
- if (ok < 0) {
- ok = ioctl(wl->tty, KDSKBMODE, K_RAW);
- if (ok < 0)
- error(1, errno, "failed to set keyboard mode on tty");
- }
-
- ok = ioctl(wl->tty, KDSETMODE, KD_GRAPHICS);
- if (ok < 0)
- error(1, errno, "failed to set KD_GRAPHICS mode on tty");
-
- wl->vt_state = VT_HAS_VT;
- mode.mode = VT_PROCESS;
- mode.relsig = SIGUSR1;
- mode.acqsig = SIGUSR1;
- ok = ioctl(wl->tty, VT_SETMODE, &mode);
- if (ok < 0)
- error(1, errno, "failed to take control of vt handling");
-
- return 0;
-}
-
-static void
-drop_privileges(struct weston_launch *wl)
-{
- if (setgid(wl->pw->pw_gid) < 0 ||
-#ifdef HAVE_INITGROUPS
- initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
-#endif
- setuid(wl->pw->pw_uid) < 0)
- error(1, errno, "dropping privileges failed");
-}
-
-static void
-launch_compositor(struct weston_launch *wl, int argc, char *argv[])
-{
- char command[PATH_MAX];
- char *child_argv[MAX_ARGV_SIZE];
- sigset_t mask;
- int i;
-
- if (wl->verbose)
- printf("weston-launch: spawned weston with pid: %d\n", getpid());
-
- drop_privileges(wl);
-
- setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
- setenv("LD_LIBRARY_PATH", LIBDIR, 1);
- unsetenv("DISPLAY");
-
- /* Do not give our signal mask to the new process. */
- sigemptyset(&mask);
- sigaddset(&mask, SIGTERM);
- sigaddset(&mask, SIGCHLD);
- sigaddset(&mask, SIGINT);
- sigaddset(&mask, SIGUSR1);
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
-
- snprintf (command, PATH_MAX, "%s \"$@\"", argv[0]);
-
- child_argv[0] = wl->pw->pw_shell;
- child_argv[1] = "-l";
- child_argv[2] = "-c";
- child_argv[3] = command;
- for (i = 0; i < argc; ++i)
- child_argv[4 + i] = argv[i];
- child_argv[4 + i] = NULL;
-
- execv(child_argv[0], child_argv);
- error(1, errno, "exec failed");
-}
-
-static void
-help(const char *name)
-{
- fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
- fprintf(stderr, " -u, --user Start session as specified username\n");
- fprintf(stderr, " -v, --verbose Be verbose\n");
- fprintf(stderr, " -h, --help Display this help message\n");
-}
-
-int
-main(int argc, char *argv[])
-{
- struct weston_launch wl;
- int i, c;
- struct option opts[] = {
- { "verbose", no_argument, NULL, 'v' },
- { "help", no_argument, NULL, 'h' },
- { 0, 0, NULL, 0 }
- };
-
- memset(&wl, 0, sizeof wl);
- wl.drm_fd = -1;
-
- while ((c = getopt_long(argc, argv, "u:t::vh", opts, &i)) != -1) {
- switch (c) {
- case 'v':
- wl.verbose = 1;
- break;
- case 'h':
- help("mutter-launch");
- exit(EXIT_FAILURE);
- }
- }
-
- if ((argc - optind) > (MAX_ARGV_SIZE - 6))
- error(1, E2BIG, "Too many arguments to pass to weston");
-
- if (optind >= argc)
- error(1, 0, "Expected program argument");
-
- wl.pw = getpwuid(getuid());
- if (wl.pw == NULL)
- error(1, errno, "failed to get username");
-
- if (!weston_launch_allowed(&wl))
- error(1, 0, "Permission denied. You must run from an active and local (systemd) session.");
-
- if (setup_tty(&wl) < 0)
- exit(EXIT_FAILURE);
-
- if (setup_launcher_socket(&wl) < 0)
- exit(EXIT_FAILURE);
-
- if (setup_signals(&wl) < 0)
- exit(EXIT_FAILURE);
-
- wl.child = fork();
- if (wl.child == -1) {
- error(1, errno, "fork failed");
- exit(EXIT_FAILURE);
- }
-
- if (wl.child == 0)
- launch_compositor(&wl, argc - optind, argv + optind);
-
- close(wl.sock[1]);
-
- while (1) {
- struct pollfd fds[2];
- int n;
-
- fds[0].fd = wl.sock[0];
- fds[0].events = POLLIN;
- fds[1].fd = wl.signalfd;
- fds[1].events = POLLIN;
-
- n = poll(fds, 2, -1);
- if (n < 0)
- error(0, errno, "poll failed");
- if (fds[0].revents & POLLIN)
- handle_socket_msg(&wl);
- if (fds[1].revents)
- handle_signal(&wl);
- }
-
- return 0;
-}
diff --git a/src/wayland/weston-launch.h b/src/wayland/weston-launch.h
deleted file mode 100644
index 1e716c5ac..000000000
--- a/src/wayland/weston-launch.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright © 2012 Benjamin Franzke
- * 2013 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. The copyright holders make
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _WESTON_LAUNCH_H_
-#define _WESTON_LAUNCH_H_
-
-enum weston_launcher_message_type {
- WESTON_LAUNCHER_REQUEST,
- WESTON_LAUNCHER_EVENT,
-};
-
-enum weston_launcher_opcode {
- WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
- WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST),
- WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
-};
-
-enum weston_launcher_server_opcode {
- WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH = (1 << 1 | WESTON_LAUNCHER_EVENT),
- WESTON_LAUNCHER_SERVER_VT_ENTER = (2 << 1 | WESTON_LAUNCHER_EVENT),
-};
-
-struct weston_launcher_message {
- int opcode;
-};
-
-struct weston_launcher_open {
- struct weston_launcher_message header;
- int flags;
- char path[0];
-};
-
-struct weston_launcher_activate_vt {
- struct weston_launcher_message header;
- signed char vt;
-};
-
-struct weston_launcher_reply {
- struct weston_launcher_message header;
- int ret;
-};
-
-struct weston_launcher_event {
- struct weston_launcher_message header;
- int detail; /* unused, but makes sure replies and events are serialized the same */
-};
-
-#endif