8
#include <gdk/gdkkeysyms.h>
9
#include <dbus/dbus-glib.h>
10
#include <glib/gi18n.h>
12
#include "gdm-user-manager.h"
13
#include "gdm-sessions.h"
15
#define MAX_USERS_IN_COMBO_BOX 20
18
static GtkBuilder *ui;
19
static GtkWidget *dialog, *unlock_button, *option_vbox;
20
static GtkWidget *user_combo, *user_entry, *delay_spin;
21
static GtkWidget *session_combo;
22
static GtkWidget *auto_login_radio, *login_delay_box, *login_delay_check, *sound_enable_check, *face_browser_enable_check;
24
/* Timer to delay application of configuration */
25
static guint apply_timeout = 0;
27
/* Flag to show when information is user_login_loaded */
28
static gboolean user_login_loaded = FALSE;
29
static gboolean session_loaded = FALSE;
31
/* Flag to show when information is loaded */
32
static gboolean locked = TRUE;
34
/* True if the user selection method is a combo box, False if an entry */
35
static gboolean user_list_is_combo = TRUE;
37
/* User information */
38
static GdmUserManager *user_manager;
40
/* Proxy to GDM settings */
41
static DBusGProxy *proxy = NULL;
50
if (!dbus_g_proxy_call (proxy, "GetSoundEnabled", &error,
52
G_TYPE_BOOLEAN, &value, G_TYPE_INVALID)) {
53
g_warning ("Error calling GetSoundEnabled(): %s", error->message);
62
set_sound_enabled (gboolean enabled)
66
dbus_g_proxy_call (proxy, "SetSoundEnabled", &error,
67
G_TYPE_BOOLEAN, enabled, G_TYPE_INVALID,
70
g_warning ("Error calling SetSoundEnabled(%s): %s", enabled ? "TRUE" : "FALSE", error->message);
79
get_face_browser_enabled ()
84
if (!dbus_g_proxy_call (proxy, "GetFaceBrowserEnabled", &error,
86
G_TYPE_BOOLEAN, &value, G_TYPE_INVALID)) {
87
g_warning ("Error calling GetFaceBrowserEnabled(): %s", error->message);
96
set_face_browser_enabled (gboolean enabled)
100
dbus_g_proxy_call (proxy, "SetFaceBrowserEnabled", &error,
101
G_TYPE_BOOLEAN, enabled, G_TYPE_INVALID,
104
g_warning ("Error calling SetFaceBrowserEnabled(%s): %s", enabled ? "TRUE" : "FALSE", error->message);
113
get_value (const gchar *key, gchar *def)
116
GError *error = NULL;
118
if (!dbus_g_proxy_call (proxy, "GetValue", &error,
119
G_TYPE_STRING, key, G_TYPE_INVALID,
120
G_TYPE_STRING, &value, G_TYPE_INVALID)) {
121
g_warning ("Error calling GetValue('%s'): %s", key, error->message);
130
set_value (const gchar *key, const gchar *value)
132
GError *error = NULL;
134
dbus_g_proxy_call (proxy, "SetValue", &error,
136
G_TYPE_STRING, value, G_TYPE_INVALID, G_TYPE_INVALID);
138
g_warning ("Error calling SetValue('%s', '%s'): %s", key, value, error->message);
147
get_boolean_value (const gchar *key, gboolean def)
152
value = get_value (key, NULL);
155
result = strcmp (value, "true") == 0;
162
get_integer_value (const gchar *key, gint def)
168
value = get_value (key, NULL);
169
if (!value || value[0] == '\0')
172
result = strtol (value, &end, 10);
184
set_boolean_value (const gchar *key, gboolean value)
186
return set_value (key, value ? "true" : "false");
191
set_integer_value (const gchar *key, gint value)
193
char value_string[1024];
194
snprintf(value_string, 1024, "%d", value);
195
return set_value (key, value_string);
206
gboolean auto_login = FALSE, timed_login = FALSE, error = FALSE;
207
gchar *default_session = NULL;
209
if (apply_timeout != 0) {
210
g_source_remove (apply_timeout);
214
if (user_list_is_combo) {
215
model = gtk_combo_box_get_model (GTK_COMBO_BOX (user_combo));
216
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (user_combo), &iter))
217
gtk_tree_model_get (model, &iter, 1, &user, -1);
220
user = g_strdup (gtk_entry_get_text (GTK_ENTRY (user_entry)));
222
model = gtk_combo_box_get_model (GTK_COMBO_BOX (session_combo));
223
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (session_combo), &iter))
224
gtk_tree_model_get (model, &iter, 1, &default_session, -1);
226
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (auto_login_radio))) {
227
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (login_delay_check)))
233
delay = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (delay_spin));
235
g_debug ("set user='%s', auto=%s, timed=%s, delay=%d, default_session=%s",
237
auto_login ? "True" : "False",
238
timed_login ? "True" : "False", delay,
241
if (!set_boolean_value ("daemon/TimedLoginEnable", timed_login) ||
242
!set_boolean_value ("daemon/AutomaticLoginEnable", auto_login) ||
243
!set_value ("daemon/TimedLogin", user) ||
244
!set_value ("daemon/AutomaticLogin", user) ||
245
!set_integer_value ("daemon/TimedLoginDelay", delay) ||
246
!set_value ("daemon/DefaultSession", default_session))
256
gdm_capplet_response_cb (GtkWidget *widget, gint response_id)
258
if (response_id != 1)
264
unlock_response_cb (DBusGProxy *proxy,
265
DBusGProxyCall *call_id,
268
gboolean is_unlocked;
269
GError *error = NULL;
271
dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_BOOLEAN, &is_unlocked, G_TYPE_INVALID);
273
g_warning ("Failed to unlock: %s", error->message);
274
g_error_free (error);
282
gtk_widget_set_sensitive (unlock_button, FALSE);
283
gtk_widget_set_sensitive (option_vbox, user_login_loaded && !locked);
289
unlock_button_clicked_cb (GtkWidget *widget)
291
dbus_g_proxy_begin_call (proxy, "Unlock", unlock_response_cb, NULL, NULL, G_TYPE_INVALID);
297
login_delay_check_toggled_cb (GtkWidget *widget)
299
gtk_widget_set_sensitive (delay_spin,
300
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (login_delay_check)));
302
if (session_loaded && user_login_loaded)
309
sound_enable_check_toggled_cb (GtkWidget *widget)
311
set_sound_enabled (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
317
face_browser_enable_check_toggled_cb (GtkWidget *widget)
319
set_face_browser_enabled (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
333
apply_config_cb (GtkWidget *widget)
335
if (session_loaded && user_login_loaded) {
336
if (apply_timeout != 0)
337
g_source_remove (apply_timeout);
338
apply_timeout = g_timeout_add (200, (GSourceFunc)delayed_apply_cb, NULL);
348
if (get_boolean_value ("daemon/TimedLoginEnable", FALSE))
349
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (login_delay_check), TRUE);
351
delay = get_integer_value ("daemon/TimedLoginDelay", 30);
353
g_debug ("init delay=%d", delay);
355
gtk_spin_button_set_value (GTK_SPIN_BUTTON (delay_spin), delay);
361
automatic_login_toggle_cb (GtkWidget *automatic_login_toggle)
363
gboolean automatic_login;
365
automatic_login = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (automatic_login_toggle));
366
gtk_widget_set_sensitive (login_delay_box, automatic_login);
367
gtk_widget_set_sensitive (user_combo, automatic_login);
368
gtk_widget_set_sensitive (user_entry, automatic_login);
369
gtk_widget_set_sensitive (face_browser_enable_check, !automatic_login);
371
if (session_loaded && user_login_loaded)
378
default_user_combo_box_changed_cb (void)
380
if (session_loaded && user_login_loaded) {
381
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_login_radio), TRUE);
388
default_session_combo_box_changed_cb (void)
390
if (session_loaded && user_login_loaded)
396
init_default_user (void)
400
gboolean auto_login, timed_login, active;
403
auto_login = get_boolean_value ("daemon/AutomaticLoginEnable", FALSE);
404
timed_login = get_boolean_value ("daemon/TimedLoginEnable", FALSE);
407
user = get_value ("daemon/AutomaticLogin", NULL);
409
user = get_value ("daemon/TimedLogin", NULL);
411
g_debug ("init user='%s' auto=%s", user, auto_login || timed_login ? "True" : "False");
413
if (auto_login || timed_login)
414
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (auto_login_radio), TRUE);
416
if (!user_list_is_combo) {
418
gtk_entry_set_text (GTK_ENTRY (user_entry), user);
421
model = gtk_combo_box_get_model (GTK_COMBO_BOX (user_combo));
422
active = gtk_tree_model_get_iter_first (model, &iter);
424
/* If no user then use first available */
427
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (user_combo), &iter);
430
while (user != NULL && active) {
434
gtk_tree_model_get (model, &iter, 1, &u, -1);
435
matched = strcmp (user, u) == 0;
438
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (user_combo), &iter);
442
active = gtk_tree_model_iter_next (model, &iter);
452
init_default_session (void)
457
gchar *default_session = NULL;
459
default_session = get_value ("daemon/DefaultSession", NULL);
460
g_debug ("Init default session found:'%s'", default_session);
462
model = gtk_combo_box_get_model (GTK_COMBO_BOX (session_combo));
463
active = gtk_tree_model_get_iter_first (model, &iter);
465
/* If no default session then use gnome one */
466
if (default_session == NULL || strlen(default_session) == 0)
467
default_session = g_strdup("gnome");
473
gtk_tree_model_get (model, &iter, 1, &u, -1);
474
matched = strcmp (default_session, u) == 0;
477
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (session_combo), &iter);
481
active = gtk_tree_model_iter_next (model, &iter);
483
session_loaded = TRUE;
485
g_free (default_session);
489
static void add_user (GdmUser *user)
494
const gchar *home_user_dir;
495
gchar *encryption_path;
496
gchar *encryption_content;
497
GFile *encryption_file;
498
GString *encryption_mount;
499
gboolean using_encryption = FALSE;
501
/* don't enable autologin for user having encrypted home dir
502
there are some corner case if gdmsetup isn't run as root and another user
503
than the current one is using encrypted dir: you can't check for them if
504
they access to it. The solution is the server to refuse the change then
505
(too late in the cycle for such changes). */
506
home_user_dir = gdm_user_get_home_directory (user);
507
encryption_path = g_build_filename (home_user_dir, ".ecryptfs", "Private.mnt", NULL);
508
encryption_file = g_file_new_for_path (encryption_path);
509
if (g_file_load_contents (encryption_file, NULL, &encryption_content, NULL, NULL, NULL)) {
510
if (g_str_has_suffix (encryption_content, "\n"))
511
encryption_content[strlen(encryption_content)-1] = '\0';
512
encryption_mount = g_string_new(encryption_content);
513
if (strcmp (encryption_mount->str, home_user_dir) == 0)
514
using_encryption = TRUE;
515
g_string_free (encryption_mount, TRUE);
518
g_object_unref (encryption_file);
519
g_free (encryption_path);
521
if (using_encryption) {
522
g_debug ("%s is using an encrypted home, not listing him for autologin", gdm_user_get_real_name (user));
526
model = GTK_LIST_STORE (gtk_builder_get_object (ui, "login_user_model"));
527
gtk_list_store_append (model, &iter);
528
label = g_string_new("");
529
g_string_printf (label, "%s (%s)", gdm_user_get_real_name (user), gdm_user_get_user_name (user));
530
gtk_list_store_set (model, &iter,
532
1, gdm_user_get_user_name (user),
534
g_string_free (label, TRUE);
538
static void add_session (gchar *session_id, gchar *name, gchar *comment)
544
model = GTK_LIST_STORE (gtk_builder_get_object (ui, "session_model"));
545
gtk_list_store_append (model, &iter);
546
label = g_string_new("");
547
g_string_printf (label, "%s", name);
548
gtk_list_store_set (model, &iter,
552
g_string_free (label, TRUE);
557
users_loaded_cb(GdmUserManager *manager)
559
GSList *users, *item;
561
users = gdm_user_manager_list_users (user_manager);
563
if (g_slist_length (users) > MAX_USERS_IN_COMBO_BOX) {
564
user_list_is_combo = FALSE;
565
gtk_widget_hide (user_combo);
566
gtk_widget_show (user_entry);
569
for (item = users; item; item = item->next)
570
add_user ((GdmUser *) item->data);
573
init_default_user ();
575
user_login_loaded = TRUE;
576
gtk_widget_set_sensitive (option_vbox, user_login_loaded && !locked);
581
user_added_cb (GdmUserManager *manager, GdmUser *user)
583
if (session_loaded && user_login_loaded)
589
load_sessions_cb(void)
594
session_ids = gdm_get_all_sessions ();
596
for (i = 0; session_ids[i] != NULL; i++) {
599
if (!gdm_get_details_for_session (session_ids[i],
603
add_session (session_ids[i], name, comment);
607
g_strfreev (session_ids);
609
init_default_session();
614
split_text (const gchar *text, const gchar *prefix_label_name, const gchar *suffix_label_name)
617
GtkWidget *prefix_label, *suffix_label;
619
prefix_label = GTK_WIDGET (gtk_builder_get_object (ui, prefix_label_name));
620
suffix_label = GTK_WIDGET (gtk_builder_get_object (ui, suffix_label_name));
622
tokens = g_strsplit (text, "%s", 2);
623
if (tokens[0] != NULL && tokens[1] != NULL) {
624
if (tokens[0][0] != '\0')
625
gtk_label_set_text (GTK_LABEL (prefix_label), g_strstrip (tokens[0]));
627
gtk_widget_hide (prefix_label);
628
if (tokens[1][0] != '\0')
629
gtk_label_set_text (GTK_LABEL (suffix_label), g_strstrip (tokens[1]));
631
gtk_widget_hide (suffix_label);
637
int main (int argc, char **argv)
639
GtkCellRenderer *renderer;
640
DBusGConnection *connection;
641
GError *error = NULL;
643
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
644
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
645
textdomain (GETTEXT_PACKAGE);
647
gtk_init (&argc, &argv);
649
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
651
g_warning ("Failed to get system bus: %s", error->message);
654
proxy = dbus_g_proxy_new_for_name (connection,
655
"org.gnome.DisplayManager",
656
"/org/gnome/DisplayManager/Settings",
657
"org.gnome.DisplayManager.Settings");
659
ui = gtk_builder_new ();
660
gtk_builder_add_from_file (ui, UIDIR "/gdmsetup.ui", &error);
662
g_warning ("Failed to load UI: %s", error->message);
665
dialog = GTK_WIDGET (gtk_builder_get_object (ui, "gdm_capplet"));
666
unlock_button = GTK_WIDGET (gtk_builder_get_object (ui, "unlock_button"));
667
option_vbox = GTK_WIDGET (gtk_builder_get_object (ui, "gdm_capplet_vbox"));
668
user_combo = GTK_WIDGET (gtk_builder_get_object (ui, "default_user_combo_box"));
669
session_combo = GTK_WIDGET (gtk_builder_get_object (ui, "default_session_combo_box"));
670
user_entry = GTK_WIDGET (gtk_builder_get_object (ui, "default_user_entry"));
671
delay_spin = GTK_WIDGET (gtk_builder_get_object (ui, "login_delay_spin"));
672
auto_login_radio = GTK_WIDGET (gtk_builder_get_object (ui, "automatic_login_radio"));
673
login_delay_box = GTK_WIDGET (gtk_builder_get_object (ui, "login_delay_box"));
674
login_delay_check = GTK_WIDGET (gtk_builder_get_object (ui, "login_delay_check"));
675
sound_enable_check = GTK_WIDGET (gtk_builder_get_object (ui, "sound_enable_check"));
676
face_browser_enable_check = GTK_WIDGET (gtk_builder_get_object (ui, "face_browser_enable_check"));
678
if (g_file_test ("/usr/share/gdm/autostart/LoginWindow/libcanberra-ready-sound.desktop", G_FILE_TEST_EXISTS))
679
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sound_enable_check), get_sound_enabled ());
681
gtk_widget_hide (GTK_WIDGET (sound_enable_check));
683
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (face_browser_enable_check), get_face_browser_enabled ());
685
gtk_builder_connect_signals (ui, NULL);
687
/* Translators: Label for choosing which user to log in as. '%s' is replaced with an input field. */
688
split_text (_("Log in as %s automatically"), "user_prefix_label", "user_suffix_label");
689
/* Translators: Label for choosing the login delay. '%s' is replaced with an input field. */
690
split_text (_("Allow %s seconds for anyone else to log in first"), "delay_prefix_label", "delay_suffix_label");
691
/* Translators: Label for choosing the default session. '%s' is replaced with an input field. */
692
split_text (_("Select %s as default session"), "session_prefix_label", "session_suffix_label");
697
renderer = gtk_cell_renderer_text_new ();
698
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (user_combo), renderer, TRUE);
699
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (user_combo), renderer, "text", 0);
701
renderer = gtk_cell_renderer_text_new ();
702
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (session_combo), renderer, TRUE);
703
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (session_combo), renderer, "text", 0);
705
user_manager = gdm_user_manager_ref_default ();
706
g_signal_connect (user_manager, "users-loaded", G_CALLBACK (users_loaded_cb), NULL);
707
g_signal_connect (user_manager, "user-added", G_CALLBACK (user_added_cb), NULL);
709
gtk_widget_hide (user_entry);
711
gtk_widget_set_sensitive (option_vbox, FALSE);
712
gtk_widget_show (dialog);