diff -ruN gdm-2.30.5.orig/common/Makefile.am gdm-2.30.5/common/Makefile.am --- gdm-2.30.5.orig/common/Makefile.am 2010-09-01 22:01:35.683042849 +0500 +++ gdm-2.30.5/common/Makefile.am 2010-09-01 21:58:42.953973704 +0500 @@ -21,6 +21,7 @@ -DGDM_DEFAULTS_CONF=\"$(GDM_DEFAULTS_CONF)\" \ -DGDM_CUSTOM_CONF=\"$(GDM_CUSTOM_CONF)\" \ -DGDM_OLD_CONF=\"$(GDM_OLD_CONF)\" \ + -DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \ $(COMMON_CFLAGS) \ $(NULL) diff -ruN gdm-2.30.5.orig/common/gdm-common.c gdm-2.30.5/common/gdm-common.c --- gdm-2.30.5.orig/common/gdm-common.c 2010-09-01 22:01:35.609411138 +0500 +++ gdm-2.30.5/common/gdm-common.c 2010-09-01 21:58:42.591978553 +0500 @@ -495,3 +495,64 @@ return retval; } +gboolean +gdm_check_first_time_login (char *username) +{ + struct passwd *pwent = NULL; + gboolean ret = FALSE; + + g_return_val_if_fail (username != NULL && username[0], FALSE); + + pwent = getpwnam (username); + if (pwent != NULL && pwent->pw_dir != NULL) { + char *user_dmrc; + user_dmrc = g_build_filename (pwent->pw_dir, ".dmrc", NULL); + if (!g_file_test (user_dmrc, G_FILE_TEST_EXISTS)) { + char *sys_dmrc; + sys_dmrc = g_build_filename (GDM_CACHE_DIR, username, "dmrc", NULL); + if (!g_file_test (sys_dmrc, G_FILE_TEST_EXISTS)) + ret = TRUE; + g_free (sys_dmrc); + } + g_free (user_dmrc); + } + return ret; +} + +char * +gdm_user_home (char *username) +{ + struct passwd *pwent = NULL; + + g_return_val_if_fail (username != NULL && username[0], NULL); + + pwent = getpwnam (username); + if (pwent != NULL && pwent->pw_dir != NULL && + g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) + return g_strdup (pwent->pw_dir); + else + return NULL; +} + +char * +gdm_create_temp_gdm_dmrc_filename (char *username) { + char *tmp_filename = NULL; + char *gdm_home = NULL; + char *login_home = NULL; + + g_return_val_if_fail (username != NULL && username[0], NULL); + + gdm_home = gdm_user_home (GDM_USERNAME); + login_home = gdm_user_home (username); + + if (gdm_home && login_home) { + char *tmp_dmrc = g_strdup_printf ("%s.dmrc", username); + tmp_filename = g_build_filename (gdm_home, tmp_dmrc, NULL); + g_free (tmp_dmrc); + } + + g_free (gdm_home); + g_free (login_home); + + return (tmp_filename); +} diff -ruN gdm-2.30.5.orig/common/gdm-common.h gdm-2.30.5/common/gdm-common.h --- gdm-2.30.5.orig/common/gdm-common.h 2010-09-01 22:01:35.673196234 +0500 +++ gdm-2.30.5/common/gdm-common.h 2010-09-01 21:58:42.794900367 +0500 @@ -63,6 +63,9 @@ GError **error); char *gdm_read_default (gchar *key); +gboolean gdm_check_first_time_login (char *username); +char *gdm_user_home (char *username); +char *gdm_create_temp_gdm_dmrc_filename (char *username); G_END_DECLS diff -ruN gdm-2.30.5.orig/daemon/gdm-session-settings.c gdm-2.30.5/daemon/gdm-session-settings.c --- gdm-2.30.5.orig/daemon/gdm-session-settings.c 2010-09-01 22:01:35.709460311 +0500 +++ gdm-2.30.5/daemon/gdm-session-settings.c 2010-09-01 21:58:43.068598014 +0500 @@ -267,12 +267,112 @@ } gboolean +gdm_session_settings_first_time_load (GdmSessionSettings *settings, + const char *username, + GError **error) +{ + GKeyFile *key_file = NULL; + GError *load_error; + gboolean is_loaded; + char *session_name; + char *language_name; + char *layout_name; + char *filename = NULL; + + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (username != NULL, FALSE); + + if (settings->priv->session_name != NULL) { + g_debug ("Freeing old session value %s", settings->priv->session_name); + g_free (settings->priv->session_name); + settings->priv->session_name = NULL; + } + + if (settings->priv->language_name != NULL) { + g_debug ("Freeing old language value %s", settings->priv->language_name); + g_free (settings->priv->language_name); + settings->priv->language_name = NULL; + } + + if (settings->priv->layout_name != NULL) { + g_debug ("Freeing old layout value %s", settings->priv->layout_name); + g_free (settings->priv->layout_name); + settings->priv->layout_name = NULL; + } + + filename = g_build_filename (GDM_CACHE_DIR, username, "dmrc", NULL); + + is_loaded = FALSE; + + key_file = g_key_file_new (); + + load_error = NULL; + + if (!g_key_file_load_from_file (key_file, filename, + G_KEY_FILE_NONE, &load_error)) { + g_propagate_error (error, load_error); + goto out; + } + + session_name = g_key_file_get_string (key_file, "Desktop", + "Session", &load_error); + if (session_name != NULL) { + g_debug ("Setting value to %s", session_name); + gdm_session_settings_set_session_name (settings, session_name); + g_free (session_name); + } else if (g_error_matches (load_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { + g_error_free (load_error); + load_error = NULL; + } else { + g_propagate_error (error, load_error); + goto out; + } + + language_name = g_key_file_get_string (key_file, "Desktop", "Language", + &load_error); + + if (language_name != NULL) { + gdm_session_settings_set_language_name (settings, language_name); + g_free (language_name); + } else if (g_error_matches (load_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { + g_error_free (load_error); + load_error = NULL; + } else { + g_propagate_error (error, load_error); + goto out; + } + + layout_name = g_key_file_get_string (key_file, "Desktop", "Layout", + &load_error); + + if (layout_name != NULL) { + gdm_session_settings_set_layout_name (settings, layout_name); + g_free (layout_name); + } else if (g_error_matches (load_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { + g_error_free (load_error); + load_error = NULL; + } else { + g_propagate_error (error, load_error); + goto out; + } + + is_loaded = TRUE; +out: + if (key_file) + g_key_file_free (key_file); + if (filename) + g_free (filename); + + return is_loaded; +} + +gboolean gdm_session_settings_load (GdmSessionSettings *settings, const char *username, gboolean handle_last, GError **error) { - GKeyFile *key_file; + GKeyFile *key_file = NULL; GError *load_error; gboolean is_loaded; gboolean skip_session; @@ -281,7 +381,7 @@ char *session_name; char *language_name; char *layout_name; - char *filename; + char *filename = NULL; skip_session = FALSE; skip_language = FALSE; @@ -388,8 +488,10 @@ is_loaded = TRUE; out: - g_key_file_free (key_file); - g_free (filename); + if (key_file) + g_key_file_free (key_file); + if (filename) + g_free (filename); return is_loaded; } diff -ruN gdm-2.30.5.orig/daemon/gdm-session-settings.h gdm-2.30.5/daemon/gdm-session-settings.h --- gdm-2.30.5.orig/daemon/gdm-session-settings.h 2010-09-01 22:01:35.738996278 +0500 +++ gdm-2.30.5/daemon/gdm-session-settings.h 2010-09-01 21:58:43.219687977 +0500 @@ -53,6 +53,10 @@ GType gdm_session_settings_get_type (void); GdmSessionSettings *gdm_session_settings_new (void); +gboolean gdm_session_settings_first_time_load (GdmSessionSettings *settings, + const char *username, + GError **error); + gboolean gdm_session_settings_load (GdmSessionSettings *settings, const char *username, gboolean handle_last, diff -ruN gdm-2.30.5.orig/daemon/gdm-session-worker.c gdm-2.30.5/daemon/gdm-session-worker.c --- gdm-2.30.5.orig/daemon/gdm-session-worker.c 2010-09-01 22:01:35.897625192 +0500 +++ gdm-2.30.5/daemon/gdm-session-worker.c 2010-09-01 22:14:28.403340394 +0500 @@ -1100,10 +1100,37 @@ worker->priv->auditor = NULL; } +/* + * We create a special case if srcfile is + * ~gdm/priv->username>.dmrc and + * destfile is ~/.dmrc. In this case since + * ~gdm/priv->username>.dmrc is + * owned by ther user 'gdm', we need to by-pass + * the uid check for copying the file. + */ + +static gboolean +owner_check (GdmSessionWorker *worker, + const char *srcfile, + const char *destfile) +{ + gboolean ret = TRUE; + char *login_home = gdm_user_home (worker->priv->username); + char *user_dmrc = g_build_filename (login_home, ".dmrc", NULL); + char *temp_gdm_dmrc = gdm_create_temp_gdm_dmrc_filename (worker->priv->username); + if (!g_strcmp0 (temp_gdm_dmrc, srcfile) && !g_strcmp0 (user_dmrc, destfile)) + ret = FALSE; + + g_free (login_home); + g_free (user_dmrc); + g_free (temp_gdm_dmrc); + return ret; +} + static gboolean -check_user_copy_file (const char *srcfile, +check_user_copy_file (GdmSessionWorker *worker, + const char *srcfile, const char *destfile, - uid_t user, gssize max_file_size) { struct stat srcfileinfo; @@ -1134,7 +1161,7 @@ } /* Owned by user? */ - if (G_UNLIKELY (srcfileinfo.st_uid != user)) { + if (owner_check (worker, srcfile, destfile) && G_UNLIKELY (srcfileinfo.st_uid != worker->priv->uid)) { g_debug ("File is not owned by user"); return FALSE; } @@ -1158,9 +1185,9 @@ g_debug ("GdmSessionWorker: Checking if %s should be copied to cache %s", userfilename, cachefilename); - res = check_user_copy_file (userfilename, + res = check_user_copy_file (worker, + userfilename, cachefilename, - worker->priv->uid, MAX_FILE_SIZE); if (res) { @@ -1291,9 +1318,9 @@ NULL); g_debug ("Checking user's ~/.gnome/gdm file"); - res = check_user_copy_file (tempfilename, + res = check_user_copy_file (worker, + tempfilename, NULL, - worker->priv->uid, MAX_FILE_SIZE); if (res) { GKeyFile *keyfile; @@ -1824,6 +1851,89 @@ } static gboolean +copy_temp_dmrc_from_gdm_to_user (GdmSessionWorker *worker, char **filename) +{ + char *temp_gdm_dmrc; + char *login_home; + + if ((temp_gdm_dmrc = gdm_create_temp_gdm_dmrc_filename (worker->priv->username)) == NULL) + return FALSE; + + login_home = gdm_user_home (worker->priv->username); + /* + * gdm-first-time-login-helper saves the dmrc for + * worker->priv->username as temp_gdm_dmrc under + * gdm HOME. Copy this to .dmrc file under HOME and + * change the ownership. This is a special case usage + * for gdm_cache_copy_file. + */ + *filename = g_build_filename (login_home, ".dmrc", NULL); + gdm_cache_copy_file (worker, temp_gdm_dmrc, *filename); + + /* Remove .dmrc under gdm HOME */ + VE_IGNORE_EINTR (g_unlink (temp_gdm_dmrc)); + + g_free (login_home); + g_free (temp_gdm_dmrc); + return TRUE; +} + +static gboolean +run_gdm_first_time_login_helper (GdmSessionWorker *worker, char *session_name, + char *language_name, char *layout_name) +{ + gboolean success = FALSE; + pid_t fpid; + g_debug ("Running " LIBEXECDIR "/gdm-first-time-login-helper \"%s\" \"%s\" \"%s\" \"%s\"", + worker->priv->username ? worker->priv->username : "", + session_name ? session_name : "", + layout_name ? layout_name : "", + language_name ? language_name : ""); + char *argv[] = { LIBEXECDIR"/gdm-first-time-login-helper", + worker->priv->username ? worker->priv->username : "", + session_name ? session_name : "", + layout_name ? layout_name : "", + language_name ? language_name : "", + NULL }; + + fpid = fork(); + if (fpid > 0) { + int status; + /* Wait for the child to finish */ + if (waitpid (fpid, &status, 0) == -1) { + g_debug("User aborted gdm-first-time-login-helper"); + } else { + success = TRUE; + } + } else if (fpid == 0) { + execv (argv[0], argv); + g_debug("Cannot start gdm-first-time-login-helper"); + _exit (0); + } + + if (fpid == -1) { + g_debug("Cannot start gdm-first-time-login-helper"); + } + + if (success == TRUE) { + char *cachedir; + char *cachefile; + char *filename; + + copy_temp_dmrc_from_gdm_to_user (worker, &filename); + cachedir = gdm_session_worker_create_cachedir (worker); + g_debug ("Copying user dmrc file to cache"); + cachefile = g_build_filename (cachedir, "dmrc", NULL); + gdm_cache_copy_file (worker, filename, cachefile); + g_free (cachefile); + g_free (cachedir); + g_free (filename); + } + + return success; +} + +static gboolean gdm_session_worker_accredit_user (GdmSessionWorker *worker, GError **error) { @@ -1948,6 +2058,16 @@ attempt_to_load_user_settings (worker, worker->priv->username, TRUE); } + + if (gdm_check_first_time_login (worker->priv->username) && + !gdm_session_settings_is_loaded (worker->priv->user_settings) && + run_gdm_first_time_login_helper (worker, session_name, language_name, layout_name)) { + g_debug ("Now loading settings created by gdm-first-time-login-helper."); + gdm_session_settings_first_time_load (worker->priv->user_settings, worker->priv->username, NULL); + } else { + g_debug ("Did not run gdm-first-time-login-helper."); + } + g_free (session_name); g_free (language_name); g_free (layout_name); diff -ruN gdm-2.30.5.orig/daemon/gdm-simple-slave.c gdm-2.30.5/daemon/gdm-simple-slave.c --- gdm-2.30.5.orig/daemon/gdm-simple-slave.c 2010-09-01 22:01:36.019925754 +0500 +++ gdm-2.30.5/daemon/gdm-simple-slave.c 2010-09-01 21:58:43.531635831 +0500 @@ -1143,6 +1143,8 @@ res = gdm_slave_connect_to_x11_display (GDM_SLAVE (slave)); if (res) { gboolean enabled; + gboolean first_time_login; + char *username; int delay; /* FIXME: handle wait-for-go */ @@ -1151,8 +1153,14 @@ delay = 0; enabled = FALSE; - gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay); - if (! enabled || delay > 0) { + first_time_login = FALSE; + username = NULL; + gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay); + + if (username && username[0]) + first_time_login = gdm_check_first_time_login (username); + + if (! enabled || delay > 0 || first_time_login) { start_greeter (slave); create_new_session (slave); } else { @@ -1160,6 +1168,7 @@ gdm_slave_run_script (GDM_SLAVE (slave), GDMCONFDIR "/Init", GDM_USERNAME); reset_session (slave); } + g_free(username); } else { if (slave->priv->connection_attempts >= MAX_CONNECT_ATTEMPTS) { g_warning ("Unable to connect to display after %d tries - bailing out", slave->priv->connection_attempts); diff -ruN gdm-2.30.5.orig/gui/simple-greeter/Makefile.am gdm-2.30.5/gui/simple-greeter/Makefile.am --- gdm-2.30.5.orig/gui/simple-greeter/Makefile.am 2010-09-01 22:01:37.411576745 +0500 +++ gdm-2.30.5/gui/simple-greeter/Makefile.am 2010-09-01 21:58:43.638348167 +0500 @@ -280,7 +280,8 @@ $(NULL) libexec_PROGRAMS = \ - gdm-simple-greeter + gdm-simple-greeter \ + gdm-first-time-login-helper gdm_simple_greeter_SOURCES = \ greeter-main.c \ @@ -347,6 +348,62 @@ $(DEVKIT_POWER_LIBS) \ $(NULL) +gdm_first_time_login_helper_SOURCES = \ + gdm-first-time-login-helper.c \ + gdm-timer.h \ + gdm-timer.c \ + gdm-greeter-panel.h \ + gdm-greeter-panel.c \ + gdm-clock-widget.h \ + gdm-clock-widget.c \ + gdm-option-widget.h \ + gdm-option-widget.c \ + gdm-recent-option-widget.h \ + gdm-recent-option-widget.c \ + gdm-languages.h \ + gdm-languages.c \ + gdm-cell-renderer-timer.h \ + gdm-cell-renderer-timer.c \ + gdm-scrollable-widget.h \ + gdm-scrollable-widget.c \ + gdm-chooser-widget.h \ + gdm-chooser-widget.c \ + gdm-language-chooser-widget.h \ + gdm-language-chooser-widget.c \ + locarchive.h \ + gdm-language-chooser-dialog.h \ + gdm-language-chooser-dialog.c \ + gdm-language-option-widget.h \ + gdm-language-option-widget.c \ + gdm-layout-chooser-widget.h \ + gdm-layout-chooser-widget.c \ + gdm-layout-chooser-dialog.h \ + gdm-layout-chooser-dialog.c \ + gdm-layout-option-widget.h \ + gdm-layout-option-widget.c \ + gdm-layouts.h \ + gdm-layouts.c \ + gdm-sessions.h \ + gdm-sessions.c \ + gdm-session-chooser-widget.h \ + gdm-session-chooser-widget.c \ + gdm-session-chooser-dialog.h \ + gdm-session-chooser-dialog.c \ + gdm-session-option-widget.h \ + gdm-session-option-widget.c \ + branding.h \ + branding.c \ + $(NULL) + +gdm_first_time_login_helper_LDADD = \ + $(top_builddir)/common/libgdmcommon.la \ + $(top_builddir)/gui/simple-greeter/libnotificationarea/libnotificationarea.la \ + $(SIMPLE_GREETER_LIBS) \ + $(GTK_LIBS) \ + $(GCONF_LIBS) \ + $(LIBXKLAVIER_LIBS) \ + $(NULL) + uidir = $(pkgdatadir) ui_DATA = \ gdm-greeter-login-window.ui \ diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-chooser-widget.c gdm-2.30.5/gui/simple-greeter/gdm-chooser-widget.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-chooser-widget.c 2010-09-01 22:01:36.112529002 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-chooser-widget.c 2010-09-01 21:58:43.537095985 +0500 @@ -1334,6 +1334,11 @@ widget->priv->in_use_message = NULL; } + if (widget->priv->update_idle_id > 0) { + g_source_remove (widget->priv->update_idle_id); + widget->priv->update_idle_id = 0; + } + G_OBJECT_CLASS (gdm_chooser_widget_parent_class)->dispose (object); } diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-first-time-login-helper.c gdm-2.30.5/gui/simple-greeter/gdm-first-time-login-helper.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-first-time-login-helper.c 1970-01-01 05:00:00.000000000 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-first-time-login-helper.c 2010-09-02 17:35:30.742634791 +0500 @@ -0,0 +1,331 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (c) 2010, Oracle and/or its affiliates. + * + * 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 + * + * Written by: Suresh Chandrasekharan + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gdm-common.h" +#include "gdm-session-chooser-dialog.h" +#include "gdm-layout-chooser-dialog.h" +#include "gdm-language-chooser-dialog.h" + +typedef enum ptypes {MESSAGE=0, SESSION, LAYOUT, LANGUAGE} ptypes; + +static GtkWidget * +firsttime_login_message_popup (GtkWidget *dialog, + const char *title, + const char *text) +{ + GtkWidget *image; + gchar *display_text; + + dialog = (GtkWidget *) g_object_new (GTK_TYPE_MESSAGE_DIALOG, + "modal", TRUE, + "icon-name", "user-info", + "buttons", GTK_BUTTONS_NONE, + NULL); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + _("_Skip Setup"), GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + display_text = g_strconcat ("", text, "", NULL); + gtk_message_dialog_set_markup ((GtkMessageDialog *)dialog, display_text); + g_free(display_text); + gtk_window_set_title (GTK_WINDOW (dialog), title); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); + image = gtk_image_new_from_icon_name ("user-info", GTK_ICON_SIZE_DIALOG); + gtk_message_dialog_set_image ((GtkMessageDialog *)dialog, image); + gtk_widget_show (image); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + return (GtkWidget *)dialog; + } + +static void +run_dialog(int height, int width, ptypes key, char *set_name, char **name) { + GtkWidget *dialog; + int items = 1; + switch (key) { + case MESSAGE: + dialog = firsttime_login_message_popup(dialog, + _("First Time Login Assistant"), + _("This is the first time you have logged in, please select your preferences:")); + break; + case SESSION: + dialog = gdm_session_chooser_dialog_new(); + items = gdm_session_chooser_dialog_get_number_of_items (GDM_SESSION_CHOOSER_DIALOG (dialog)); + if (items && set_name && set_name[0] != '\0') + gdm_session_chooser_dialog_set_current_session_name (GDM_SESSION_CHOOSER_DIALOG (dialog), set_name); + break; + case LAYOUT: + dialog = gdm_layout_chooser_dialog_new(); + items = gdm_layout_chooser_dialog_get_number_of_items (GDM_LAYOUT_CHOOSER_DIALOG (dialog)); + if (items && set_name && set_name[0] != '\0') + gdm_layout_chooser_dialog_set_current_layout_name (GDM_LAYOUT_CHOOSER_DIALOG (dialog), set_name); + break; + case LANGUAGE: + dialog = gdm_language_chooser_dialog_new(); + items = gdm_language_chooser_dialog_get_number_of_items (GDM_LANGUAGE_CHOOSER_DIALOG (dialog)); + if (items && set_name && set_name[0] != '\0') + gdm_language_chooser_dialog_set_current_language_name (GDM_LANGUAGE_CHOOSER_DIALOG (dialog), set_name); + break; + } + + if (!items) { + *name = strdup (set_name); + gtk_widget_destroy (dialog); + return; + } + + gtk_widget_set_size_request (dialog, height, width); + + gtk_widget_show_all (GTK_WIDGET (dialog)); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { + switch (key) { + case MESSAGE: + /*dummy value*/ + *name = strdup(""); + break; + case SESSION: + *name = gdm_session_chooser_dialog_get_current_session_name (GDM_SESSION_CHOOSER_DIALOG (dialog)); + break; + case LAYOUT: + *name = gdm_layout_chooser_dialog_get_current_layout_name (GDM_LAYOUT_CHOOSER_DIALOG (dialog)); + break; + case LANGUAGE: + *name = gdm_language_chooser_dialog_get_current_language_name (GDM_LANGUAGE_CHOOSER_DIALOG (dialog)); + break; + } + } else { + *name = NULL; + } + gtk_widget_destroy (dialog); +} + +static gboolean +session_settings_save (char *session_name, + char *language_name, + char *layout_name, + char *user_name, + GError **error) +{ + GKeyFile *key_file; + GError *file_error; + gboolean is_saved; + char *filename; + gsize length; + gchar *contents; + + g_return_val_if_fail (user_name != NULL, FALSE); + + if ((filename = gdm_create_temp_gdm_dmrc_filename (user_name)) == NULL) + return FALSE; + + is_saved = FALSE; + key_file = g_key_file_new (); + + file_error = NULL; + g_key_file_load_from_file (key_file, filename, + G_KEY_FILE_KEEP_COMMENTS | + G_KEY_FILE_KEEP_TRANSLATIONS, + NULL); + + if (session_name != NULL) { + g_key_file_set_string (key_file, "Desktop", "Session", + session_name); + } + + if (language_name != NULL) { + g_key_file_set_string (key_file, "Desktop", "Language", + language_name); + } + + if (layout_name != NULL) { + g_key_file_set_string (key_file, "Desktop", "Layout", + layout_name); + } + + contents = g_key_file_to_data (key_file, &length, &file_error); + + if (contents == NULL) { + g_propagate_error (error, file_error); + goto out; + } + + if (!g_file_set_contents (filename, contents, length, &file_error)) { + g_free (contents); + g_propagate_error (error, file_error); + goto out; + } + g_free (contents); + + is_saved = TRUE; +out: + g_key_file_free (key_file); + g_free (filename); + + return is_saved; +} + +static void +set_normal_cursor (void) +{ + GdkWindow *root_window; + GdkCursor *cursor; + + root_window = gdk_screen_get_root_window (gdk_screen_get_default ()); + cursor = gdk_cursor_new (GDK_LEFT_PTR); + gdk_window_set_cursor (root_window, cursor); + gdk_cursor_unref (cursor); +} + +static gboolean +set_uid_gid (char *user_name) +{ + struct passwd *pwent; + + if (user_name == NULL) { + return FALSE; + } + + pwent = getpwnam (user_name); + if (pwent == NULL) { + g_debug (_("User %s doesn't exist"), user_name); + return FALSE; + } + + g_debug ("Changing (uid:gid) for child process to (%d:%d)", + pwent->pw_uid, + pwent->pw_gid); + + if (pwent->pw_uid != 0) { + if (setgid (pwent->pw_gid) < 0) { + g_debug (_("Couldn't set groupid to %d"), + pwent->pw_gid); + return FALSE; + } + + if (initgroups (pwent->pw_name, pwent->pw_gid) < 0) { + g_debug (_("initgroups () failed for %s"), + pwent->pw_name); + return FALSE; + } + + if (setuid (pwent->pw_uid) < 0) { + g_debug (_("Couldn't set userid to %d"), + (int)pwent->pw_uid); + return FALSE; + } + } else { + gid_t groups[1] = { 0 }; + + if (setgid (0) < 0) { + g_debug (_("Couldn't set groupid to %d"), 0); + /* Don't error out, it's not fatal, if it fails we'll + * just still be */ + } + + /* this will get rid of any suplementary groups etc... */ + setgroups (1, groups); + } + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + + GError *error; + char *dialog_feedback = NULL; + char *layout_name = NULL; + char *lang_name = NULL; + char *session_name = NULL; + int ret = -1; + + if (argc != 5) { + g_message ("Usage: %s ", argv[0]); + return (ret); + } + + if (!set_uid_gid (GDM_USERNAME)) { + g_warning (_("Could not set user to %s"), GDM_USERNAME); + } + + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + setlocale (LC_ALL, ""); + + gtk_init (&argc, &argv); + + set_normal_cursor(); + run_dialog(480, 120, MESSAGE, NULL, &dialog_feedback); + if (!dialog_feedback) + return (ret); + + run_dialog(480, 480, SESSION, argv[2], &session_name); + if (!session_name) { + g_free(dialog_feedback); + return (ret); + } + run_dialog(480, 480, LAYOUT, argv[3], &layout_name); + if (!layout_name) { + g_free(dialog_feedback); + g_free(session_name); + return (ret); + } + run_dialog(480, 480, LANGUAGE, argv[4], &lang_name); + if (!lang_name) { + g_free(dialog_feedback); + g_free(session_name); + g_free(layout_name); + return (ret); + } + error = NULL; + if (!session_settings_save (session_name, lang_name, layout_name, argv[1], &error)) { + g_warning (_("could not save session and language settings: %s"), + error->message); + g_error_free (error); + } else { + ret = 0; + } + g_free(dialog_feedback); + g_free(session_name); + g_free(layout_name); + g_free(lang_name); + return (ret); +} diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-language-chooser-dialog.c gdm-2.30.5/gui/simple-greeter/gdm-language-chooser-dialog.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-language-chooser-dialog.c 2010-09-01 22:01:36.588478718 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-language-chooser-dialog.c 2010-09-01 21:58:43.540632912 +0500 @@ -71,6 +71,17 @@ gdm_language_chooser_widget_set_current_language_name (GDM_LANGUAGE_CHOOSER_WIDGET (dialog->priv->chooser_widget), language_name); } +int +gdm_language_chooser_dialog_get_number_of_items (GdmLanguageChooserDialog *dialog) +{ + + dialog->priv = GDM_LANGUAGE_CHOOSER_DIALOG_GET_PRIVATE (dialog); + + if (dialog->priv->chooser_widget == NULL) + dialog->priv->chooser_widget = gdm_language_chooser_widget_new (); + return gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (dialog->priv->chooser_widget)); +} + static void gdm_language_chooser_dialog_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -164,7 +175,7 @@ dialog); gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("_Skip Setup"), GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-language-chooser-dialog.h gdm-2.30.5/gui/simple-greeter/gdm-language-chooser-dialog.h --- gdm-2.30.5.orig/gui/simple-greeter/gdm-language-chooser-dialog.h 2010-09-01 22:01:36.629941936 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-language-chooser-dialog.h 2010-09-01 21:58:43.583884465 +0500 @@ -53,6 +53,8 @@ char * gdm_language_chooser_dialog_get_current_language_name (GdmLanguageChooserDialog *dialog); void gdm_language_chooser_dialog_set_current_language_name (GdmLanguageChooserDialog *dialog, const char *language_name); +int gdm_language_chooser_dialog_get_number_of_items +(GdmLanguageChooserDialog *dialog); G_END_DECLS diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-language-chooser-widget.c gdm-2.30.5/gui/simple-greeter/gdm-language-chooser-widget.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-language-chooser-widget.c 2010-09-01 22:01:36.929885868 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-language-chooser-widget.c 2010-09-01 21:58:43.621315437 +0500 @@ -250,6 +250,10 @@ gdm_chooser_widget_set_separator_position (GDM_CHOOSER_WIDGET (widget), GDM_CHOOSER_WIDGET_POSITION_TOP); + if (!widget->priv->languages_added) { + add_available_languages (widget); + widget->priv->languages_added = TRUE; + } } static void diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-layout-chooser-dialog.c gdm-2.30.5/gui/simple-greeter/gdm-layout-chooser-dialog.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-layout-chooser-dialog.c 2010-09-01 22:01:37.049323804 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-layout-chooser-dialog.c 2010-09-01 21:58:43.623118039 +0500 @@ -71,6 +71,17 @@ gdm_layout_chooser_widget_set_current_layout_name (GDM_LAYOUT_CHOOSER_WIDGET (dialog->priv->chooser_widget), layout_name); } +int +gdm_layout_chooser_dialog_get_number_of_items (GdmLayoutChooserDialog *dialog) +{ + + dialog->priv = GDM_LAYOUT_CHOOSER_DIALOG_GET_PRIVATE (dialog); + + if (dialog->priv->chooser_widget == NULL) + dialog->priv->chooser_widget = gdm_layout_chooser_widget_new (); + return gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (dialog->priv->chooser_widget)); +} + static void gdm_layout_chooser_dialog_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -138,6 +149,7 @@ static void gdm_layout_chooser_dialog_init (GdmLayoutChooserDialog *dialog) { + char *layout_name; dialog->priv = GDM_LAYOUT_CHOOSER_DIALOG_GET_PRIVATE (dialog); @@ -145,8 +157,12 @@ gdm_chooser_widget_set_hide_inactive_items (GDM_CHOOSER_WIDGET (dialog->priv->chooser_widget), FALSE); - gdm_layout_chooser_widget_set_current_layout_name (GDM_LAYOUT_CHOOSER_WIDGET (dialog->priv->chooser_widget), - setlocale (LC_MESSAGES, NULL)); + layout_name = gdm_layout_chooser_widget_get_current_layout_name (GDM_LAYOUT_CHOOSER_WIDGET (dialog->priv->chooser_widget)); + + gdm_layout_chooser_widget_set_current_layout_name (GDM_LAYOUT_CHOOSER_WIDGET (dialog->priv->chooser_widget), layout_name); + + g_free (layout_name); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->priv->chooser_widget); g_signal_connect_swapped (G_OBJECT (dialog->priv->chooser_widget), @@ -154,7 +170,7 @@ dialog); gtk_dialog_add_buttons (GTK_DIALOG (dialog), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("_Skip Setup"), GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-layout-chooser-dialog.h gdm-2.30.5/gui/simple-greeter/gdm-layout-chooser-dialog.h --- gdm-2.30.5.orig/gui/simple-greeter/gdm-layout-chooser-dialog.h 2010-09-01 22:01:37.099934882 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-layout-chooser-dialog.h 2010-09-01 21:58:43.624250116 +0500 @@ -53,6 +53,7 @@ char * gdm_layout_chooser_dialog_get_current_layout_name (GdmLayoutChooserDialog *dialog); void gdm_layout_chooser_dialog_set_current_layout_name (GdmLayoutChooserDialog *dialog, const char *layout_name); +int gdm_layout_chooser_dialog_get_number_of_items (GdmLayoutChooserDialog *dialog); G_END_DECLS diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-layout-chooser-widget.c gdm-2.30.5/gui/simple-greeter/gdm-layout-chooser-widget.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-layout-chooser-widget.c 2010-09-01 22:01:37.170275501 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-layout-chooser-widget.c 2010-09-01 21:58:43.629124850 +0500 @@ -176,6 +176,10 @@ gdm_chooser_widget_set_separator_position (GDM_CHOOSER_WIDGET (widget), GDM_CHOOSER_WIDGET_POSITION_TOP); + if (!widget->priv->layouts_added) { + add_available_layouts (widget); + widget->priv->layouts_added = TRUE; + } } static void diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-dialog.c gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-dialog.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-dialog.c 1970-01-01 05:00:00.000000000 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-dialog.c 2010-09-01 21:58:43.631852835 +0500 @@ -0,0 +1,216 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Matthias Clasen + * Copyright (c) 2010, Oracle and/or its affiliates. + * + * 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. + * + * Written by suresh.chandrasekharan@oracle.com based on + * gdm-layout-chooser-dialog.c + */ + +#include "config.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "gdm-session-chooser-widget.h" +#include "gdm-session-chooser-dialog.h" + +#define GDM_SESSION_CHOOSER_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_CHOOSER_DIALOG, GdmSessionChooserDialogPrivate)) + +struct GdmSessionChooserDialogPrivate +{ + GtkWidget *chooser_widget; +}; + + +static void gdm_session_chooser_dialog_class_init (GdmSessionChooserDialogClass *klass); +static void gdm_session_chooser_dialog_init (GdmSessionChooserDialog *session_chooser_dialog); +static void gdm_session_chooser_dialog_finalize (GObject *object); + +G_DEFINE_TYPE (GdmSessionChooserDialog, gdm_session_chooser_dialog, GTK_TYPE_DIALOG) + +char * +gdm_session_chooser_dialog_get_current_session_name (GdmSessionChooserDialog *dialog) +{ + char *session_name; + + g_return_val_if_fail (GDM_IS_SESSION_CHOOSER_DIALOG (dialog), NULL); + + session_name = gdm_session_chooser_widget_get_current_session_name (GDM_SESSION_CHOOSER_WIDGET (dialog->priv->chooser_widget)); + + return session_name; +} + +void +gdm_session_chooser_dialog_set_current_session_name (GdmSessionChooserDialog *dialog, + const char *session_name) +{ + + g_return_if_fail (GDM_IS_SESSION_CHOOSER_DIALOG (dialog)); + + gdm_session_chooser_widget_set_current_session_name (GDM_SESSION_CHOOSER_WIDGET (dialog->priv->chooser_widget), session_name); +} + +int +gdm_session_chooser_dialog_get_number_of_items (GdmSessionChooserDialog *dialog) +{ + + dialog->priv = GDM_SESSION_CHOOSER_DIALOG_GET_PRIVATE (dialog); + + if (dialog->priv->chooser_widget == NULL) + dialog->priv->chooser_widget = gdm_session_chooser_widget_new (); + return gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (dialog->priv->chooser_widget)); +} + +static void +gdm_session_chooser_dialog_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + int screen_w; + int screen_h; + GtkRequisition child_requisition; + + if (GTK_WIDGET_CLASS (gdm_session_chooser_dialog_parent_class)->size_request) { + GTK_WIDGET_CLASS (gdm_session_chooser_dialog_parent_class)->size_request (widget, requisition); + } + + screen_w = gdk_screen_get_width (gtk_widget_get_screen (widget)); + screen_h = gdk_screen_get_height (gtk_widget_get_screen (widget)); + + gtk_widget_get_child_requisition (GTK_BIN (widget)->child, &child_requisition); + *requisition = child_requisition; + + requisition->width += 2 * GTK_CONTAINER (widget)->border_width; + requisition->height += 2 * GTK_CONTAINER (widget)->border_width; + + requisition->width = MIN (requisition->width, .50 * screen_w); + requisition->height = MIN (requisition->height, .80 * screen_h); +} + +static void +gdm_session_chooser_dialog_realize (GtkWidget *widget) +{ + GdmSessionChooserDialog *chooser_dialog; + + chooser_dialog = GDM_SESSION_CHOOSER_DIALOG (widget); + + gtk_widget_show (chooser_dialog->priv->chooser_widget); + + GTK_WIDGET_CLASS (gdm_session_chooser_dialog_parent_class)->realize (widget); +} + +static void +gdm_session_chooser_dialog_class_init (GdmSessionChooserDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gdm_session_chooser_dialog_finalize; + widget_class->size_request = gdm_session_chooser_dialog_size_request; + widget_class->realize = gdm_session_chooser_dialog_realize; + + g_type_class_add_private (klass, sizeof (GdmSessionChooserDialogPrivate)); +} + +static gboolean +respond (GdmSessionChooserDialog *dialog) +{ + gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + return FALSE; +} + +static void +queue_response (GdmSessionChooserDialog *dialog) +{ + g_idle_add ((GSourceFunc) respond, dialog); +} + +static void +gdm_session_chooser_dialog_init (GdmSessionChooserDialog *dialog) +{ + + char *session_name; + dialog->priv = GDM_SESSION_CHOOSER_DIALOG_GET_PRIVATE (dialog); + + dialog->priv->chooser_widget = gdm_session_chooser_widget_new (); + gdm_chooser_widget_set_hide_inactive_items (GDM_CHOOSER_WIDGET (dialog->priv->chooser_widget), + FALSE); + + session_name = gdm_session_chooser_widget_get_current_session_name (GDM_SESSION_CHOOSER_WIDGET (dialog->priv->chooser_widget)); + + gdm_session_chooser_widget_set_current_session_name (GDM_SESSION_CHOOSER_WIDGET (dialog->priv->chooser_widget), session_name); + + g_free (session_name); + + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->priv->chooser_widget); + + g_signal_connect_swapped (G_OBJECT (dialog->priv->chooser_widget), + "activated", G_CALLBACK (queue_response), + dialog); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + _("_Skip Setup"), GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); + gtk_container_set_border_width (GTK_CONTAINER (dialog->priv->chooser_widget), 5); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ALWAYS); + gtk_window_set_default_size (GTK_WINDOW (dialog), 512, 440); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); +} + +static void +gdm_session_chooser_dialog_finalize (GObject *object) +{ + GdmSessionChooserDialog *session_chooser_dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_SESSION_CHOOSER_DIALOG (object)); + + session_chooser_dialog = GDM_SESSION_CHOOSER_DIALOG (object); + + g_return_if_fail (session_chooser_dialog->priv != NULL); + + G_OBJECT_CLASS (gdm_session_chooser_dialog_parent_class)->finalize (object); +} + +GtkWidget * +gdm_session_chooser_dialog_new (void) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_SESSION_CHOOSER_DIALOG, + "icon-name", "session-properties", + "title", _("Login sessions"), + "border-width", 8, + "modal", TRUE, + NULL); + + return GTK_WIDGET (object); +} diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-dialog.h gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-dialog.h --- gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-dialog.h 1970-01-01 05:00:00.000000000 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-dialog.h 2010-09-01 21:58:43.633807526 +0500 @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Matthias Clasen + * Copyright (c) 2010, Oracle and/or its affiliates. + * + * 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. + * + * Written by suresh.chandrasekharan@oracle.com based on + * gdm-layout-chooser-dialog.h + */ + +#ifndef __GDM_SESSION_CHOOSER_DIALOG_H +#define __GDM_SESSION_CHOOSER_DIALOG_H + +#include +#include + +G_BEGIN_DECLS + +#define GDM_TYPE_SESSION_CHOOSER_DIALOG (gdm_session_chooser_dialog_get_type ()) +#define GDM_SESSION_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SESSION_CHOOSER_DIALOG, GdmSessionChooserDialog)) +#define GDM_SESSION_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SESSION_CHOOSER_DIALOG, GdmSessionChooserDialogClass)) +#define GDM_IS_SESSION_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SESSION_CHOOSER_DIALOG)) +#define GDM_IS_SESSION_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SESSION_CHOOSER_DIALOG)) +#define GDM_SESSION_CHOOSER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SESSION_CHOOSER_DIALOG, GdmSessionChooserDialogClass)) + +typedef struct GdmSessionChooserDialogPrivate GdmSessionChooserDialogPrivate; + +typedef struct +{ + GtkDialog parent; + GdmSessionChooserDialogPrivate *priv; +} GdmSessionChooserDialog; + +typedef struct +{ + GtkDialogClass parent_class; +} GdmSessionChooserDialogClass; + +GType gdm_session_chooser_dialog_get_type (void); + +GtkWidget * gdm_session_chooser_dialog_new (void); + +char * gdm_session_chooser_dialog_get_current_session_name (GdmSessionChooserDialog *dialog); +void gdm_session_chooser_dialog_set_current_session_name (GdmSessionChooserDialog *dialog, + const char *session_name); +int gdm_session_chooser_dialog_get_number_of_items +(GdmSessionChooserDialog *dialog); + +G_END_DECLS + +#endif /* __GDM_SESSION_CHOOSER_DIALOG_H */ diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-widget.c gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-widget.c --- gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-widget.c 1970-01-01 05:00:00.000000000 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-widget.c 2010-09-01 21:58:43.636044856 +0500 @@ -0,0 +1,210 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Matthias Clasen + * Copyright (c) 2010, Oracle and/or its affiliates. + * + * 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. + * + * Written by suresh.chandrasekharan@oracle.com based on + * gdm-layout-chooser-widget.c + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "gdm-session-chooser-widget.h" +#include "gdm-chooser-widget.h" +#include "gdm-sessions.h" + +#define GDM_SESSION_CHOOSER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SESSION_CHOOSER_WIDGET, GdmSessionChooserWidgetPrivate)) + +struct GdmSessionChooserWidgetPrivate +{ + guint sessions_added : 1; +}; + +static void gdm_session_chooser_widget_class_init (GdmSessionChooserWidgetClass *klass); +static void gdm_session_chooser_widget_init (GdmSessionChooserWidget *session_chooser_widget); +static void gdm_session_chooser_widget_finalize (GObject *object); + +G_DEFINE_TYPE (GdmSessionChooserWidget, gdm_session_chooser_widget, GDM_TYPE_CHOOSER_WIDGET) + +enum { + CHOOSER_LIST_TITLE_COLUMN = 0, + CHOOSER_LIST_TRANSLATED_COLUMN, + CHOOSER_LIST_LOCALE_COLUMN +}; + +char * +gdm_session_chooser_widget_get_current_session_name (GdmSessionChooserWidget *widget) +{ + char *id; + + g_return_val_if_fail (GDM_IS_SESSION_CHOOSER_WIDGET (widget), NULL); + + id = gdm_chooser_widget_get_selected_item (GDM_CHOOSER_WIDGET (widget)); + + if (id == NULL) { + id = g_strdup ("gnome"); + } + + return id; +} + +void +gdm_session_chooser_widget_set_current_session_name (GdmSessionChooserWidget *widget, + const char *id) +{ + g_return_if_fail (GDM_IS_SESSION_CHOOSER_WIDGET (widget)); + + if (id == NULL) { + gdm_chooser_widget_set_selected_item (GDM_CHOOSER_WIDGET (widget), + NULL); + return; + } + + gdm_chooser_widget_set_selected_item (GDM_CHOOSER_WIDGET (widget), id); +} + +static void +gdm_session_chooser_widget_add_session (GdmSessionChooserWidget *widget, + const char *name) +{ + char *escaped; + + if (name != NULL) { + escaped = g_markup_escape_text (name, -1); + gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget), + name, + NULL, + escaped, + NULL, + 0, + FALSE, + FALSE, + NULL, + NULL); + g_free (escaped); + } +} + +static void +add_available_sessions (GdmSessionChooserWidget *widget) +{ + char **session_names; + int i; + + session_names = gdm_get_all_sessions (); + + if (session_names == NULL) + return; + + for (i = 0; session_names[i] != NULL; i++) { + gdm_session_chooser_widget_add_session (widget, + session_names[i]); + } + + g_strfreev (session_names); +} + +static void +gdm_session_chooser_widget_dispose (GObject *object) +{ + G_OBJECT_CLASS (gdm_session_chooser_widget_parent_class)->dispose (object); +} + +static void +gdm_session_chooser_widget_realize (GtkWidget *widget) +{ + GdmSessionChooserWidget *chooser; + + chooser = GDM_SESSION_CHOOSER_WIDGET (widget); + + GTK_WIDGET_CLASS (gdm_session_chooser_widget_parent_class)->realize (widget); + + if (!chooser->priv->sessions_added) { + add_available_sessions (chooser); + chooser->priv->sessions_added = TRUE; + } +} + +static void +gdm_session_chooser_widget_class_init (GdmSessionChooserWidgetClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->dispose = gdm_session_chooser_widget_dispose; + object_class->finalize = gdm_session_chooser_widget_finalize; + widget_class->realize = gdm_session_chooser_widget_realize; + + g_type_class_add_private (klass, sizeof (GdmSessionChooserWidgetPrivate)); +} + +static void +gdm_session_chooser_widget_init (GdmSessionChooserWidget *widget) +{ + widget->priv = GDM_SESSION_CHOOSER_WIDGET_GET_PRIVATE (widget); + + gdm_chooser_widget_set_separator_position (GDM_CHOOSER_WIDGET (widget), + GDM_CHOOSER_WIDGET_POSITION_TOP); + if (!widget->priv->sessions_added) { + add_available_sessions (widget); + widget->priv->sessions_added = TRUE; + } +} + +static void +gdm_session_chooser_widget_finalize (GObject *object) +{ + GdmSessionChooserWidget *session_chooser_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_SESSION_CHOOSER_WIDGET (object)); + + session_chooser_widget = GDM_SESSION_CHOOSER_WIDGET (object); + + g_return_if_fail (session_chooser_widget->priv != NULL); + + G_OBJECT_CLASS (gdm_session_chooser_widget_parent_class)->finalize (object); +} + +GtkWidget * +gdm_session_chooser_widget_new (void) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_SESSION_CHOOSER_WIDGET, + "inactive-text", _("_Session:"), + "active-text", _("_Session:"), + NULL); + + return GTK_WIDGET (object); +} diff -ruN gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-widget.h gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-widget.h --- gdm-2.30.5.orig/gui/simple-greeter/gdm-session-chooser-widget.h 1970-01-01 05:00:00.000000000 +0500 +++ gdm-2.30.5/gui/simple-greeter/gdm-session-chooser-widget.h 2010-09-01 21:58:43.636899984 +0500 @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Matthias Clasen + * Copyright (c) 2010, Oracle and/or its affiliates. + * + * 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. + * + * Written by suresh.chandrasekharan@oracle.com based on + * gdm-layout-chooser-widget.h + */ + +#ifndef __GDM_SESSION_CHOOSER_WIDGET_H +#define __GDM_SESSION_CHOOSER_WIDGET_H + +#include +#include "gdm-chooser-widget.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_SESSION_CHOOSER_WIDGET (gdm_session_chooser_widget_get_type ()) +#define GDM_SESSION_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SESSION_CHOOSER_WIDGET, GdmSessionChooserWidget)) +#define GDM_SESSION_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SESSION_CHOOSER_WIDGET, GdmSessionChooserWidgetClass)) +#define GDM_IS_SESSION_CHOOSER_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SESSION_CHOOSER_WIDGET)) +#define GDM_IS_SESSION_CHOOSER_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SESSION_CHOOSER_WIDGET)) +#define GDM_SESSION_CHOOSER_WIDGET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SESSION_CHOOSER_WIDGET, GdmSessionChooserWidgetClass)) + +typedef struct GdmSessionChooserWidgetPrivate GdmSessionChooserWidgetPrivate; + +typedef struct +{ + GdmChooserWidget parent; + GdmSessionChooserWidgetPrivate *priv; +} GdmSessionChooserWidget; + +typedef struct +{ + GdmChooserWidgetClass parent_class; +} GdmSessionChooserWidgetClass; + +GType gdm_session_chooser_widget_get_type (void); +GtkWidget * gdm_session_chooser_widget_new (void); + +char * gdm_session_chooser_widget_get_current_session_name (GdmSessionChooserWidget *widget); +void gdm_session_chooser_widget_set_current_session_name (GdmSessionChooserWidget *widget, + const char *name); + +G_END_DECLS + +#endif /* __GDM_SESSION_CHOOSER_WIDGET_H */