po/stamp-it
po/POTFILES
src/lightdm
-src/display-glue.h
src/ldmgreeter
src/ldmgreeter
+src/display-glue.h
src/display-manager-glue.h
+src/user-manager-glue.h
+src/session-manager-glue.h
<allow send_destination="org.gnome.LightDisplayManager" send_interface="org.gnome.LightDisplayManager"/>
<allow send_destination="org.gnome.LightDisplayManager" send_interface="org.gnome.LightDisplayManager.Display"/>
<allow send_destination="org.gnome.LightDisplayManager" send_interface="org.gnome.LightDisplayManager.Users"/>
+ <allow send_destination="org.gnome.LightDisplayManager" send_interface="org.gnome.LightDisplayManager.Session"/>
</policy>
</busconfig>
$(DBUSBINDINGTOOL) --prefix=display --mode=glib-server --output=$@ $^
display-manager-glue.h: display-manager.xml
$(DBUSBINDINGTOOL) --prefix=display_manager --mode=glib-server --output=$@ $^
+session-manager-glue.h: session-manager.xml
+ $(DBUSBINDINGTOOL) --prefix=session_manager --mode=glib-server --output=$@ $^
user-manager-glue.h: user-manager.xml
$(DBUSBINDINGTOOL) --prefix=user_manager --mode=glib-server --output=$@ $^
lightdm.c \
pam-session.c \
pam-session.h \
+ session-manager.c \
+ session-manager.h \
user-manager.c \
user-manager.h
BUILT_SOURCES = \
display-glue.h \
display-manager-glue.h \
+ session-manager-glue.h \
user-manager-glue.h
lightdm_CFLAGS = \
-DVERSION=\"$(VERSION)\" \
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
-DLOCALE_DIR=\"$(localedir)\" \
+ -DXSESSIONS_DIR=\"$(prefix)/share/xsessions\" \
-DGREETER_USER=\"gdm\" \
-DGREETER_BINARY=\"$(prefix)/bin/ldmgreeter\" \
-DLIGHTDM_BINARY=\"lightdm\"
{
DBusGConnection *bus;
- DBusGProxy *display_proxy, *user_proxy;
+ DBusGProxy *display_proxy, *session_proxy, *user_proxy;
gboolean have_users;
GList *users;
+ gboolean have_sessions;
+ GList *sessions;
+
gboolean is_authenticated;
};
return greeter->priv->users;
}
+#define TYPE_SESSION dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID)
+#define TYPE_SESSION_LIST dbus_g_type_get_collection ("GPtrArray", TYPE_SESSION)
+
+static void
+update_sessions (Greeter *greeter)
+{
+ GPtrArray *sessions;
+ gboolean result;
+ gint i;
+ GError *error = NULL;
+
+ if (greeter->priv->have_sessions)
+ return;
+
+ result = dbus_g_proxy_call (greeter->priv->session_proxy, "GetSessions", &error,
+ G_TYPE_INVALID,
+ TYPE_SESSION_LIST, &sessions,
+ G_TYPE_INVALID);
+ if (!result)
+ g_warning ("Failed to get sessions: %s", error->message);
+ g_clear_error (&error);
+
+ if (!result)
+ return;
+
+ for (i = 0; i < sessions->len; i++)
+ {
+ GValue value = { 0 };
+ Session *session;
+
+ session = g_malloc0 (sizeof (Session));
+
+ g_value_init (&value, TYPE_SESSION);
+ g_value_set_static_boxed (&value, sessions->pdata[i]);
+ dbus_g_type_struct_get (&value, 0, &session->name, 1, &session->comment, G_MAXUINT);
+
+ g_value_unset (&value);
+
+ greeter->priv->sessions = g_list_append (greeter->priv->sessions, session);
+ }
+
+ g_ptr_array_free (sessions, TRUE);
+
+ greeter->priv->have_sessions = TRUE;
+}
+
+const GList *
+greeter_get_sessions (Greeter *greeter)
+{
+ update_sessions (greeter);
+ return greeter->priv->sessions;
+}
+
#define TYPE_MESSAGE dbus_g_type_get_struct ("GValueArray", G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID)
#define TYPE_MESSAGE_LIST dbus_g_type_get_collection ("GPtrArray", TYPE_MESSAGE)
"org.gnome.LightDisplayManager",
"/org/gnome/LightDisplayManager/Display",
"org.gnome.LightDisplayManager.Greeter");
+ greeter->priv->session_proxy = dbus_g_proxy_new_for_name (greeter->priv->bus,
+ "org.gnome.LightDisplayManager",
+ "/org/gnome/LightDisplayManager/Session",
+ "org.gnome.LightDisplayManager.Session");
greeter->priv->user_proxy = dbus_g_proxy_new_for_name (greeter->priv->bus,
"org.gnome.LightDisplayManager",
"/org/gnome/LightDisplayManager/Users",
const char *real_name;
} UserInfo;
+typedef struct
+{
+ const char *name;
+ const char *comment;
+} Session;
+
GType greeter_get_type (void);
Greeter *greeter_new (void);
const GList *greeter_get_users (Greeter *greeter);
+const GList *greeter_get_sessions (Greeter *greeter);
+
void greeter_start_authentication (Greeter *greeter, const char *username);
void greeter_provide_secret (Greeter *greeter, const gchar *secret);
#include "greeter.h"
static Greeter *greeter;
-static GtkListStore *user_model;
-static GtkWidget *user_window, *vbox, *label, *user_view, *username_entry, *password_entry;
+static GtkListStore *session_model, *user_model;
+static GtkWidget *user_window, *vbox, *label, *user_view;
+static GtkWidget *username_entry, *password_entry;
+static GtkWidget *session_combo;
static GtkWidget *panel_window;
static void
int
main(int argc, char **argv)
{
- const GList *users, *link;
+ const GList *sessions, *users, *link;
GtkCellRenderer *renderer;
GdkDisplay *display;
GdkScreen *screen;
gtk_widget_set_sensitive (password_entry, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), password_entry, FALSE, FALSE, 0);
g_signal_connect (password_entry, "activate", G_CALLBACK (password_activate_cb), NULL);
+
+ session_model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ sessions = greeter_get_sessions (greeter);
+ for (link = sessions; link; link = link->next)
+ {
+ Session *session = link->data;
+ GtkTreeIter iter;
+
+ gtk_list_store_append (GTK_LIST_STORE (session_model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (session_model), &iter,
+ 0, session->name,
+ 1, session->name,
+ -1);
+ }
+
+ session_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (session_model));
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (session_combo), renderer, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (session_combo), renderer, "text", 1);
+ gtk_box_pack_start (GTK_BOX (vbox), session_combo, FALSE, FALSE, 0);
gtk_widget_show_all (user_window);
#include "display-manager.h"
#include "user-manager.h"
+#include "session-manager.h"
static GMainLoop *loop;
static gboolean debug = FALSE;
{
DisplayManager *display_manager;
UserManager *user_manager;
+ SessionManager *session_manager;
DBusGConnection *bus;
struct sigaction action;
GError *error = NULL;
user_manager = user_manager_new ();
dbus_g_connection_register_g_object (bus, "/org/gnome/LightDisplayManager/Users", G_OBJECT (user_manager));
+ session_manager = session_manager_new ();
+ dbus_g_connection_register_g_object (bus, "/org/gnome/LightDisplayManager/Session", G_OBJECT (session_manager));
+
display_manager = display_manager_new ();
dbus_g_connection_register_g_object (bus, "/org/gnome/LightDisplayManager", G_OBJECT (display_manager));
--- /dev/null
+/*
+ * Copyright (C) 2010 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 "session-manager.h"
+#include "session-manager-glue.h"
+
+struct SessionManagerPrivate
+{
+ gboolean sessions_loaded;
+ GList *sessions;
+};
+
+G_DEFINE_TYPE (SessionManager, session_manager, G_TYPE_OBJECT);
+
+SessionManager *
+session_manager_new (void)
+{
+ return g_object_new (SESSION_MANAGER_TYPE, NULL);
+}
+
+static void
+session_free (Session *session)
+{
+ g_free (session->name);
+ g_free (session->comment);
+ g_free (session->exec);
+ g_free (session);
+}
+
+static Session *
+load_session (GKeyFile *key_file, GError **error)
+{
+ Session *session;
+
+ session = g_malloc0 (sizeof (Session));
+
+ session->name = g_key_file_get_locale_string(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, error);
+ if (!session->name)
+ {
+ session_free (session);
+ return NULL;
+ }
+
+ session->comment = g_key_file_get_locale_string(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, error);
+ if (!session->comment)
+ {
+ session_free (session);
+ return NULL;
+ }
+
+ session->exec = g_key_file_get_value(key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, error);
+ if (!session->exec)
+ {
+ session_free (session);
+ return NULL;
+ }
+
+ return session;
+}
+
+static void
+load_sessions (SessionManager *manager)
+{
+ GDir *directory;
+ GError *error = NULL;
+ GKeyFile *key_file;
+
+ if (manager->priv->sessions_loaded)
+ return;
+
+ directory = g_dir_open (XSESSIONS_DIR, 0, &error);
+ if (!directory)
+ g_warning ("Failed to open sessions directory: %s", error->message);
+ g_clear_error (&error);
+ if (!directory)
+ return;
+
+ key_file = g_key_file_new ();
+ while (TRUE)
+ {
+ const gchar *filename;
+ gchar *path;
+ gboolean result;
+ Session *session;
+
+ filename = g_dir_read_name (directory);
+ if (filename == NULL)
+ break;
+
+ if (!g_str_has_suffix (filename, ".desktop"))
+ continue;
+
+ path = g_build_filename (XSESSIONS_DIR, filename, NULL);
+ g_debug ("Loading session %s", path);
+
+ result = g_key_file_load_from_file(key_file, path, G_KEY_FILE_NONE, &error);
+ if (!result)
+ g_warning ("Failed to load session file %s: %s:", path, error->message);
+ g_clear_error (&error);
+
+ if (result)
+ {
+ session = load_session (key_file, &error);
+ if (session)
+ {
+ g_debug ("Loaded session %s (%s)", session->name, session->comment);
+ manager->priv->sessions = g_list_append (manager->priv->sessions, session);
+ }
+ else
+ g_warning ("Invalid session %s: %s", path, error->message);
+ g_clear_error (&error);
+ }
+
+ g_free (path);
+ }
+
+ g_dir_close (directory);
+ g_key_file_free (key_file);
+
+ manager->priv->sessions_loaded = TRUE;
+}
+
+#define TYPE_SESSION dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID)
+
+gboolean
+session_manager_get_sessions (SessionManager *manager, GPtrArray **sessions, GError *error)
+{
+ GList *link;
+
+ load_sessions (manager);
+
+ *sessions = g_ptr_array_sized_new (g_list_length (manager->priv->sessions));
+ for (link = manager->priv->sessions; link; link = link->next)
+ {
+ Session *session = link->data;
+ GValue value = { 0 };
+
+ g_value_init (&value, TYPE_SESSION);
+ g_value_take_boxed (&value, dbus_g_type_specialized_construct (TYPE_SESSION));
+ dbus_g_type_struct_set (&value, 0, session->name, 1, session->comment, G_MAXUINT);
+ g_ptr_array_add (*sessions, g_value_get_boxed (&value));
+ }
+
+ return TRUE;
+}
+
+static void
+session_manager_init (SessionManager *manager)
+{
+ manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, SESSION_MANAGER_TYPE, SessionManagerPrivate);
+}
+
+static void
+session_manager_class_init (SessionManagerClass *klass)
+{
+ g_type_class_add_private (klass, sizeof (SessionManagerPrivate));
+
+ dbus_g_object_type_install_info (SESSION_MANAGER_TYPE, &dbus_glib_session_manager_object_info);
+}
--- /dev/null
+/*
+ * Copyright (C) 2010 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 _SESSION_MANAGER_H_
+#define _SESSION_MANAGER_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SESSION_MANAGER_TYPE (session_manager_get_type())
+#define SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_MANAGER_TYPE, SessionManager));
+
+typedef struct SessionManagerPrivate SessionManagerPrivate;
+
+typedef struct
+{
+ GObject parent_instance;
+ SessionManagerPrivate *priv;
+} SessionManager;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} SessionManagerClass;
+
+typedef struct
+{
+ char *name;
+ char *comment;
+ char *exec;
+} Session;
+
+GType session_manager_get_type (void);
+
+SessionManager *session_manager_new (void);
+
+gboolean session_manager_get_sessions (SessionManager *manager, GPtrArray **sessions, GError *error);
+
+G_END_DECLS
+
+#endif /* _SESSION_MANAGER_H_ */
--- /dev/null
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.gnome.LightDisplayManager.Session">
+
+ <!-- Method to return the users -->
+ <method name="GetSessions">
+ <arg name="users" direction="out" type="a(ss)"/>
+ </method>
+
+ </interface>
+</node>