Skip to content

Commit

Permalink
Support Wayland sessions / greeters
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-ancell committed Jul 28, 2015
1 parent 2db3a8b commit f4f681f
Show file tree
Hide file tree
Showing 23 changed files with 318 additions and 23 deletions.
2 changes: 1 addition & 1 deletion data/lightdm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#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

Expand Down
3 changes: 2 additions & 1 deletion liblightdm-gobject/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ liblightdm_gobject_1_la_CFLAGS = $(LIBLIGHTDM_GOBJECT_CFLAGS) \
$(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
Expand Down
30 changes: 19 additions & 11 deletions liblightdm-gobject/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ compare_session (gconstpointer a, gconstpointer b)
}

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;
Expand All @@ -57,10 +57,6 @@ load_session (GKeyFile *key_file, const gchar *key)
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
Expand Down Expand Up @@ -91,14 +87,18 @@ load_session (GKeyFile *key_file, const gchar *key)
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);

g_free (priv->key);
priv->key = g_strdup (key);

g_free (priv->type);
priv->type = g_strdup (type);
priv->type = type;

g_free (priv->name);
priv->name = name;
Expand All @@ -114,7 +114,7 @@ load_session (GKeyFile *key_file, const gchar *key)
}

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;
Expand Down Expand Up @@ -154,7 +154,7 @@ load_sessions_dir (GList *sessions, const gchar *sessions_dir)
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);
Expand Down Expand Up @@ -182,8 +182,16 @@ load_sessions (const gchar *sessions_dir)
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;
Expand Down
3 changes: 1 addition & 2 deletions liblightdm-qt/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ common_cflags = \
$(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)
Expand Down
5 changes: 4 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ lightdm_SOURCES = \
vnc-server.h \
vt.c \
vt.h \
wayland-session.c \
wayland-session.h \
x-authority.c \
x-authority.h \
x-server-local.c \
Expand Down Expand Up @@ -78,7 +80,8 @@ lightdm_CFLAGS = \
-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\"

Expand Down
18 changes: 18 additions & 0 deletions src/seat-xlocal.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "configuration.h"
#include "x-server-local.h"
#include "unity-system-compositor.h"
#include "wayland-session.h"
#include "plymouth.h"
#include "vt.h"

Expand Down Expand Up @@ -247,6 +248,21 @@ create_unity_system_compositor (Seat *seat)
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)
{
Expand All @@ -257,6 +273,8 @@ 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;
Expand Down
6 changes: 5 additions & 1 deletion src/seat.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,11 +962,15 @@ find_session_config (Seat *seat, const gchar *sessions_dir, const gchar *session
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;
Expand Down
4 changes: 2 additions & 2 deletions src/session-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct SessionConfigPrivate
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;
Expand All @@ -52,7 +52,7 @@ session_config_new_from_file (const gchar *filename, GError **error)
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)
Expand Down
2 changes: 1 addition & 1 deletion src/session-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ typedef struct

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);

Expand Down
106 changes: 106 additions & 0 deletions src/wayland-session.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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));
}
45 changes: 45 additions & 0 deletions src/wayland-session.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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_ */
8 changes: 8 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ TESTS = \
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 \
Expand Down Expand Up @@ -348,12 +351,14 @@ EXTRA_DIST = \
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 \
Expand Down Expand Up @@ -565,6 +570,9 @@ EXTRA_DIST = \
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 \
Expand Down
Loading

0 comments on commit f4f681f

Please sign in to comment.