summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2014-08-21 16:07:32 +1200
committerRobert Ancell <robert.ancell@canonical.com>2014-08-21 16:07:32 +1200
commit28a8780e4f6ff891de83b1d24098a476392bd7f9 (patch)
treef84874015c17d2478820982833bb95b3b3264f80
parent462503d215d05b0e20fe8fb6f71609505d60d73e (diff)
downloadlightdm-28a8780e4f6ff891de83b1d24098a476392bd7f9.tar.gz
Add a new session type 'mir-container' that allows the session to run inside a custom system compositor
-rw-r--r--src/seat-surfaceflinger.c6
-rw-r--r--src/seat-unity.c5
-rw-r--r--src/seat-xdmcp-session.c4
-rw-r--r--src/seat-xlocal.c17
-rw-r--r--src/seat-xremote.c4
-rw-r--r--src/seat-xvnc.c4
-rw-r--r--src/seat.c34
-rw-r--r--src/seat.h2
-rw-r--r--src/session-config.c13
-rw-r--r--src/session-config.h2
-rw-r--r--src/session.c24
-rw-r--r--src/session.h5
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/data/sessions/mir-container.desktop6
-rw-r--r--tests/scripts/mir-container-session.conf54
-rw-r--r--tests/src/unity-system-compositor.c6
-rwxr-xr-xtests/test-mir-container-session2
17 files changed, 156 insertions, 35 deletions
diff --git a/src/seat-surfaceflinger.c b/src/seat-surfaceflinger.c
index 4bfdef15..3d7b6437 100644
--- a/src/seat-surfaceflinger.c
+++ b/src/seat-surfaceflinger.c
@@ -25,8 +25,12 @@ seat_surfaceflinger_setup (Seat *seat)
}
static DisplayServer *
-seat_surfaceflinger_create_display_server (Seat *seat, const gchar *session_type)
+seat_surfaceflinger_create_display_server (Seat *seat, Session *session)
{
+ const gchar *session_type;
+
+ session_type = session_get_session_type (session);
+
/* Allow mir types too, because Mir sessions usually support surfaceflinger
as an alternate mode, since Mir is frequently used on phones. */
if (strcmp (session_type, "surfaceflinger") == 0 || strcmp (session_type, "mir") == 0)
diff --git a/src/seat-unity.c b/src/seat-unity.c
index ec0678a1..45985bb6 100644
--- a/src/seat-unity.c
+++ b/src/seat-unity.c
@@ -243,8 +243,11 @@ create_mir_server (Seat *seat)
}
static DisplayServer *
-seat_unity_create_display_server (Seat *seat, const gchar *session_type)
+seat_unity_create_display_server (Seat *seat, Session *session)
{
+ const gchar *session_type;
+
+ session_type = session_get_session_type (session);
if (strcmp (session_type, "x") == 0)
return DISPLAY_SERVER (create_x_server (seat));
else if (strcmp (session_type, "mir") == 0)
diff --git a/src/seat-xdmcp-session.c b/src/seat-xdmcp-session.c
index 62a21f46..5aebef9a 100644
--- a/src/seat-xdmcp-session.c
+++ b/src/seat-xdmcp-session.c
@@ -34,13 +34,13 @@ seat_xdmcp_session_new (XDMCPSession *session)
}
static DisplayServer *
-seat_xdmcp_session_create_display_server (Seat *seat, const gchar *session_type)
+seat_xdmcp_session_create_display_server (Seat *seat, Session *session)
{
XAuthority *authority;
gchar *host;
XServerRemote *x_server;
- if (strcmp (session_type, "x") != 0)
+ if (strcmp (session_get_session_type (session), "x") != 0)
return NULL;
authority = xdmcp_session_get_authority (SEAT_XDMCP_SESSION (seat)->priv->session);
diff --git a/src/seat-xlocal.c b/src/seat-xlocal.c
index 7d2b861c..b6e8d0e6 100644
--- a/src/seat-xlocal.c
+++ b/src/seat-xlocal.c
@@ -247,12 +247,27 @@ create_unity_system_compositor (Seat *seat)
}
static DisplayServer *
-seat_xlocal_create_display_server (Seat *seat, const gchar *session_type)
+seat_xlocal_create_display_server (Seat *seat, Session *session)
{
+ const gchar *session_type;
+
+ session_type = session_get_session_type (session);
if (strcmp (session_type, "x") == 0)
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, "mir-container") == 0)
+ {
+ DisplayServer *compositor;
+ const gchar *compositor_command;
+
+ compositor = create_unity_system_compositor (seat);
+ compositor_command = session_config_get_compositor_command (session_get_config (session));
+ if (compositor_command)
+ unity_system_compositor_set_command (UNITY_SYSTEM_COMPOSITOR (compositor), compositor_command);
+
+ return compositor;
+ }
else
{
l_warning (seat, "Can't create unsupported display server '%s'", session_type);
diff --git a/src/seat-xremote.c b/src/seat-xremote.c
index 44cafc49..d7af16aa 100644
--- a/src/seat-xremote.c
+++ b/src/seat-xremote.c
@@ -25,12 +25,14 @@ seat_xremote_setup (Seat *seat)
}
static DisplayServer *
-seat_xremote_create_display_server (Seat *seat, const gchar *session_type)
+seat_xremote_create_display_server (Seat *seat, Session *session)
{
+ const gchar *session_type;
XServerRemote *x_server;
const gchar *hostname;
gint number;
+ session_type = session_get_session_type (session);
if (strcmp (session_type, "x") != 0)
{
l_warning (seat, "X remote seat only supports X display servers, not '%s'", session_type);
diff --git a/src/seat-xvnc.c b/src/seat-xvnc.c
index ecabc9b2..fa7737ec 100644
--- a/src/seat-xvnc.c
+++ b/src/seat-xvnc.c
@@ -34,12 +34,12 @@ SeatXVNC *seat_xvnc_new (GSocket *connection)
}
static DisplayServer *
-seat_xvnc_create_display_server (Seat *seat, const gchar *session_type)
+seat_xvnc_create_display_server (Seat *seat, Session *session)
{
XServerXVNC *x_server;
const gchar *command = NULL;
- if (strcmp (session_type, "x") != 0)
+ if (strcmp (session_get_session_type (session), "x") != 0)
return NULL;
x_server = x_server_xvnc_new ();
diff --git a/src/seat.c b/src/seat.c
index d29a43c4..cca8e6f2 100644
--- a/src/seat.c
+++ b/src/seat.c
@@ -78,7 +78,7 @@ typedef struct
static GHashTable *seat_modules = NULL;
// FIXME: Make a get_display_server() that re-uses display servers if supported
-static DisplayServer *create_display_server (Seat *seat, const gchar *session_type);
+static DisplayServer *create_display_server (Seat *seat, Session *session);
static Greeter *create_greeter_session (Seat *seat);
static void start_session (Seat *seat, Session *session);
@@ -527,7 +527,7 @@ switch_to_greeter_from_failed_session (Seat *seat, Session *session)
{
DisplayServer *display_server;
- display_server = create_display_server (seat, session_get_session_type (session));
+ display_server = create_display_server (seat, session);
session_set_display_server (session, display_server);
if (!display_server_start (display_server))
{
@@ -937,7 +937,7 @@ configure_session (Session *session, SessionConfig *config, const gchar *session
{
const gchar *desktop_name;
- session_set_session_type (session, session_config_get_session_type (config));
+ session_set_config (session, config);
session_set_env (session, "XDG_SESSION_DESKTOP", session_name);
session_set_env (session, "DESKTOP_SESSION", session_name);
session_set_env (session, "GDMSESSION", session_name);
@@ -1063,7 +1063,7 @@ greeter_create_session_cb (Greeter *greeter, Seat *seat)
Session *session;
session = create_session (seat, FALSE);
- session_set_session_type (session, session_get_session_type (SESSION (greeter)));
+ session_set_config (session, session_get_config (SESSION (greeter)));
session_set_display_server (session, session_get_display_server (SESSION (greeter)));
return g_object_ref (session);
@@ -1170,7 +1170,7 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
/* Otherwise start a new display server for this session */
else
{
- display_server = create_display_server (seat, session_get_session_type (session));
+ display_server = create_display_server (seat, session);
session_set_display_server (session, display_server);
if (!display_server_start (display_server))
{
@@ -1212,7 +1212,7 @@ create_greeter_session (Seat *seat)
}
greeter_session = SEAT_GET_CLASS (seat)->create_greeter_session (seat);
- session_set_session_type (SESSION (greeter_session), session_config_get_session_type (session_config));
+ session_set_config (SESSION (greeter_session), session_config);
seat->priv->sessions = g_list_append (seat->priv->sessions, SESSION (greeter_session));
g_signal_connect (greeter_session, "notify::active-username", G_CALLBACK (greeter_active_username_changed_cb), seat);
g_signal_connect (greeter_session, "authentication-complete", G_CALLBACK (session_authentication_complete_cb), seat);
@@ -1326,13 +1326,13 @@ display_server_ready_cb (DisplayServer *display_server, Seat *seat)
}
static DisplayServer *
-create_display_server (Seat *seat, const gchar *session_type)
+create_display_server (Seat *seat, Session *session)
{
DisplayServer *display_server;
- l_debug (seat, "Creating display server of type %s", session_type);
+ l_debug (seat, "Creating display server of type %s", session_get_session_type (session));
- display_server = SEAT_GET_CLASS (seat)->create_display_server (seat, session_type);
+ display_server = SEAT_GET_CLASS (seat)->create_display_server (seat, session);
if (!display_server)
return NULL;
@@ -1371,7 +1371,7 @@ seat_switch_to_greeter (Seat *seat)
g_object_unref (seat->priv->session_to_activate);
seat->priv->session_to_activate = g_object_ref (greeter_session);
- display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+ display_server = create_display_server (seat, SESSION (greeter_session));
session_set_display_server (SESSION (greeter_session), display_server);
return display_server_start (display_server);
@@ -1403,7 +1403,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
if (seat->priv->session_to_activate)
g_object_unref (seat->priv->session_to_activate);
seat->priv->session_to_activate = g_object_ref (session);
- display_server = create_display_server (seat, session_get_session_type (session));
+ display_server = create_display_server (seat, session);
session_set_display_server (session, display_server);
display_server_start (display_server);
}
@@ -1443,7 +1443,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
g_object_unref (seat->priv->session_to_activate);
seat->priv->session_to_activate = g_object_ref (greeter_session);
- display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+ display_server = create_display_server (seat, SESSION (greeter_session));
session_set_display_server (SESSION (greeter_session), display_server);
display_server_start (display_server);
}
@@ -1514,7 +1514,7 @@ seat_switch_to_guest (Seat *seat, const gchar *session_name)
if (!session)
return FALSE;
- display_server = create_display_server (seat, session_get_session_type (session));
+ display_server = create_display_server (seat, session);
if (seat->priv->session_to_activate)
g_object_unref (seat->priv->session_to_activate);
@@ -1566,7 +1566,7 @@ seat_lock (Seat *seat, const gchar *username)
}
else
{
- display_server = create_display_server (seat, session_get_session_type (SESSION (greeter_session)));
+ display_server = create_display_server (seat, SESSION (greeter_session));
if (seat->priv->session_to_activate)
g_object_unref (seat->priv->session_to_activate);
@@ -1645,7 +1645,7 @@ seat_real_start (Seat *seat)
g_object_unref (seat->priv->session_to_activate);
seat->priv->session_to_activate = g_object_ref (session);
- display_server = create_display_server (seat, session_get_session_type (session));
+ display_server = create_display_server (seat, session);
session_set_display_server (session, display_server);
if (!display_server || !display_server_start (display_server))
{
@@ -1676,7 +1676,7 @@ seat_real_start (Seat *seat)
seat->priv->session_to_activate = g_object_ref (greeter_session);
session = SESSION (greeter_session);
- display_server = create_display_server (seat, session_get_session_type (session));
+ display_server = create_display_server (seat, session);
session_set_display_server (session, display_server);
if (!display_server || !display_server_start (display_server))
{
@@ -1700,7 +1700,7 @@ seat_real_start (Seat *seat)
{
DisplayServer *background_display_server;
- background_display_server = create_display_server (seat, session_get_session_type (background_session));
+ background_display_server = create_display_server (seat, background_session);
session_set_display_server (background_session, background_display_server);
if (!display_server_start (background_display_server))
l_warning (seat, "Failed to start display server for background session");
diff --git a/src/seat.h b/src/seat.h
index 1b861098..faa4a0a4 100644
--- a/src/seat.h
+++ b/src/seat.h
@@ -40,7 +40,7 @@ typedef struct
void (*setup)(Seat *seat);
gboolean (*start)(Seat *seat);
- DisplayServer *(*create_display_server) (Seat *seat, const gchar *session_type);
+ DisplayServer *(*create_display_server) (Seat *seat, Session *session);
gboolean (*display_server_supports_session_type) (Seat *seat, DisplayServer *display_server, const gchar *session_type);
Greeter *(*create_greeter_session) (Seat *seat);
Session *(*create_session) (Seat *seat);
diff --git a/src/session-config.c b/src/session-config.c
index c62aef39..85081b28 100644
--- a/src/session-config.c
+++ b/src/session-config.c
@@ -21,6 +21,9 @@ struct SessionConfigPrivate
/* Command to run */
gchar *command;
+
+ /* Compositor command to run (for type mir-container) */
+ gchar *compositor_command;
};
G_DEFINE_TYPE (SessionConfig, session_config, G_TYPE_OBJECT);
@@ -54,6 +57,8 @@ session_config_new_from_file (const gchar *filename, GError **error)
config->priv->desktop_name = g_key_file_get_string (desktop_file, G_KEY_FILE_DESKTOP_GROUP, "DesktopNames", NULL);
if (!config->priv->desktop_name)
config->priv->desktop_name = g_key_file_get_string (desktop_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-DesktopName", NULL);
+ if (!config->priv->compositor_command)
+ config->priv->compositor_command = g_key_file_get_string (desktop_file, G_KEY_FILE_DESKTOP_GROUP, "X-LightDM-System-Compositor-Command", NULL);
g_key_file_free (desktop_file);
@@ -81,6 +86,13 @@ session_config_get_desktop_name (SessionConfig *config)
return config->priv->desktop_name;
}
+const gchar *
+session_config_get_compositor_command (SessionConfig *config)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+ return config->priv->compositor_command;
+}
+
static void
session_config_init (SessionConfig *config)
{
@@ -95,6 +107,7 @@ session_config_finalize (GObject *object)
g_free (self->priv->session_type);
g_free (self->priv->desktop_name);
g_free (self->priv->command);
+ g_free (self->priv->compositor_command);
G_OBJECT_CLASS (session_config_parent_class)->finalize (object);
}
diff --git a/src/session-config.h b/src/session-config.h
index 2fd0efec..25e8002b 100644
--- a/src/session-config.h
+++ b/src/session-config.h
@@ -44,6 +44,8 @@ const gchar *session_config_get_session_type (SessionConfig *config);
const gchar *session_config_get_desktop_name (SessionConfig *config);
+const gchar *session_config_get_compositor_command (SessionConfig *config);
+
G_END_DECLS
#endif /* SESSION_CONFIG_H_ */
diff --git a/src/session.c b/src/session.c
index c0cbc140..82af286f 100644
--- a/src/session.c
+++ b/src/session.c
@@ -38,8 +38,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
struct SessionPrivate
{
- /* Session type */
- gchar *session_type;
+ /* Configuration for this session */
+ SessionConfig *config;
/* Display server running on */
DisplayServer *display_server;
@@ -131,18 +131,27 @@ session_new (void)
}
void
-session_set_session_type (Session *session, const gchar *session_type)
+session_set_config (Session *session, SessionConfig *config)
{
g_return_if_fail (session != NULL);
- g_free (session->priv->session_type);
- session->priv->session_type = g_strdup (session_type);
+
+ if (session->priv->config)
+ g_object_unref (session->priv->config);
+ session->priv->config = g_object_ref (config);
+}
+
+SessionConfig *
+session_get_config (Session *session)
+{
+ g_return_val_if_fail (session != NULL, NULL);
+ return session->priv->config;
}
const gchar *
session_get_session_type (Session *session)
{
g_return_val_if_fail (session != NULL, NULL);
- return session->priv->session_type;
+ return session_config_get_session_type (session_get_config (session));
}
void
@@ -904,7 +913,8 @@ session_finalize (GObject *object)
Session *self = SESSION (object);
int i;
- g_free (self->priv->session_type);
+ if (self->priv->config)
+ g_object_unref (self->priv->config);
if (self->priv->display_server)
g_object_unref (self->priv->display_server);
if (self->priv->pid)
diff --git a/src/session.h b/src/session.h
index 06182967..e820e137 100644
--- a/src/session.h
+++ b/src/session.h
@@ -18,6 +18,7 @@
typedef struct Session Session;
+#include "session-config.h"
#include "display-server.h"
#include "accounts.h"
#include "x-authority.h"
@@ -61,7 +62,9 @@ GType session_get_type (void);
Session *session_new (void);
-void session_set_session_type (Session *session, const gchar *session_type);
+void session_set_config (Session *session, SessionConfig *config);
+
+SessionConfig *session_get_config (Session *session);
const gchar *session_get_session_type (Session *session);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 172d31f3..d09d5df2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -187,6 +187,7 @@ TESTS = \
test-mir-session \
test-mir-session-crash \
test-mir-session-compositor-crash \
+ test-mir-container-session \
test-unity-compositor-command \
test-unity-compositor-not-found \
test-unity-compositor-fail-start \
@@ -337,6 +338,7 @@ EXTRA_DIST = \
data/sessions/alternative.desktop \
data/sessions/default.desktop \
data/sessions/mir.desktop \
+ data/sessions/mir-container.desktop \
data/sessions/named.desktop \
data/sessions/surfaceflinger.desktop \
scripts/0-additional.conf \
@@ -440,6 +442,7 @@ EXTRA_DIST = \
scripts/login-wrong-password.conf \
scripts/login-xserver-crash.conf \
scripts/mir-autologin.conf \
+ scripts/mir-container-session.conf \
scripts/mir-greeter.conf \
scripts/mir-session.conf \
scripts/mir-session-compositor-crash.conf \
diff --git a/tests/data/sessions/mir-container.desktop b/tests/data/sessions/mir-container.desktop
new file mode 100644
index 00000000..72639b3a
--- /dev/null
+++ b/tests/data/sessions/mir-container.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Name=Test Session
+Comment=LightDM test Mir session
+Exec=test-session
+X-LightDM-Session-Type=mir-container
+X-LightDM-System-Compositor-Command=unity-system-compositor --container
diff --git a/tests/scripts/mir-container-session.conf b/tests/scripts/mir-container-session.conf
new file mode 100644
index 00000000..cb259ac0
--- /dev/null
+++ b/tests/scripts/mir-container-session.conf
@@ -0,0 +1,54 @@
+#
+# Check can login into a containerised Mir session on a VT based seat
+#
+
+[SeatDefaults]
+user-session=mir-container
+
+#?*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
+
+# System compositor starts
+#?UNITY-SYSTEM-COMPOSITOR START FILE=/run/lightdm-mir-0 VT=8 ENABLE-HARDWARE-CURSOR=TRUE XDG_VTNR=8 CONTAINER=TRUE
+#?*UNITY-SYSTEM-COMPOSITOR READY
+
+# Switch to system compositor
+#?VT ACTIVATE VT=8
+
+# Greeter terminates
+#?GREETER-X-0 TERMINATE SIGNAL=15
+#?XSERVER-0 TERMINATE SIGNAL=15
+
+# Session starts
+#?SESSION-MIR-session-0 START XDG_SEAT=seat0 XDG_VTNR=8 XDG_GREETER_DATA_DIR=.*/no-password1 XDG_SESSION_TYPE=mir XDG_SESSION_DESKTOP=mir-container USER=no-password1
+#?LOGIN1 ACTIVATE-SESSION SESSION=c1
+
+# Session shown
+#?UNITY-SYSTEM-COMPOSITOR SET-ACTIVE-SESSION ID=session-0
+
+# Cleanup
+#?*STOP-DAEMON
+#?SESSION-MIR-session-0 TERMINATE SIGNAL=15
+#?UNITY-SYSTEM-COMPOSITOR TERMINATE SIGNAL=15
+#?RUNNER DAEMON-EXIT STATUS=0
diff --git a/tests/src/unity-system-compositor.c b/tests/src/unity-system-compositor.c
index 6efc1baa..ab6ea114 100644
--- a/tests/src/unity-system-compositor.c
+++ b/tests/src/unity-system-compositor.c
@@ -144,7 +144,7 @@ main (int argc, char **argv)
{
int i;
GString *status_text;
- gboolean test = FALSE;
+ gboolean test = FALSE, container = FALSE;
int vt_number = -1;
gboolean enable_hardware_cursor = FALSE;
const gchar *file = NULL;
@@ -188,6 +188,8 @@ main (int argc, char **argv)
}
else if (strcmp (arg, "--test") == 0)
test = TRUE;
+ else if (strcmp (arg, "--container") == 0)
+ container = TRUE;
else
return EXIT_FAILURE;
}
@@ -205,6 +207,8 @@ main (int argc, char **argv)
g_string_append_printf (status_text, " XDG_VTNR=%s", g_getenv ("XDG_VTNR"));
if (test)
g_string_append (status_text, " TEST=TRUE");
+ if (container)
+ g_string_append (status_text, " CONTAINER=TRUE");
status_notify ("%s", status_text->str);
g_string_free (status_text, TRUE);
diff --git a/tests/test-mir-container-session b/tests/test-mir-container-session
new file mode 100755
index 00000000..4af57059
--- /dev/null
+++ b/tests/test-mir-container-session
@@ -0,0 +1,2 @@
+#!/bin/sh
+./src/dbus-env ./src/test-runner mir-container-session test-gobject-greeter