diff options
author | Matthias Clasen <mclasen@redhat.com> | 2011-05-17 12:44:22 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-10-21 02:15:55 -0400 |
commit | f4a1a84e8bb31908dbba66aa0ca071054739790a (patch) | |
tree | 494d8adad85e0f94e3fe87be1fc1f410f420a590 | |
parent | 275a6bc0b443a2b76301b38488f5addfa69011ac (diff) | |
download | gdm-f4a1a84e8bb31908dbba66aa0ca071054739790a.tar.gz |
Initial work towards alternative welcome sessions
Patch from bug 650366; it will be easier to work through the review
in the branch.
-rw-r--r-- | common/gdm-settings-keys.h | 1 | ||||
-rw-r--r-- | daemon/Makefile.am | 2 | ||||
-rw-r--r-- | daemon/gdm-display.c | 32 | ||||
-rw-r--r-- | daemon/gdm-display.h | 4 | ||||
-rw-r--r-- | daemon/gdm-display.xml | 3 | ||||
-rw-r--r-- | daemon/gdm-setup-session.c | 162 | ||||
-rw-r--r-- | daemon/gdm-setup-session.h | 61 | ||||
-rw-r--r-- | daemon/gdm-simple-slave.c | 167 | ||||
-rw-r--r-- | daemon/gdm-slave.c | 36 | ||||
-rw-r--r-- | daemon/gdm-slave.h | 3 | ||||
-rw-r--r-- | data/gdm.schemas.in.in | 5 |
11 files changed, 469 insertions, 7 deletions
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h index 65a16280..e908c642 100644 --- a/common/gdm-settings-keys.h +++ b/common/gdm-settings-keys.h @@ -32,6 +32,7 @@ G_BEGIN_DECLS #define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable" #define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin" #define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay" +#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable" #define GDM_KEY_DEBUG "debug/Enable" diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 98b95ce9..588bf3b4 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -121,6 +121,8 @@ gdm_simple_slave_SOURCES = \ gdm-welcome-session.h \ gdm-greeter-session.c \ gdm-greeter-session.h \ + gdm-setup-session.c \ + gdm-setup-session.h \ gdm-server.c \ gdm-server.h \ gdm-session.c \ diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index 6ee675ac..d63ecec0 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -385,6 +385,37 @@ gdm_display_get_timed_login_details (GdmDisplay *display, return TRUE; } +static void +gdm_display_real_get_initial_setup_details (GdmDisplay *display, + gboolean *enabledp) +{ + gboolean enabled; + gboolean res; + + enabled = FALSE; + + res = gdm_settings_direct_get_boolean (GDM_KEY_INITIAL_SETUP_ENABLE, &enabled); + + if (enabledp != NULL) { + *enabledp = enabled; + } +} + +gboolean +gdm_display_get_initial_setup_details (GdmDisplay *display, + gboolean *enabled) +{ + g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); + + GDM_DISPLAY_GET_CLASS (display)->get_initial_setup_details (display, enabled); + + g_debug ("GdmSlave: Got initial setup details for display %s: %d", + display->priv->x11_display_name, + *enabled); + + return TRUE; +} + static gboolean gdm_display_real_remove_user_authorization (GdmDisplay *display, const char *username, @@ -1020,6 +1051,7 @@ gdm_display_class_init (GdmDisplayClass *klass) klass->remove_user_authorization = gdm_display_real_remove_user_authorization; klass->set_slave_bus_name = gdm_display_real_set_slave_bus_name; klass->get_timed_login_details = gdm_display_real_get_timed_login_details; + klass->get_initial_setup_details = gdm_display_real_get_initial_setup_details; klass->prepare = gdm_display_real_prepare; klass->manage = gdm_display_real_manage; klass->finish = gdm_display_real_finish; diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h index 607ea1d4..474a771d 100644 --- a/daemon/gdm-display.h +++ b/daemon/gdm-display.h @@ -74,6 +74,8 @@ typedef struct gboolean *enabled, char **username, int *delay); + void (*get_initial_setup_details) (GdmDisplay *display, + gboolean *enabled); } GdmDisplayClass; typedef enum @@ -122,6 +124,8 @@ gboolean gdm_display_get_timed_login_details (GdmDisplay *disp char **username, int *delay, GError **error); +gboolean gdm_display_get_initial_setup_details (GdmDisplay *display, + gboolean *enabled); /* exported but protected */ gboolean gdm_display_get_x11_cookie (GdmDisplay *display, diff --git a/daemon/gdm-display.xml b/daemon/gdm-display.xml index a92e37fc..87ea7c25 100644 --- a/daemon/gdm-display.xml +++ b/daemon/gdm-display.xml @@ -40,5 +40,8 @@ <arg name="username" direction="out" type="s"/> <arg name="delay" direction="out" type="i"/> </method> + <method name="GetInitialSetupDetails"> + <arg name="enabled" direction="out" type="b"/> + </method> </interface> </node> diff --git a/daemon/gdm-setup-session.c b/daemon/gdm-setup-session.c new file mode 100644 index 00000000..2f1e3b79 --- /dev/null +++ b/daemon/gdm-setup-session.c @@ -0,0 +1,162 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011 Red Hat, Inc. + * Author: Matthias Clasen + * + * 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <ctype.h> +#include <pwd.h> +#include <grp.h> +#include <signal.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <glib-object.h> + +#include "gdm-welcome-session.h" +#include "gdm-setup-session.h" + +#define GDM_GREETER_SERVER_DBUS_PATH "/org/gnome/DisplayManager/GreeterServer" +#define GDM_GREETER_SERVER_DBUS_INTERFACE "org.gnome.DisplayManager.GreeterServer" + +#define GDM_SETUP_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SETUP_SESSION, GdmSetupSessionPrivate)) + +struct GdmSetupSessionPrivate +{ + gpointer dummy; +}; + +enum { + PROP_0, +}; + +static void gdm_setup_session_class_init (GdmSetupSessionClass *klass); +static void gdm_setup_session_init (GdmSetupSession *setup_session); +static void gdm_setup_session_finalize (GObject *object); + +G_DEFINE_TYPE (GdmSetupSession, gdm_setup_session, GDM_TYPE_WELCOME_SESSION) + +static void +gdm_setup_session_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_setup_session_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gdm_setup_session_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmSetupSession *setup_session; + + setup_session = GDM_SETUP_SESSION (G_OBJECT_CLASS (gdm_setup_session_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (setup_session); +} + +static void +gdm_setup_session_class_init (GdmSetupSessionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_setup_session_get_property; + object_class->set_property = gdm_setup_session_set_property; + object_class->constructor = gdm_setup_session_constructor; + object_class->finalize = gdm_setup_session_finalize; + + g_type_class_add_private (klass, sizeof (GdmSetupSessionPrivate)); +} + +static void +gdm_setup_session_init (GdmSetupSession *setup_session) +{ + setup_session->priv = GDM_SETUP_SESSION_GET_PRIVATE (setup_session); +} + +static void +gdm_setup_session_finalize (GObject *object) +{ + GdmSetupSession *setup_session; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_SETUP_SESSION (object)); + + setup_session = GDM_SETUP_SESSION (object); + + g_return_if_fail (setup_session->priv != NULL); + + G_OBJECT_CLASS (gdm_setup_session_parent_class)->finalize (object); +} + +GdmSetupSession * +gdm_setup_session_new (const char *display_name, + const char *seat_id, + const char *display_device, + const char *display_hostname, + gboolean display_is_local) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_SETUP_SESSION, + "command", BINDIR "/gnome-session --session gdm", + "server-dbus-path", GDM_GREETER_SERVER_DBUS_PATH, + "server-dbus-interface", GDM_GREETER_SERVER_DBUS_INTERFACE, + "server-env-var-name", "GDM_GREETER_DBUS_ADDRESS", + "register-ck-session", TRUE, + "x11-display-name", display_name, + "x11-display-seat-id", seat_id, + "x11-display-device", display_device, + "x11-display-hostname", display_hostname, + "x11-display-is-local", display_is_local, + "runtime-dir", GDM_SCREENSHOT_DIR, + NULL); + + return GDM_SETUP_SESSION (object); +} diff --git a/daemon/gdm-setup-session.h b/daemon/gdm-setup-session.h new file mode 100644 index 00000000..c674c6c1 --- /dev/null +++ b/daemon/gdm-setup-session.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011 Red Hat, Inc. + * Author: Matthias Clasen + * + * 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 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + +#ifndef __GDM_SETUP_SESSION_H +#define __GDM_SETUP_SESSION_H + +#include <glib-object.h> + +#include "gdm-welcome-session.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_SETUP_SESSION (gdm_setup_session_get_type ()) +#define GDM_SETUP_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SETUP_SESSION, GdmSetupSession)) +#define GDM_SETUP_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SETUP_SESSION, GdmSetupSessionClass)) +#define GDM_IS_SETUP_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SETUP_SESSION)) +#define GDM_IS_SETUP_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SETUP_SESSION)) +#define GDM_SETUP_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SETUP_SESSION, GdmSetupSessionClass)) + +typedef struct GdmSetupSessionPrivate GdmSetupSessionPrivate; + +typedef struct +{ + GdmWelcomeSession parent; + GdmSetupSessionPrivate *priv; +} GdmSetupSession; + +typedef struct +{ + GdmWelcomeSessionClass parent_class; +} GdmSetupSessionClass; + +GType gdm_setup_session_get_type (void); +GdmSetupSession * gdm_setup_session_new (const char *display_name, + const char *seat_id, + const char *display_device, + const char *display_hostname, + gboolean display_is_local); + +G_END_DECLS + +#endif /* __GDM_SETUP_SESSION_H */ diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c index 2f0163f3..49145fe4 100644 --- a/daemon/gdm-simple-slave.c +++ b/daemon/gdm-simple-slave.c @@ -57,6 +57,7 @@ #include "gdm-session-direct.h" #include "gdm-greeter-server.h" #include "gdm-greeter-session.h" +#include "gdm-setup-session.h" #include "gdm-settings-direct.h" #include "gdm-settings-keys.h" @@ -86,7 +87,7 @@ struct GdmSimpleSlavePrivate GdmSessionDirect *session; GdmGreeterServer *greeter_server; - GdmGreeterSession *greeter; + GdmWelcomeSession *greeter; guint start_session_when_ready : 1; guint waiting_to_start_session : 1; @@ -110,6 +111,7 @@ static void destroy_session (GdmSimpleSlave *slave); static void start_greeter (GdmSimpleSlave *slave); static void queue_start_session (GdmSimpleSlave *slave, const char *service_name); +static void start_initial_setup (GdmSimpleSlave *slave); static void on_session_started (GdmSession *session, @@ -1295,11 +1297,155 @@ start_greeter (GdmSimpleSlave *slave) gdm_greeter_server_start (slave->priv->greeter_server); g_debug ("GdmSimpleSlave: Creating greeter on %s %s %s", display_name, display_device, display_hostname); - slave->priv->greeter = gdm_greeter_session_new (display_name, - seat_id, - display_device, - display_hostname, - display_is_local); + slave->priv->greeter = (GdmWelcomeSession*)gdm_greeter_session_new (display_name, + seat_id, + display_device, + display_hostname, + display_is_local); + g_signal_connect (slave->priv->greeter, + "started", + G_CALLBACK (on_greeter_session_start), + slave); + g_signal_connect (slave->priv->greeter, + "stopped", + G_CALLBACK (on_greeter_session_stop), + slave); + g_signal_connect (slave->priv->greeter, + "exited", + G_CALLBACK (on_greeter_session_exited), + slave); + g_signal_connect (slave->priv->greeter, + "died", + G_CALLBACK (on_greeter_session_died), + slave); + g_object_set (slave->priv->greeter, + "x11-authority-file", auth_file, + NULL); + + address = gdm_greeter_server_get_address (slave->priv->greeter_server); + gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->greeter), address); + g_free (address); + gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->greeter)); + + g_free (display_id); + g_free (display_name); + g_free (seat_id); + g_free (display_device); + g_free (display_hostname); + g_free (auth_file); +} + +static void +start_initial_setup (GdmSimpleSlave *slave) +{ + gboolean display_is_local; + char *display_id; + char *display_name; + char *seat_id; + char *display_device; + char *display_hostname; + char *auth_file; + char *address; + gboolean res; + + g_debug ("GdmSimpleSlave: Running initial setup"); + + display_is_local = FALSE; + display_id = NULL; + display_name = NULL; + seat_id = NULL; + auth_file = NULL; + display_device = NULL; + display_hostname = NULL; + + g_object_get (slave, + "display-id", &display_id, + "display-is-local", &display_is_local, + "display-name", &display_name, + "display-seat-id", &seat_id, + "display-hostname", &display_hostname, + "display-x11-authority-file", &auth_file, + NULL); + + g_debug ("GdmSimpleSlave: Creating initial setup for %s %s", display_name, display_hostname); + + if (slave->priv->server != NULL) { + display_device = gdm_server_get_display_device (slave->priv->server); + } + + /* FIXME: send a signal back to the master */ + + /* If XDMCP setup pinging */ + slave->priv->ping_interval = DEFAULT_PING_INTERVAL; + res = gdm_settings_direct_get_int (GDM_KEY_PING_INTERVAL, + &(slave->priv->ping_interval)); + + if ( ! display_is_local && slave->priv->ping_interval > 0) { + alarm (slave->priv->ping_interval); + } + + /* Run the init script. gdmslave suspends until script has terminated */ + gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME); + + slave->priv->greeter_server = gdm_greeter_server_new (display_id); + g_signal_connect (slave->priv->greeter_server, + "begin-auto-login", + G_CALLBACK (on_greeter_begin_auto_login), + slave); + g_signal_connect (slave->priv->greeter_server, + "begin-verification", + G_CALLBACK (on_greeter_begin_verification), + slave); + g_signal_connect (slave->priv->greeter_server, + "begin-verification-for-user", + G_CALLBACK (on_greeter_begin_verification_for_user), + slave); + g_signal_connect (slave->priv->greeter_server, + "query-answer", + G_CALLBACK (on_greeter_answer), + slave); + g_signal_connect (slave->priv->greeter_server, + "session-selected", + G_CALLBACK (on_greeter_session_selected), + slave); + g_signal_connect (slave->priv->greeter_server, + "language-selected", + G_CALLBACK (on_greeter_language_selected), + slave); + g_signal_connect (slave->priv->greeter_server, + "user-selected", + G_CALLBACK (on_greeter_user_selected), + slave); + g_signal_connect (slave->priv->greeter_server, + "connected", + G_CALLBACK (on_greeter_connected), + slave); + g_signal_connect (slave->priv->greeter_server, + "disconnected", + G_CALLBACK (on_greeter_disconnected), + slave); + g_signal_connect (slave->priv->greeter_server, + "cancelled", + G_CALLBACK (on_greeter_cancel), + slave); + g_signal_connect (slave->priv->greeter_server, + "start-session-when-ready", + G_CALLBACK (on_start_session_when_ready), + slave); + + g_signal_connect (slave->priv->greeter_server, + "start-session-later", + G_CALLBACK (on_start_session_later), + slave); + + gdm_greeter_server_start (slave->priv->greeter_server); + + g_debug ("GdmSimpleSlave: Creating initial setup on %s %s %s", display_name, display_device, display_hostname); + slave->priv->greeter = (GdmWelcomeSession *)gdm_setup_session_new (display_name, + seat_id, + display_device, + display_hostname, + display_is_local); g_signal_connect (slave->priv->greeter, "started", G_CALLBACK (on_greeter_session_start), @@ -1344,15 +1490,22 @@ idle_connect_to_display (GdmSimpleSlave *slave) if (res) { gboolean enabled; int delay; + gboolean initial_setup_enabled; /* FIXME: handle wait-for-go */ setup_server (slave); + initial_setup_enabled = FALSE; + gdm_slave_get_initial_setup_details (GDM_SLAVE (slave), &initial_setup_enabled); + delay = 0; enabled = FALSE; gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay); - if (! enabled || delay > 0) { + if (initial_setup_enabled) { + start_initial_setup (slave); + create_new_session (slave); + } else if (! enabled || delay > 0) { start_greeter (slave); create_new_session (slave); } else { diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c index 2dc0323f..33a22eb1 100644 --- a/daemon/gdm-slave.c +++ b/daemon/gdm-slave.c @@ -1122,6 +1122,42 @@ gdm_slave_get_timed_login_details (GdmSlave *slave, return res; } +gboolean +gdm_slave_get_initial_setup_details (GdmSlave *slave, + gboolean *enabledp) +{ + GError *error; + gboolean res; + gboolean enabled; + + g_debug ("GdmSlave: Requesting initial setup details"); + + error = NULL; + res = dbus_g_proxy_call (slave->priv->display_proxy, + "GetInitialSetupDetails", + &error, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &enabled, + G_TYPE_INVALID); + + if (! res) { + if (error != NULL) { + g_warning ("Failed to get initial setup details: %s", error->message); + g_error_free (error); + } else { + g_warning ("Failed to get initial setup details"); + } + } else { + g_debug ("GdmSlave: Got initial setup details: %d", enabled); + } + + if (enabledp != NULL) { + *enabledp = enabled; + } + + return res; +} + static gboolean _get_uid_and_gid_for_user (const char *username, uid_t *uid, diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h index eda2e193..c4a944d8 100644 --- a/daemon/gdm-slave.h +++ b/daemon/gdm-slave.h @@ -65,6 +65,9 @@ gboolean gdm_slave_get_timed_login_details (GdmSlave *slave, char **username, int *delay); +gboolean gdm_slave_get_initial_setup_details (GdmSlave *slave, + gboolean *enabled); + gboolean gdm_slave_add_user_authorization (GdmSlave *slave, const char *username, char **filename); diff --git a/data/gdm.schemas.in.in b/data/gdm.schemas.in.in index 514117d7..f049c2fd 100644 --- a/data/gdm.schemas.in.in +++ b/data/gdm.schemas.in.in @@ -47,6 +47,11 @@ <signature>i</signature> <default>30</default> </schema> + <schema> + <key>daemon/InitialSetupEnable</key> + <signature>b</signature> + <default>false</default> + </schema> <schema> <key>debug/Enable</key> |