+Overview of changes in lightdm 1.11.6
+
+ * Add a seat option 'allow-user-switching' that can disable all user
+ switching for that seat
+ * Add a new session type 'mir-container' that allows the session to run
+ inside a custom system compositor
+ * Only seat0 takes VT from Plymouth
+ * Removed unused GAsyncResultIface.is_tagged as this attribute was not
+ available in earlier versions of Glib I/O.
+ * Abort autogen if yelp-tools not installed
+ * Return correct errors for D-Bus calls
+
Overview of changes in lightdm 1.11.5
* Make PAM services configurable
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(lightdm, 1.11.5)
+AC_INIT(lightdm, 1.11.6)
AC_CONFIG_MACRO_DIR(m4)
AC_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz foreign])
+lightdm (1.11.6-0ubuntu1) utopic; urgency=medium
+
+ * New upstream release:
+ * Add a seat option 'allow-user-switching' that can disable all user
+ switching for that seat
+ * Add a new session type 'mir-container' that allows the session to run
+ inside a custom system compositor (LP: #1359332)
+ * Only seat0 takes VT from Plymouth
+ * Removed unused GAsyncResultIface.is_tagged as this attribute was not
+ available in earlier versions of Glib I/O.
+ * Abort autogen if yelp-tools not installed
+ * Return correct errors for D-Bus calls
+
+ -- Robert Ancell <robert.ancell@canonical.com> Fri, 22 Aug 2014 09:10:29 +1200
+
lightdm (1.11.5-0ubuntu1) utopic; urgency=medium
* New upstream release:
process.h \
seat.c \
seat.h \
- seat-surfaceflinger.c \
- seat-surfaceflinger.h \
seat-unity.c \
seat-unity.h \
seat-xdmcp-session.c \
session-config.h \
shared-data-manager.c \
shared-data-manager.h \
- surfaceflinger-server.c \
- surfaceflinger-server.h \
unity-system-compositor.c \
unity-system-compositor.h \
vnc-server.c \
#include "seat-xlocal.h"
#include "seat-xremote.h"
#include "seat-unity.h"
-#include "seat-surfaceflinger.h"
#include "plymouth.h"
enum {
seat_register_module ("xlocal", SEAT_XLOCAL_TYPE);
seat_register_module ("xremote", SEAT_XREMOTE_TYPE);
seat_register_module ("unity", SEAT_UNITY_TYPE);
- seat_register_module ("surfaceflinger", SEAT_SURFACEFLINGER_TYPE);
}
static void
+++ /dev/null
-/*
- * Copyright (C) 2013 Robert Ancell.
- * 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 <string.h>
-
-#include "seat-surfaceflinger.h"
-#include "surfaceflinger-server.h"
-#include "vt.h"
-
-G_DEFINE_TYPE (SeatSurfaceflinger, seat_surfaceflinger, SEAT_TYPE);
-
-static void
-seat_surfaceflinger_setup (Seat *seat)
-{
- seat_set_supports_multi_session (seat, FALSE);
- SEAT_CLASS (seat_surfaceflinger_parent_class)->setup (seat);
-}
-
-static DisplayServer *
-seat_surfaceflinger_create_display_server (Seat *seat, const gchar *session_type)
-{
- /* 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)
- return DISPLAY_SERVER (surfaceflinger_server_new ());
- else
- {
- l_warning (seat, "Can't create unsupported display server '%s'", session_type);
- return NULL;
- }
-}
-
-static Greeter *
-seat_surfaceflinger_create_greeter_session (Seat *seat)
-{
- Greeter *greeter_session;
-
- greeter_session = SEAT_CLASS (seat_surfaceflinger_parent_class)->create_greeter_session (seat);
- session_set_env (SESSION (greeter_session), "XDG_SEAT", seat_get_name (seat));
-
- /* Fake the VT */
- session_set_env (SESSION (greeter_session), "XDG_VTNR", vt_can_multi_seat () ? "1" : "0");
-
- return greeter_session;
-}
-
-static Session *
-seat_surfaceflinger_create_session (Seat *seat)
-{
- Session *session;
-
- session = SEAT_CLASS (seat_surfaceflinger_parent_class)->create_session (seat);
- session_set_env (session, "XDG_SEAT", seat_get_name (seat));
-
- /* Fake the VT */
- session_set_env (session, "XDG_VTNR", vt_can_multi_seat () ? "1" : "0");
-
- return session;
-}
-
-static void
-seat_surfaceflinger_init (SeatSurfaceflinger *seat)
-{
-}
-
-static void
-seat_surfaceflinger_class_init (SeatSurfaceflingerClass *klass)
-{
- SeatClass *seat_class = SEAT_CLASS (klass);
-
- seat_class->setup = seat_surfaceflinger_setup;
- seat_class->create_display_server = seat_surfaceflinger_create_display_server;
- seat_class->create_greeter_session = seat_surfaceflinger_create_greeter_session;
- seat_class->create_session = seat_surfaceflinger_create_session;
-}
+++ /dev/null
-/*
- * Copyright (C) 2013 Robert Ancell.
- * 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 _SEAT_SURFACEFLINGER_H_
-#define _SEAT_SURFACEFLINGER_H_
-
-#include <glib-object.h>
-#include "seat.h"
-
-G_BEGIN_DECLS
-
-#define SEAT_SURFACEFLINGER_TYPE (seat_surfaceflinger_get_type())
-#define SEAT_SURFACEFLINGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAT_SURFACEFLINGER_TYPE, SeatSurfaceflinger))
-
-typedef struct SeatSurfaceflingerPrivate SeatSurfaceflingerPrivate;
-
-typedef struct
-{
- Seat parent_instance;
- SeatSurfaceflingerPrivate *priv;
-} SeatSurfaceflinger;
-
-typedef struct
-{
- SeatClass parent_class;
-} SeatSurfaceflingerClass;
-
-GType seat_surfaceflinger_get_type (void);
-
-G_END_DECLS
-
-#endif /* _SEAT_SURFACEFLINGER_H_ */
/* System compositor */
UnitySystemCompositor *compositor;
+ /* X server being used for XDMCP */
+ XServerLocal *xdmcp_x_server;
+
/* Next Mir ID to use for a Mir sessions, X server and greeters */
gint next_session_id;
gint next_x_server_id;
G_DEFINE_TYPE (SeatUnity, seat_unity, SEAT_TYPE);
-static gboolean
-seat_unity_get_start_local_sessions (Seat *seat)
-{
- return !seat_get_string_property (seat, "xdmcp-manager");
-}
+static XServerLocal *create_x_server (Seat *seat);
static void
seat_unity_setup (Seat *seat)
SEAT_CLASS (seat_unity_parent_class)->setup (seat);
}
+static void
+check_stopped (SeatUnity *seat)
+{
+ if (!seat->priv->compositor && !seat->priv->xdmcp_x_server)
+ SEAT_CLASS (seat_unity_parent_class)->stop (SEAT (seat));
+}
+
+static void
+xdmcp_x_server_stopped_cb (DisplayServer *display_server, Seat *seat)
+{
+ l_debug (seat, "XDMCP X server stopped");
+
+ g_signal_handlers_disconnect_matched (SEAT_UNITY (seat)->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ SEAT_UNITY (seat)->priv->xdmcp_x_server = NULL;
+
+ g_object_unref (display_server);
+
+ if (seat_get_is_stopping (seat))
+ check_stopped (SEAT_UNITY (seat));
+ else
+ seat_stop (seat);
+}
+
static void
compositor_ready_cb (UnitySystemCompositor *compositor, SeatUnity *seat)
{
- l_debug (seat, "Compositor ready");
+ const gchar *xdmcp_manager = NULL;
+
+ l_debug (seat, "Compositor ready");
+
+ /* If running as an XDMCP client then just start an X server */
+ xdmcp_manager = seat_get_string_property (SEAT (seat), "xdmcp-manager");
+ if (xdmcp_manager)
+ {
+ const gchar *key_name = NULL;
+ gint port = 0;
+
+ seat->priv->xdmcp_x_server = create_x_server (SEAT (seat));
+ x_server_local_set_xdmcp_server (seat->priv->xdmcp_x_server, xdmcp_manager);
+ port = seat_get_integer_property (SEAT (seat), "xdmcp-port");
+ if (port > 0)
+ x_server_local_set_xdmcp_port (seat->priv->xdmcp_x_server, port);
+ key_name = seat_get_string_property (SEAT (seat), "xdmcp-key");
+ if (key_name)
+ {
+ gchar *dir, *path;
+ GKeyFile *keys;
+ gboolean result;
+ GError *error = NULL;
+
+ dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
+ path = g_build_filename (dir, "keys.conf", NULL);
+ g_free (dir);
+
+ keys = g_key_file_new ();
+ result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
+ if (error)
+ l_debug (seat, "Error getting key %s", error->message);
+ g_clear_error (&error);
+
+ if (result)
+ {
+ gchar *key = NULL;
+
+ if (g_key_file_has_key (keys, "keyring", key_name, NULL))
+ key = g_key_file_get_string (keys, "keyring", key_name, NULL);
+ else
+ l_debug (seat, "Key %s not defined", key_name);
+
+ if (key)
+ x_server_local_set_xdmcp_key (seat->priv->xdmcp_x_server, key);
+ g_free (key);
+ }
+
+ g_free (path);
+ g_key_file_free (keys);
+ }
+
+ g_signal_connect (seat->priv->xdmcp_x_server, "stopped", G_CALLBACK (xdmcp_x_server_stopped_cb), seat);
+ if (!display_server_start (DISPLAY_SERVER (seat->priv->xdmcp_x_server)))
+ seat_stop (SEAT (seat));
+ }
+
SEAT_CLASS (seat_unity_parent_class)->start (SEAT (seat));
}
static void
compositor_stopped_cb (UnitySystemCompositor *compositor, SeatUnity *seat)
{
+ l_debug (seat, "Compositor stopped");
+
g_object_unref (seat->priv->compositor);
seat->priv->compositor = NULL;
if (seat_get_is_stopping (SEAT (seat)))
- {
- SEAT_CLASS (seat_unity_parent_class)->stop (SEAT (seat));
- return;
- }
-
- l_debug (seat, "Stopping Unity seat, compositor terminated");
-
- seat_stop (SEAT (seat));
+ check_stopped (seat);
+ else
+ seat_stop (SEAT (seat));
}
static gboolean
return FALSE;
}
- timeout = seat_get_integer_property (seat, "unity-compositor-timeout");
+ timeout = seat_get_integer_property (SEAT (seat), "unity-compositor-timeout");
if (timeout <= 0)
timeout = 60;
SEAT_UNITY (seat)->priv->compositor = unity_system_compositor_new ();
g_signal_connect (SEAT_UNITY (seat)->priv->compositor, "ready", G_CALLBACK (compositor_ready_cb), seat);
g_signal_connect (SEAT_UNITY (seat)->priv->compositor, "stopped", G_CALLBACK (compositor_stopped_cb), seat);
- unity_system_compositor_set_command (SEAT_UNITY (seat)->priv->compositor, seat_get_string_property (seat, "unity-compositor-command"));
+ unity_system_compositor_set_command (SEAT_UNITY (seat)->priv->compositor, seat_get_string_property (SEAT (seat), "unity-compositor-command"));
unity_system_compositor_set_vt (SEAT_UNITY (seat)->priv->compositor, vt);
unity_system_compositor_set_timeout (SEAT_UNITY (seat)->priv->compositor, timeout);
return display_server_start (DISPLAY_SERVER (SEAT_UNITY (seat)->priv->compositor));
}
-static DisplayServer *
+static XServerLocal *
create_x_server (Seat *seat)
{
XServerLocal *x_server;
- const gchar *command = NULL, *layout = NULL, *config_file = NULL, *xdmcp_manager = NULL, *key_name = NULL;
+ const gchar *command = NULL, *layout = NULL, *config_file = NULL;
gboolean allow_tcp;
- gint port = 0;
gchar *id;
l_debug (seat, "Starting X server on Unity compositor");
allow_tcp = seat_get_boolean_property (seat, "xserver-allow-tcp");
x_server_local_set_allow_tcp (x_server, allow_tcp);
- xdmcp_manager = seat_get_string_property (seat, "xdmcp-manager");
- if (xdmcp_manager)
- x_server_local_set_xdmcp_server (x_server, xdmcp_manager);
-
- port = seat_get_integer_property (seat, "xdmcp-port");
- if (port > 0)
- x_server_local_set_xdmcp_port (x_server, port);
-
- key_name = seat_get_string_property (seat, "xdmcp-key");
- if (key_name)
- {
- gchar *dir, *path;
- GKeyFile *keys;
- gboolean result;
- GError *error = NULL;
-
- dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
- path = g_build_filename (dir, "keys.conf", NULL);
- g_free (dir);
-
- keys = g_key_file_new ();
- result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
- if (error)
- l_debug (seat, "Error getting key %s", error->message);
- g_clear_error (&error);
-
- if (result)
- {
- gchar *key = NULL;
-
- if (g_key_file_has_key (keys, "keyring", key_name, NULL))
- key = g_key_file_get_string (keys, "keyring", key_name, NULL);
- else
- l_debug (seat, "Key %s not defined", key_name);
-
- if (key)
- x_server_local_set_xdmcp_key (x_server, key);
- g_free (key);
- }
-
- g_free (path);
- g_key_file_free (keys);
- }
-
- return DISPLAY_SERVER (x_server);
+ return x_server;
}
static DisplayServer *
}
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 create_x_server (seat);
+ return DISPLAY_SERVER (create_x_server (seat));
else if (strcmp (session_type, "mir") == 0)
return create_mir_server (seat);
else
{
/* Stop the compositor first */
if (SEAT_UNITY (seat)->priv->compositor)
- {
display_server_stop (DISPLAY_SERVER (SEAT_UNITY (seat)->priv->compositor));
- return;
- }
- SEAT_CLASS (seat_unity_parent_class)->stop (seat);
+ /* Stop the XDMCP X server first */
+ if (SEAT_UNITY (seat)->priv->xdmcp_x_server)
+ display_server_stop (DISPLAY_SERVER (SEAT_UNITY (seat)->priv->xdmcp_x_server));
+
+ check_stopped (SEAT_UNITY (seat));
}
static void
if (seat->priv->compositor)
g_object_unref (seat->priv->compositor);
+ if (seat->priv->xdmcp_x_server)
+ {
+ g_signal_handlers_disconnect_matched (seat->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ g_object_unref (seat->priv->xdmcp_x_server);
+ }
if (seat->priv->active_session)
g_object_unref (seat->priv->active_session);
if (seat->priv->active_display_server)
SeatClass *seat_class = SEAT_CLASS (klass);
object_class->finalize = seat_unity_finalize;
- seat_class->get_start_local_sessions = seat_unity_get_start_local_sessions;
seat_class->setup = seat_unity_setup;
seat_class->start = seat_unity_start;
seat_class->create_display_server = seat_unity_create_display_server;
}
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);
#include "plymouth.h"
#include "vt.h"
+struct SeatXLocalPrivate
+{
+ /* X server being used for XDMCP */
+ XServerLocal *xdmcp_x_server;
+};
+
G_DEFINE_TYPE (SeatXLocal, seat_xlocal, SEAT_TYPE);
-static gboolean
-seat_xlocal_get_start_local_sessions (Seat *seat)
-{
- return !seat_get_string_property (seat, "xdmcp-manager");
-}
+static XServerLocal *create_x_server (Seat *seat);
static void
seat_xlocal_setup (Seat *seat)
SEAT_CLASS (seat_xlocal_parent_class)->setup (seat);
}
+static void
+check_stopped (SeatXLocal *seat)
+{
+ if (!seat->priv->xdmcp_x_server)
+ SEAT_CLASS (seat_xlocal_parent_class)->stop (SEAT (seat));
+}
+
+static void
+xdmcp_x_server_stopped_cb (DisplayServer *display_server, Seat *seat)
+{
+ l_debug (seat, "XDMCP X server stopped");
+
+ g_signal_handlers_disconnect_matched (SEAT_XLOCAL (seat)->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ SEAT_XLOCAL (seat)->priv->xdmcp_x_server = NULL;
+ g_object_unref (display_server);
+
+ if (seat_get_is_stopping (seat))
+ check_stopped (SEAT_XLOCAL (seat));
+ else
+ seat_stop (seat);
+}
+
static gboolean
seat_xlocal_start (Seat *seat)
{
+ const gchar *xdmcp_manager = NULL;
+
+ /* If running as an XDMCP client then just start an X server */
+ xdmcp_manager = seat_get_string_property (seat, "xdmcp-manager");
+ if (xdmcp_manager)
+ {
+ SeatXLocal *s = SEAT_XLOCAL (seat);
+ const gchar *key_name = NULL;
+ gint port = 0;
+
+ s->priv->xdmcp_x_server = create_x_server (seat);
+ x_server_local_set_xdmcp_server (s->priv->xdmcp_x_server, xdmcp_manager);
+ port = seat_get_integer_property (seat, "xdmcp-port");
+ if (port > 0)
+ x_server_local_set_xdmcp_port (s->priv->xdmcp_x_server, port);
+ key_name = seat_get_string_property (seat, "xdmcp-key");
+ if (key_name)
+ {
+ gchar *dir, *path;
+ GKeyFile *keys;
+ gboolean result;
+ GError *error = NULL;
+
+ dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
+ path = g_build_filename (dir, "keys.conf", NULL);
+ g_free (dir);
+
+ keys = g_key_file_new ();
+ result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
+ if (error)
+ l_debug (seat, "Error getting key %s", error->message);
+ g_clear_error (&error);
+
+ if (result)
+ {
+ gchar *key = NULL;
+
+ if (g_key_file_has_key (keys, "keyring", key_name, NULL))
+ key = g_key_file_get_string (keys, "keyring", key_name, NULL);
+ else
+ l_debug (seat, "Key %s not defined", key_name);
+
+ if (key)
+ x_server_local_set_xdmcp_key (s->priv->xdmcp_x_server, key);
+ g_free (key);
+ }
+
+ g_free (path);
+ g_key_file_free (keys);
+ }
+
+ g_signal_connect (s->priv->xdmcp_x_server, "stopped", G_CALLBACK (xdmcp_x_server_stopped_cb), seat);
+ return display_server_start (DISPLAY_SERVER (s->priv->xdmcp_x_server));
+ }
+
return SEAT_CLASS (seat_xlocal_parent_class)->start (seat);
}
return vt;
}
-static DisplayServer *
+static XServerLocal *
create_x_server (Seat *seat)
{
XServerLocal *x_server;
- const gchar *command = NULL, *layout = NULL, *config_file = NULL, *xdmcp_manager = NULL, *key_name = NULL;
+ const gchar *command = NULL, *layout = NULL, *config_file = NULL;
gboolean allow_tcp;
- gint vt, port = 0;
+ gint vt;
x_server = x_server_local_new ();
allow_tcp = seat_get_boolean_property (seat, "xserver-allow-tcp");
x_server_local_set_allow_tcp (x_server, allow_tcp);
- xdmcp_manager = seat_get_string_property (seat, "xdmcp-manager");
- if (xdmcp_manager)
- x_server_local_set_xdmcp_server (x_server, xdmcp_manager);
-
- port = seat_get_integer_property (seat, "xdmcp-port");
- if (port > 0)
- x_server_local_set_xdmcp_port (x_server, port);
-
- key_name = seat_get_string_property (seat, "xdmcp-key");
- if (key_name)
- {
- gchar *dir, *path;
- GKeyFile *keys;
- gboolean result;
- GError *error = NULL;
-
- dir = config_get_string (config_get_instance (), "LightDM", "config-directory");
- path = g_build_filename (dir, "keys.conf", NULL);
- g_free (dir);
-
- keys = g_key_file_new ();
- result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error);
- if (error)
- l_debug (seat, "Error getting key %s", error->message);
- g_clear_error (&error);
-
- if (result)
- {
- gchar *key = NULL;
-
- if (g_key_file_has_key (keys, "keyring", key_name, NULL))
- key = g_key_file_get_string (keys, "keyring", key_name, NULL);
- else
- l_debug (seat, "Key %s not defined", key_name);
-
- if (key)
- x_server_local_set_xdmcp_key (x_server, key);
- g_free (key);
- }
-
- g_free (path);
- g_key_file_free (keys);
- }
-
- return DISPLAY_SERVER (x_server);
+ return x_server;
}
static DisplayServer *
}
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 create_x_server (seat);
+ 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);
SEAT_CLASS (seat_xlocal_parent_class)->run_script (seat, display_server, script);
}
+static void
+seat_xlocal_stop (Seat *seat)
+{
+ /* Stop the XDMCP X server first */
+ if (SEAT_XLOCAL (seat)->priv->xdmcp_x_server)
+ display_server_stop (DISPLAY_SERVER (SEAT_XLOCAL (seat)->priv->xdmcp_x_server));
+
+ check_stopped (SEAT_XLOCAL (seat));
+}
+
static void
seat_xlocal_init (SeatXLocal *seat)
{
+ seat->priv = G_TYPE_INSTANCE_GET_PRIVATE (seat, SEAT_XLOCAL_TYPE, SeatXLocalPrivate);
+}
+
+static void
+seat_xlocal_finalize (GObject *object)
+{
+ SeatXLocal *seat = SEAT_XLOCAL (object);
+
+ if (seat->priv->xdmcp_x_server)
+ {
+ g_signal_handlers_disconnect_matched (seat->priv->xdmcp_x_server, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, seat);
+ g_object_unref (seat->priv->xdmcp_x_server);
+ }
+
+ G_OBJECT_CLASS (seat_xlocal_parent_class)->finalize (object);
}
static void
seat_xlocal_class_init (SeatXLocalClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
SeatClass *seat_class = SEAT_CLASS (klass);
- seat_class->get_start_local_sessions = seat_xlocal_get_start_local_sessions;
+ object_class->finalize = seat_xlocal_finalize;
+
seat_class->setup = seat_xlocal_setup;
seat_class->start = seat_xlocal_start;
seat_class->create_display_server = seat_xlocal_create_display_server;
seat_class->set_active_session = seat_xlocal_set_active_session;
seat_class->get_active_session = seat_xlocal_get_active_session;
seat_class->run_script = seat_xlocal_run_script;
+ seat_class->stop = seat_xlocal_stop;
+
+ g_type_class_add_private (klass, sizeof (SeatXLocalPrivate));
}
}
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);
}
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 ();
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);
seat_start (Seat *seat)
{
g_return_val_if_fail (seat != NULL, FALSE);
-
+
+ l_debug (seat, "Starting");
+
SEAT_GET_CLASS (seat)->setup (seat);
- return SEAT_GET_CLASS (seat)->start (seat);
+ seat->priv->started = SEAT_GET_CLASS (seat)->start (seat);
+
+ return seat->priv->started;
}
GList *
}
}
-static gboolean
-get_start_local_sessions (Seat *seat)
-{
- return SEAT_GET_CLASS (seat)->get_start_local_sessions (seat);
-}
-
static void
display_server_stopped_cb (DisplayServer *display_server, Seat *seat)
{
}
g_list_free_full (list, g_object_unref);
- if (!seat->priv->stopping && get_start_local_sessions (seat))
+ if (!seat->priv->stopping)
{
/* If we were the active session, switch to a greeter */
active_session = seat_get_active_session (seat);
{
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))
{
{
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);
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);
/* 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))
{
}
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);
return;
}
- /* Stop if don't need to run a session */
- if (!get_start_local_sessions (seat))
- return;
-
emit_upstart_signal ("login-session-start");
/* Start the session waiting for this display server */
}
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;
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);
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);
}
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);
}
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);
}
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);
return seat->priv->stopping;
}
-static gboolean
-seat_real_get_start_local_sessions (Seat *seat)
-{
- return TRUE;
-}
-
static void
seat_real_setup (Seat *seat)
{
gboolean autologin_in_background;
Session *session = NULL, *background_session = NULL;
- l_debug (seat, "Starting");
-
- /* If this display server doesn't have a session running on it, just start it */
- if (!get_start_local_sessions (seat))
- {
- DisplayServer *display_server;
- display_server = create_display_server (seat, "x"); // FIXME: Not necessarily an X seat, but not sure what to put here
- return display_server_start (display_server);
- }
-
/* Get autologin settings */
autologin_username = seat_get_string_property (seat, "autologin-user");
if (g_strcmp0 (autologin_username, "") == 0)
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))
{
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))
{
{
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");
}
- seat->priv->started = TRUE;
return TRUE;
}
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- klass->get_start_local_sessions = seat_real_get_start_local_sessions;
klass->setup = seat_real_setup;
klass->start = seat_real_start;
klass->create_greeter_session = seat_real_create_greeter_session;
typedef struct
{
- GObject parent_instance;
+ GObject parent_instance;
SeatPrivate *priv;
} Seat;
{
GObjectClass parent_class;
- gboolean (*get_start_local_sessions) (Seat *seat);
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);
/* 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);
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);
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)
{
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);
}
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_ */
struct SessionPrivate
{
- /* Session type */
- gchar *session_type;
+ /* Configuration for this session */
+ SessionConfig *config;
/* Display server running on */
DisplayServer *display_server;
}
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
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)
typedef struct Session Session;
+#include "session-config.h"
#include "display-server.h"
#include "accounts.h"
#include "x-authority.h"
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);
+++ /dev/null
-/*
- * Copyright (C) 2013 Robert Ancell.
- * 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 <string.h>
-
-#include "surfaceflinger-server.h"
-
-G_DEFINE_TYPE (SurfaceflingerServer, surfaceflinger_server, DISPLAY_SERVER_TYPE);
-
-SurfaceflingerServer *surfaceflinger_server_new (void)
-{
- return g_object_new (SURFACEFLINGER_SERVER_TYPE, NULL);
-}
-
-static const gchar *
-surfaceflinger_server_get_session_type (DisplayServer *server)
-{
- return "surfaceflinger";
-}
-
-static void
-surfaceflinger_server_init (SurfaceflingerServer *server)
-{
- display_server_set_name (DISPLAY_SERVER (server), "sf");
-}
-
-static void
-surfaceflinger_server_class_init (SurfaceflingerServerClass *klass)
-{
- DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
-
- display_server_class->get_session_type = surfaceflinger_server_get_session_type;
-}
+++ /dev/null
-/*
- * Copyright (C) 2013 Robert Ancell.
- * 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 SURFACEFLINGER_SERVER_H_
-#define SURFACEFLINGER_SERVER_H_
-
-#include <glib-object.h>
-#include "display-server.h"
-
-G_BEGIN_DECLS
-
-#define SURFACEFLINGER_SERVER_TYPE (surfaceflinger_server_get_type())
-#define SURFACEFLINGER_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SURFACEFLINGER_SERVER_TYPE, SurfaceflingerServer))
-#define SURFACEFLINGER_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SURFACEFLINGER_SERVER_TYPE, SurfaceflingerServerClass))
-#define SURFACEFLINGER_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SURFACEFLINGER_SERVER_TYPE, SurfaceflingerServerClass))
-#define IS_SURFACEFLINGER_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SURFACEFLINGER_SERVER_TYPE))
-
-typedef struct SurfaceflingerServerPrivate SurfaceflingerServerPrivate;
-
-typedef struct
-{
- DisplayServer parent_instance;
- SurfaceflingerServerPrivate *priv;
-} SurfaceflingerServer;
-
-typedef struct
-{
- DisplayServerClass parent_class;
-} SurfaceflingerServerClass;
-
-GType surfaceflinger_server_get_type (void);
-
-SurfaceflingerServer *surfaceflinger_server_new (void);
-
-const gchar *surfaceflinger_server_get_id (SurfaceflingerServer *server);
-
-G_END_DECLS
-
-#endif /* SURFACEFLINGER_SERVER_H_ */
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 \
test-unity-mir-session-x-greeter \
test-unity-mir-switch \
test-unity-mir-switch-to-user-resettable \
- test-unity-xdg-seat \
- test-surfaceflinger-autologin
+ test-unity-xdg-seat
# test-session-exit-error
# test-greeter-no-exit
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 \
scripts/1-additional.conf \
scripts/additional-config.conf \
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 \
scripts/session-stderr.conf \
scripts/session-stderr-multi-write.conf \
scripts/session-stderr-backup.conf \
- scripts/surfaceflinger-autologin.conf \
scripts/switch-to-greeter.conf \
scripts/switch-to-greeter-disabled.conf \
scripts/switch-to-greeter-new-session.conf \
--- /dev/null
+[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
+++ /dev/null
-[Desktop Entry]
-Name=Test Session
-Comment=LightDM test Surfaceflinger session
-Exec=test-session
-X-LightDM-Session-Type=surfaceflinger
--- /dev/null
+#
+# 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
+++ /dev/null
-#
-# Check can automatically log into a Surfaceflinger session
-#
-
-[SeatDefaults]
-type=surfaceflinger
-autologin-user=have-password1
-user-session=surfaceflinger
-
-#?*START-DAEMON
-#?RUNNER DAEMON-START
-
-# Session starts (test session doesn't know it's in surfaceflinger)
-#?SESSION-UNKNOWN START XDG_SEAT=seat0 XDG_VTNR=1 XDG_GREETER_DATA_DIR=.*/have-password1 XDG_SESSION_DESKTOP=surfaceflinger USER=have-password1
-#?LOGIN1 ACTIVATE-SESSION SESSION=c0
-
-# Cleanup
-#?*STOP-DAEMON
-#?SESSION-UNKNOWN TERMINATE SIGNAL=15
-#?RUNNER DAEMON-EXIT STATUS=0
{
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;
}
else if (strcmp (arg, "--test") == 0)
test = TRUE;
+ else if (strcmp (arg, "--container") == 0)
+ container = TRUE;
else
return EXIT_FAILURE;
}
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);
--- /dev/null
+#!/bin/sh
+./src/dbus-env ./src/test-runner mir-container-session test-gobject-greeter
+++ /dev/null
-#!/bin/sh
-./src/dbus-env ./src/test-runner surfaceflinger-autologin test-gobject-greeter