#log-directory=/var/log/lightdm
#run-directory=/var/run/lightdm
#cache-directory=/var/cache/lightdm
-#sessions-directory=/usr/share/lightdm/sessions:/usr/share/xsessions
+#sessions-directory=/usr/share/lightdm/sessions:/usr/share/xsessions:/usr/share/wayland-sessions
#remote-sessions-directory=/usr/share/lightdm/remote-sessions
#greeters-directory=/usr/share/lightdm/greeters:/usr/share/xgreeters
$(WARN_CFLAGS) \
-I"$(top_srcdir)/common" \
-DCONFIG_DIR=\"$(sysconfdir)/lightdm\" \
- -DSESSIONS_DIR=\"$(pkgdatadir)/sessions:$(datadir)/xsessions\" \
+ -DSESSIONS_DIR=\"$(pkgdatadir)/sessions:$(datadir)/xsessions:$(datadir)/wayland-sessions\" \
+ -DWAYLAND_SESSIONS_DIR=\"$(datadir)/wayland-sessions\" \
-DREMOTE_SESSIONS_DIR=\"$(pkgdatadir)/remote-sessions\"
mainheader_HEADERS = lightdm.h
}
static LightDMSession *
-load_session (GKeyFile *key_file, const gchar *key)
+load_session (GKeyFile *key_file, const gchar *key, const gchar *default_type)
{
- gchar *type, *domain, *name;
+ gchar *domain, *name, *type;
LightDMSession *session;
LightDMSessionPrivate *priv;
gchar *try_exec;
g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL))
return NULL;
- type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-Session-Type", NULL);
- if (!type)
- type = "x";
-
#ifdef G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN
domain = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, NULL);
#else
g_free (full_path);
}
+ type = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-Session-Type", NULL);
+ if (!type)
+ type = strdup (default_type);
+
session = g_object_new (LIGHTDM_TYPE_SESSION, NULL);
priv = GET_PRIVATE (session);
priv->key = g_strdup (key);
g_free (priv->type);
- priv->type = g_strdup (type);
+ priv->type = type;
g_free (priv->name);
priv->name = name;
}
static GList *
-load_sessions_dir (GList *sessions, const gchar *sessions_dir)
+load_sessions_dir (GList *sessions, const gchar *sessions_dir, const gchar *default_type)
{
GDir *directory;
GError *error = NULL;
LightDMSession *session;
key = g_strndup (filename, strlen (filename) - strlen (".desktop"));
- session = load_session (key_file, key);
+ session = load_session (key_file, key, default_type);
if (session)
{
g_debug ("Loaded session %s (%s, %s)", path, GET_PRIVATE (session)->name, GET_PRIVATE (session)->comment);
int i;
dirs = g_strsplit (sessions_dir, ":", -1);
- for (i = 0; dirs[i]; i++)
- sessions = load_sessions_dir (sessions, dirs[i]);
+ for (i = 0; dirs[i]; i++)
+ {
+ const gchar *default_type = "x";
+
+ if (strcmp (dirs[i], WAYLAND_SESSIONS_DIR) == 0)
+ default_type = "wayland";
+
+ sessions = load_sessions_dir (sessions, dirs[i], default_type);
+ }
+
g_strfreev (dirs);
return sessions;
$(WARN_CXXFLAGS) \
-I$(top_srcdir)/liblightdm-gobject \
$(GLIB_CFLAGS) \
- -DQT_NO_KEYWORDS \
- -DXSESSIONS_DIR=\"$(datadir)/xsessions\"
+ -DQT_NO_KEYWORDS
liblightdm_qt_3_la_CXXFLAGS = \
$(LIBLIGHTDM_QT4_CFLAGS) \
$(common_cflags)
vnc-server.h \
vt.c \
vt.h \
+ wayland-session.c \
+ wayland-session.h \
x-authority.c \
x-authority.h \
x-server-local.c \
-DLOG_DIR=\"$(localstatedir)/log/lightdm\" \
-DRUN_DIR=\"$(localstatedir)/run/lightdm\" \
-DCACHE_DIR=\"$(localstatedir)/cache/lightdm\" \
- -DSESSIONS_DIR=\"$(pkgdatadir)/sessions:$(datadir)/xsessions\" \
+ -DSESSIONS_DIR=\"$(pkgdatadir)/sessions:$(datadir)/xsessions:$(datadir)/wayland-sessions\" \
+ -DWAYLAND_SESSIONS_DIR=\"$(datadir)/wayland-sessions\" \
-DREMOTE_SESSIONS_DIR=\"$(pkgdatadir)/remote-sessions\" \
-DGREETERS_DIR=\"$(pkgdatadir)/greeters:$(datadir)/xgreeters\"
#include "configuration.h"
#include "x-server-local.h"
#include "unity-system-compositor.h"
+#include "wayland-session.h"
#include "plymouth.h"
#include "vt.h"
return DISPLAY_SERVER (compositor);
}
+static DisplayServer *
+create_wayland_session (Seat *seat)
+{
+ WaylandSession *session;
+ gint vt;
+
+ session = wayland_session_new ();
+
+ vt = get_vt (seat, DISPLAY_SERVER (session));
+ if (vt >= 0)
+ wayland_session_set_vt (session, vt);
+
+ return DISPLAY_SERVER (session);
+}
+
static DisplayServer *
seat_xlocal_create_display_server (Seat *seat, Session *session)
{
return DISPLAY_SERVER (create_x_server (seat));
else if (strcmp (session_type, "mir") == 0)
return create_unity_system_compositor (seat);
+ else if (strcmp (session_type, "wayland") == 0)
+ return create_wayland_session (seat);
else if (strcmp (session_type, "mir-container") == 0)
{
DisplayServer *compositor;
for (i = 0; dirs[i]; i++)
{
gchar *filename, *path;
+ const gchar *default_session_type = "x";
+
+ if (strcmp (dirs[i], WAYLAND_SESSIONS_DIR) == 0)
+ default_session_type = "wayland";
filename = g_strdup_printf ("%s.desktop", session_name);
path = g_build_filename (dirs[i], filename, NULL);
g_free (filename);
- session_config = session_config_new_from_file (path, &error);
+ session_config = session_config_new_from_file (path, default_session_type, &error);
g_free (path);
if (session_config)
break;
G_DEFINE_TYPE (SessionConfig, session_config, G_TYPE_OBJECT);
SessionConfig *
-session_config_new_from_file (const gchar *filename, GError **error)
+session_config_new_from_file (const gchar *filename, const gchar *default_session_type, GError **error)
{
GKeyFile *desktop_file;
SessionConfig *config;
config->priv->command = command;
config->priv->session_type = g_key_file_get_string (desktop_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-Session-Type", NULL);
if (!config->priv->session_type)
- config->priv->session_type = g_strdup ("x");
+ config->priv->session_type = g_strdup (default_session_type);
config->priv->desktop_names = g_key_file_get_string_list (desktop_file, G_KEY_FILE_DESKTOP_GROUP, "DesktopNames", NULL, NULL);
if (!config->priv->desktop_names)
GType session_config_get_type (void);
-SessionConfig *session_config_new_from_file (const gchar *filename, GError **error);
+SessionConfig *session_config_new_from_file (const gchar *filename, const gchar *default_session_type, GError **error);
const gchar *session_config_get_command (SessionConfig *config);
--- /dev/null
+/*
+ * Copyright (C) 2015 Canonical Ltd.
+ * Author: Robert Ancell <robert.ancell@canonical.com>
+ *
+ * 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 3 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+#include "wayland-session.h"
+#include "vt.h"
+
+struct WaylandSessionPrivate
+{
+ /* VT to run on */
+ gint vt;
+ gboolean have_vt_ref;
+};
+
+G_DEFINE_TYPE (WaylandSession, wayland_session, DISPLAY_SERVER_TYPE);
+
+WaylandSession *
+wayland_session_new (void)
+{
+ return g_object_new (WAYLAND_SESSION_TYPE, NULL);
+}
+
+void
+wayland_session_set_vt (WaylandSession *session, gint vt)
+{
+ g_return_if_fail (session != NULL);
+
+ if (session->priv->have_vt_ref)
+ vt_unref (session->priv->vt);
+ session->priv->have_vt_ref = FALSE;
+ session->priv->vt = vt;
+ if (vt > 0)
+ {
+ vt_ref (vt);
+ session->priv->have_vt_ref = TRUE;
+ }
+}
+
+static gint
+wayland_session_get_vt (DisplayServer *server)
+{
+ g_return_val_if_fail (server != NULL, 0);
+ return WAYLAND_SESSION (server)->priv->vt;
+}
+
+static void
+wayland_session_connect_session (DisplayServer *display_server, Session *session)
+{
+ WaylandSession *wayland_session = WAYLAND_SESSION (display_server);
+
+ session_set_env (session, "XDG_SESSION_TYPE", "wayland");
+
+ if (wayland_session->priv->vt >= 0)
+ {
+ gchar *value = g_strdup_printf ("%d", wayland_session->priv->vt);
+ session_set_env (session, "XDG_VTNR", value);
+ g_free (value);
+ }
+}
+
+static void
+wayland_session_disconnect_session (DisplayServer *display_server, Session *session)
+{
+ session_unset_env (session, "XDG_SESSION_TYPE");
+ session_unset_env (session, "XDG_VTNR");
+}
+
+static void
+wayland_session_init (WaylandSession *session)
+{
+ session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session, WAYLAND_SESSION_TYPE, WaylandSessionPrivate);
+}
+
+static void
+wayland_session_finalize (GObject *object)
+{
+ WaylandSession *self;
+
+ self = WAYLAND_SESSION (object);
+
+ if (self->priv->have_vt_ref)
+ vt_unref (self->priv->vt);
+
+ G_OBJECT_CLASS (wayland_session_parent_class)->finalize (object);
+}
+
+static void
+wayland_session_class_init (WaylandSessionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
+
+ display_server_class->get_vt = wayland_session_get_vt;
+ display_server_class->connect_session = wayland_session_connect_session;
+ display_server_class->disconnect_session = wayland_session_disconnect_session;
+ object_class->finalize = wayland_session_finalize;
+
+ g_type_class_add_private (klass, sizeof (WaylandSessionPrivate));
+}
--- /dev/null
+/*
+ * Copyright (C) 2015 Canonical Ltd.
+ * Author: Robert Ancell <robert.ancell@canonical.com>
+ *
+ * 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 3 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+#ifndef WAYLAND_SESSION_H_
+#define WAYLAND_SESSION_H_
+
+#include <glib-object.h>
+#include "display-server.h"
+
+G_BEGIN_DECLS
+
+#define WAYLAND_SESSION_TYPE (wayland_session_get_type())
+#define WAYLAND_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WAYLAND_SESSION_TYPE, WaylandSession))
+#define IS_WAYLAND_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WAYLAND_SESSION_TYPE))
+
+typedef struct WaylandSessionPrivate WaylandSessionPrivate;
+
+typedef struct
+{
+ DisplayServer parent_instance;
+ WaylandSessionPrivate *priv;
+} WaylandSession;
+
+typedef struct
+{
+ DisplayServerClass parent_class;
+} WaylandSessionClass;
+
+GType wayland_session_get_type (void);
+
+WaylandSession *wayland_session_new (void);
+
+void wayland_session_set_vt (WaylandSession *session, gint vt);
+
+G_END_DECLS
+
+#endif /* WAYLAND_SESSION_H_ */
test-mir-session-crash \
test-mir-session-compositor-crash \
test-mir-container-session \
+ test-wayland-autologin \
+ test-wayland-greeter \
+ test-wayland-session \
test-unity-compositor-command \
test-unity-compositor-not-found \
test-unity-compositor-fail-start \
data/greeters/test-python-greeter.desktop \
data/greeters/test-qt4-greeter.desktop \
data/greeters/test-qt5-greeter.desktop \
+ data/greeters/test-wayland-greeter.desktop \
data/sessions/alternative.desktop \
data/sessions/default.desktop \
data/sessions/mir.desktop \
data/sessions/mir-container.desktop \
data/sessions/named.desktop \
data/sessions/named-legacy.desktop \
+ data/sessions/wayland.desktop \
scripts/0-additional.conf \
scripts/1-additional.conf \
scripts/additional-config.conf \
scripts/vnc-guest.conf \
scripts/vnc-login.conf \
scripts/vnc-open-file-descriptors.conf \
+ scripts/wayland-autologin.conf \
+ scripts/wayland-greeter.conf \
+ scripts/wayland-session.conf \
scripts/xauthority.conf \
scripts/xdg-current-desktop.conf \
scripts/xdg-current-desktop-legacy.conf \
[Desktop Entry]
-Name=Test GObject Greeter
-Comment=LightDM test GObject greeter
+Name=Test Mir Greeter
+Comment=LightDM test Mir greeter
Exec=test-gobject-greeter
X-LightDM-Session-Type=mir
--- /dev/null
+[Desktop Entry]
+Name=Test Wayland Greeter
+Comment=LightDM test Wayland greeter
+Exec=test-gobject-greeter
+X-LightDM-Session-Type=wayland
--- /dev/null
+[Desktop Entry]
+Name=Test Session
+Comment=LightDM test Wayland session
+Exec=test-session
+X-LightDM-Session-Type=wayland
--- /dev/null
+#
+# Check can automatically log into a Wayland session from a VT based seat
+#
+
+[Seat:*]
+autologin-user=have-password1
+user-session=wayland
+
+#?*START-DAEMON
+#?RUNNER DAEMON-START
+
+# Session starts
+#?SESSION-WAYLAND START XDG_SEAT=seat0 XDG_VTNR=7 XDG_GREETER_DATA_DIR=.*/have-password1 XDG_SESSION_TYPE=wayland XDG_SESSION_DESKTOP=wayland USER=have-password1
+#?LOGIN1 ACTIVATE-SESSION SESSION=c0
+
+# Cleanup
+#?*STOP-DAEMON
+#?SESSION-WAYLAND TERMINATE SIGNAL=15
+#?RUNNER DAEMON-EXIT STATUS=0
--- /dev/null
+#
+# Check can run a Wayland greeter from a VT based seat
+#
+
+#?*START-DAEMON
+#?RUNNER DAEMON-START
+
+# Greeter starts
+#?GREETER-WAYLAND START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
+#?LOGIN1 ACTIVATE-SESSION SESSION=c0
+#?GREETER-WAYLAND CONNECT-TO-DAEMON
+#?GREETER-WAYLAND CONNECTED-TO-DAEMON
+
+# Cleanup
+#?*STOP-DAEMON
+#?GREETER-WAYLAND TERMINATE SIGNAL=15
+#?RUNNER DAEMON-EXIT STATUS=0
--- /dev/null
+#
+# Check can login into a Wayland session on a VT based seat
+#
+
+[Seat:*]
+user-session=wayland
+
+#?*START-DAEMON
+#?RUNNER DAEMON-START
+
+# X server starts
+#?XSERVER-0 START VT=7 SEAT=seat0
+
+# Daemon connects when X server is ready
+#?*XSERVER-0 INDICATE-READY
+#?XSERVER-0 INDICATE-READY
+#?XSERVER-0 ACCEPT-CONNECT
+
+# Greeter starts
+#?GREETER-X-0 START XDG_SEAT=seat0 XDG_VTNR=7 XDG_SESSION_CLASS=greeter
+#?LOGIN1 ACTIVATE-SESSION SESSION=c0
+#?XSERVER-0 ACCEPT-CONNECT
+#?GREETER-X-0 CONNECT-XSERVER
+#?GREETER-X-0 CONNECT-TO-DAEMON
+#?GREETER-X-0 CONNECTED-TO-DAEMON
+
+# Attempt to log into account
+#?*GREETER-X-0 AUTHENTICATE USERNAME=no-password1
+#?GREETER-X-0 AUTHENTICATION-COMPLETE USERNAME=no-password1 AUTHENTICATED=TRUE
+#?*GREETER-X-0 START-SESSION
+
+# Greeter terminates
+#?GREETER-X-0 TERMINATE SIGNAL=15
+#?XSERVER-0 TERMINATE SIGNAL=15
+
+# Session starts
+#?SESSION-WAYLAND START XDG_SEAT=seat0 XDG_VTNR=8 XDG_GREETER_DATA_DIR=.*/no-password1 XDG_SESSION_TYPE=wayland XDG_SESSION_DESKTOP=wayland USER=no-password1
+#?LOGIN1 ACTIVATE-SESSION SESSION=c1
+
+# Switch to session
+#?VT ACTIVATE VT=8
+
+# Cleanup
+#?*STOP-DAEMON
+#?SESSION-WAYLAND TERMINATE SIGNAL=15
+#?RUNNER DAEMON-EXIT STATUS=0
int
main (int argc, char **argv)
{
- gchar *display, *xdg_seat, *xdg_vtnr, *xdg_session_cookie, *xdg_session_class, *mir_socket, *mir_vt, *mir_id, *path;
+ gchar *display, *xdg_seat, *xdg_vtnr, *xdg_session_cookie, *xdg_session_class, *xdg_session_type, *mir_socket, *mir_vt, *mir_id, *path;
GString *status_text;
#if !defined(GLIB_VERSION_2_36)
xdg_vtnr = getenv ("XDG_VTNR");
xdg_session_cookie = getenv ("XDG_SESSION_COOKIE");
xdg_session_class = getenv ("XDG_SESSION_CLASS");
+ xdg_session_type = getenv ("XDG_SESSION_TYPE");
mir_socket = getenv ("MIR_SOCKET");
mir_vt = getenv ("MIR_SERVER_VT");
mir_id = getenv ("MIR_SERVER_NAME");
greeter_id = g_strdup_printf ("GREETER-MIR-%s", mir_id);
else if (mir_socket || mir_vt)
greeter_id = g_strdup ("GREETER-MIR");
+ else if (g_strcmp0 (xdg_session_type, "wayland") == 0)
+ greeter_id = g_strdup ("GREETER-WAYLAND");
else
greeter_id = g_strdup ("GREETER-?");
session_id = g_strdup_printf ("SESSION-MIR-%s", mir_id);
else if (mir_socket || mir_vt)
session_id = g_strdup ("SESSION-MIR");
+ else if (g_strcmp0 (xdg_session_type, "wayland") == 0)
+ session_id = g_strdup ("SESSION-WAYLAND");
else
session_id = g_strdup ("SESSION-UNKNOWN");
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner wayland-autologin test-gobject-greeter
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner wayland-greeter test-wayland-greeter
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner wayland-session test-gobject-greeter