~ubuntu-branches/ubuntu/utopic/lightdm-gtk-greeter/utopic-proposed

« back to all changes in this revision

Viewing changes to src/lightdm-gtk-greeter.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2013-02-10 20:18:44 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20130210201844-v33v5j6i76d1ezdt
Tags: 1.5.1-0ubuntu1
* New upstream release.
* debian/rules: disable silent rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 * license.
10
10
 */
11
11
 
 
12
#ifdef HAVE_CONFIG_H
 
13
#include <config.h>
 
14
#endif
 
15
 
 
16
#ifdef HAVE_STDLIB_H
12
17
#include <stdlib.h>
 
18
#endif
 
19
 
13
20
#include <locale.h>
14
21
#include <gtk/gtk.h>
15
22
#include <glib/gi18n.h>
17
24
#include <gdk-pixbuf/gdk-pixbuf.h>
18
25
#include <gdk/gdkx.h>
19
26
 
20
 
#include "lightdm.h"
 
27
#ifdef HAVE_LIBINDICATOR
 
28
#include <libindicator/indicator-object.h>
 
29
#endif
 
30
 
 
31
#include <lightdm.h>
 
32
 
 
33
#include <src/lightdm-gtk-greeter-ui.h>
21
34
 
22
35
static LightDMGreeter *greeter;
23
36
static GKeyFile *state;
26
39
static GtkButton *login_button, *cancel_button;
27
40
static GtkLabel *message_label, *prompt_label;
28
41
static GtkWidget *login_box, *prompt_box;
 
42
static GtkImage *user_avatar;
29
43
static GtkEntry *prompt_entry;
30
44
static GtkComboBox *user_combo;
31
45
static GtkComboBox *session_combo;
32
46
static GtkComboBox *language_combo;
33
47
static gchar *default_font_name, *default_theme_name, *default_icon_theme_name;
34
48
static GdkPixbuf *default_background_pixbuf = NULL;
 
49
#if GTK_CHECK_VERSION (3, 0, 0)
35
50
static GdkRGBA *default_background_color = NULL;
 
51
#else
 
52
static GdkColor *default_background_color = NULL;
 
53
#endif
36
54
static gboolean cancelling = FALSE, prompted = FALSE;
37
55
 
 
56
 
 
57
#ifdef HAVE_LIBINDICATOR
 
58
static gboolean
 
59
entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
 
60
{
 
61
    IndicatorObject      *io;
 
62
    IndicatorObjectEntry *entry;
 
63
 
 
64
    g_return_val_if_fail (GTK_IS_WIDGET (menuitem), FALSE);
 
65
 
 
66
    io = g_object_get_data (G_OBJECT (menuitem), "indicator-custom-object-data");
 
67
    entry = g_object_get_data (G_OBJECT (menuitem), "indicator-custom-entry-data");
 
68
 
 
69
    g_return_val_if_fail (INDICATOR_IS_OBJECT (io), FALSE);
 
70
 
 
71
    g_signal_emit_by_name (io, "scroll", 1, event->direction);
 
72
    g_signal_emit_by_name (io, "scroll-entry", entry, 1, event->direction);
 
73
 
 
74
    return FALSE;
 
75
}
 
76
 
 
77
static void
 
78
entry_activated (GtkWidget *widget, gpointer user_data)
 
79
{
 
80
    IndicatorObject      *io;
 
81
    IndicatorObjectEntry *entry;
 
82
 
 
83
    g_return_if_fail (GTK_IS_WIDGET (widget));
 
84
 
 
85
    io = g_object_get_data (G_OBJECT (widget), "indicator-custom-object-data");
 
86
    entry = g_object_get_data (G_OBJECT (widget), "indicator-custom-entry-data");
 
87
 
 
88
    g_return_if_fail (INDICATOR_IS_OBJECT (io));
 
89
 
 
90
    return indicator_object_entry_activate (io, entry, gtk_get_current_event_time ());
 
91
}
 
92
 
 
93
static GtkWidget*
 
94
create_menuitem (IndicatorObject *io, IndicatorObjectEntry *entry, GtkWidget *menubar)
 
95
{
 
96
    GtkWidget *box, *menuitem;
 
97
 
 
98
#if GTK_CHECK_VERSION (3, 0, 0)
 
99
    box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
 
100
#else
 
101
    box = gtk_hbox_new (FALSE, 0);
 
102
#endif
 
103
    menuitem = gtk_menu_item_new ();
 
104
 
 
105
    gtk_widget_add_events(GTK_WIDGET(menuitem), GDK_SCROLL_MASK);
 
106
 
 
107
    g_object_set_data (G_OBJECT (menuitem), "indicator-custom-box-data", box);
 
108
    g_object_set_data (G_OBJECT (menuitem), "indicator-custom-object-data", io);
 
109
    g_object_set_data (G_OBJECT (menuitem), "indicator-custom-entry-data", entry);
 
110
 
 
111
    g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (entry_activated), NULL);
 
112
    g_signal_connect (G_OBJECT (menuitem), "scroll-event", G_CALLBACK (entry_scrolled), NULL);
 
113
 
 
114
    if (entry->image)
 
115
        gtk_box_pack_start (GTK_BOX(box), GTK_WIDGET(entry->image), FALSE, FALSE, 1);
 
116
 
 
117
    if (entry->label)
 
118
        gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(entry->label), FALSE, FALSE, 1);
 
119
 
 
120
    if (entry->menu)
 
121
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), GTK_WIDGET (entry->menu));
 
122
 
 
123
    gtk_container_add (GTK_CONTAINER (menuitem), box);
 
124
    gtk_widget_show (box);
 
125
    gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
 
126
 
 
127
    return menuitem;
 
128
}
 
129
 
 
130
static void
 
131
entry_added (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
 
132
{
 
133
    GHashTable *menuitem_lookup;
 
134
    GtkWidget  *menuitem;
 
135
 
 
136
    /* if the menuitem doesn't already exist, create it now */
 
137
    menuitem_lookup = g_object_get_data (G_OBJECT (io), "indicator-custom-menuitems-data");
 
138
    g_return_if_fail (menuitem_lookup);
 
139
    menuitem = g_hash_table_lookup (menuitem_lookup, entry);
 
140
    if (!GTK_IS_WIDGET (menuitem))
 
141
    {
 
142
        menuitem = create_menuitem (io, entry, GTK_WIDGET (user_data));
 
143
        g_hash_table_insert (menuitem_lookup, entry, menuitem);
 
144
    }
 
145
 
 
146
    gtk_widget_show (menuitem);
 
147
}
 
148
 
 
149
static void
 
150
entry_removed_cb (GtkWidget *widget, gpointer userdata)
 
151
{
 
152
    IndicatorObject *io;
 
153
    GHashTable      *menuitem_lookup;
 
154
    GtkWidget       *menuitem;
 
155
    gpointer         entry;
 
156
 
 
157
    io = g_object_get_data (G_OBJECT (widget), "indicator-custom-object-data");
 
158
    if (!INDICATOR_IS_OBJECT (io))
 
159
        return;
 
160
 
 
161
    entry = g_object_get_data (G_OBJECT (widget), "indicator-custom-entry-data");
 
162
    if (entry != userdata)
 
163
        return;
 
164
 
 
165
    menuitem_lookup = g_object_get_data (G_OBJECT (io), "indicator-custom-menuitems-data");
 
166
    g_return_if_fail (menuitem_lookup);
 
167
    menuitem = g_hash_table_lookup (menuitem_lookup, entry);
 
168
    if (GTK_IS_WIDGET (menuitem))
 
169
        gtk_widget_hide (menuitem);
 
170
 
 
171
    gtk_widget_destroy (widget);
 
172
}
 
173
 
 
174
static void
 
175
entry_removed (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data)
 
176
{
 
177
    gtk_container_foreach (GTK_CONTAINER (user_data), entry_removed_cb, entry);
 
178
}
 
179
 
 
180
static void
 
181
menu_show (IndicatorObject *io, IndicatorObjectEntry *entry, guint32 timestamp, gpointer user_data)
 
182
{
 
183
    IndicatorObjectEntry *entrydata;
 
184
    GtkWidget            *menuitem;
 
185
    GList                *entries, *lp;
 
186
 
 
187
    menuitem = GTK_WIDGET (user_data);
 
188
 
 
189
    if (!entry)
 
190
    {
 
191
        /* Close any open menus instead of opening one */
 
192
        entries = indicator_object_get_entries (io);
 
193
        for (lp = entries; lp; lp = g_list_next (entry))
 
194
        {
 
195
            entrydata = lp->data;
 
196
            gtk_menu_popdown (entrydata->menu);
 
197
        }
 
198
        g_list_free (entries);
 
199
 
 
200
        /* And tell the menuitem to exit activation mode too */
 
201
        gtk_menu_shell_cancel (GTK_MENU_SHELL (menuitem));
 
202
    }
 
203
}
 
204
 
 
205
static gboolean
 
206
load_module (const gchar *name, GtkWidget *menubar)
 
207
{
 
208
    IndicatorObject *io;
 
209
    GList           *entries, *lp;
 
210
    gchar           *path;
 
211
 
 
212
    g_return_val_if_fail (name, FALSE);
 
213
 
 
214
    if (!g_str_has_suffix (name, G_MODULE_SUFFIX))
 
215
        return FALSE;
 
216
 
 
217
    path = g_build_filename (INDICATOR_DIR, name, NULL);
 
218
    io = indicator_object_new_from_file (path);
 
219
    g_free (path);
 
220
 
 
221
    /* used to store/fetch menu entries */
 
222
    g_object_set_data_full (G_OBJECT (io), "indicator-custom-menuitems-data",
 
223
                            g_hash_table_new (g_direct_hash, g_direct_equal),
 
224
                            (GDestroyNotify) g_hash_table_destroy);
 
225
 
 
226
    g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
 
227
                      G_CALLBACK (entry_added), menubar);
 
228
    g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
 
229
                      G_CALLBACK (entry_removed), menubar);
 
230
    g_signal_connect (G_OBJECT (io), INDICATOR_OBJECT_SIGNAL_MENU_SHOW,
 
231
                      G_CALLBACK (menu_show), menubar);
 
232
 
 
233
    entries = indicator_object_get_entries (io);
 
234
    for (lp = entries; lp; lp = g_list_next (lp))
 
235
        entry_added (io, lp->data, menubar);
 
236
 
 
237
    g_list_free (entries);
 
238
 
 
239
    return TRUE;
 
240
}
 
241
#endif
 
242
 
38
243
static gchar *
39
244
get_session ()
40
245
{
195
400
}
196
401
 
197
402
static void
 
403
set_user_image (const gchar *username)
 
404
{
 
405
    const gchar *path;
 
406
    LightDMUser *user;
 
407
    GdkPixbuf *image = NULL;
 
408
    GError *error = NULL;
 
409
 
 
410
    user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
 
411
    if (user)
 
412
    {
 
413
        path = lightdm_user_get_image (user);
 
414
        if (path)
 
415
        {
 
416
            image = gdk_pixbuf_new_from_file_at_scale (path, 64, 64, FALSE, &error);
 
417
            if (image)
 
418
            {
 
419
                gtk_image_set_from_pixbuf (GTK_IMAGE (user_avatar), image);
 
420
                g_object_unref (image);
 
421
                return;
 
422
            }
 
423
            else
 
424
            {
 
425
                g_warning ("Failed to load user image: %s", error->message);
 
426
                g_clear_error (&error);
 
427
            }
 
428
        }
 
429
    }
 
430
    /* otherwise, show the default avatar instead */
 
431
    gtk_image_set_from_icon_name (GTK_IMAGE (user_avatar), "avatar-default", GTK_ICON_SIZE_DIALOG);
 
432
}
 
433
 
 
434
static void
198
435
start_authentication (const gchar *username)
199
436
{
200
437
    gchar *data;
345
582
 
346
583
        set_login_button_label (user);
347
584
        set_user_background (user);
 
585
        set_user_image (user);
348
586
        start_authentication (user);
349
587
        g_free (user);
350
588
    }
528
766
    GtkTreeModel *model;
529
767
 
530
768
    model = gtk_combo_box_get_model (user_combo);
531
 
  
 
769
 
532
770
    if (!gtk_tree_model_get_iter_first (model, iter))
533
771
        return FALSE;
534
772
    do
616
854
{
617
855
    if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
618
856
    {
619
 
        g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrastInverse", NULL);
620
 
        g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", "HighContrastInverse", NULL);
 
857
        g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrast", NULL);
 
858
        g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", "HighContrast", NULL);
621
859
    }
622
860
    else
623
861
    {
700
938
                gtk_combo_box_set_active_iter (user_combo, &iter);
701
939
                set_login_button_label (selected_user);
702
940
                set_user_background (selected_user);
 
941
                set_user_image (selected_user);
703
942
                start_authentication (selected_user);
704
943
                break;
705
944
            }
780
1019
            {
781
1020
                GdkPixbuf *p = gdk_pixbuf_scale_simple (bg, monitor_geometry.width,
782
1021
                                                        monitor_geometry.height, GDK_INTERP_BILINEAR);
 
1022
                if (!gdk_pixbuf_get_has_alpha (p))
 
1023
                    p = gdk_pixbuf_add_alpha (p, FALSE, 255, 255, 255);
783
1024
                gdk_cairo_set_source_pixbuf (c, p, monitor_geometry.x, monitor_geometry.y);
784
1025
                g_object_unref (p);
785
1026
            }
786
1027
            else
 
1028
#if GTK_CHECK_VERSION (3, 0, 0)
787
1029
                gdk_cairo_set_source_rgba (c, default_background_color);
 
1030
#else
 
1031
                gdk_cairo_set_source_color (c, default_background_color);
 
1032
#endif
788
1033
            cairo_paint (c);
789
1034
        }
790
1035
 
808
1053
    GtkCellRenderer *renderer;
809
1054
    GtkWidget *menuitem, *hbox, *image;
810
1055
    gchar *value, *state_dir;
 
1056
#if GTK_CHECK_VERSION (3, 0, 0)
811
1057
    GdkRGBA background_color;
 
1058
#else
 
1059
    GdkColor background_color;
 
1060
#endif
812
1061
    GError *error = NULL;
 
1062
#ifdef HAVE_LIBINDICATOR
 
1063
    gchar **whitelist;
 
1064
    GDir *dir;
 
1065
    gsize length = 0;
 
1066
    guint indicators_loaded = 0, i;
 
1067
#endif
813
1068
 
814
1069
    /* Disable global menus */
815
1070
    g_unsetenv ("UBUNTU_MENUPROXY");
856
1111
    value = g_key_file_get_value (config, "greeter", "background", NULL);
857
1112
    if (!value)
858
1113
        value = g_strdup ("#000000");
 
1114
#if GTK_CHECK_VERSION (3, 0, 0)
859
1115
    if (!gdk_rgba_parse (&background_color, value))
 
1116
#else
 
1117
    if (!gdk_color_parse (value, &background_color))
 
1118
#endif
860
1119
    {
861
1120
        gchar *path;
862
1121
        GError *error = NULL;
876
1135
    else
877
1136
    {
878
1137
        g_debug ("Using background color %s", value);
 
1138
#if GTK_CHECK_VERSION (3, 0, 0)
879
1139
        default_background_color = gdk_rgba_copy (&background_color);
 
1140
#else
 
1141
        default_background_color = gdk_color_copy (&background_color);
 
1142
#endif
880
1143
    }
881
1144
    g_free (value);
882
1145
 
928
1191
    g_free (value);
929
1192
 
930
1193
    builder = gtk_builder_new ();
931
 
    if (!gtk_builder_add_from_file (builder, GREETER_DATA_DIR "/greeter.ui", &error))
 
1194
    if (!gtk_builder_add_from_string (builder, lightdm_gtk_greeter_ui,
 
1195
                                      lightdm_gtk_greeter_ui_length, &error))
932
1196
    {
933
1197
        g_warning ("Error loading UI: %s", error->message);
934
1198
        return EXIT_FAILURE;
947
1211
    session_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "session_combobox"));
948
1212
    language_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "language_combobox"));  
949
1213
    panel_window = GTK_WINDOW (gtk_builder_get_object (builder, "panel_window"));
950
 
 
951
 
    /* Load logo */
952
 
    value = g_key_file_get_value (config, "greeter", "logo", NULL);
953
 
    if (value)
954
 
    {
955
 
        gchar *path;
956
 
        GtkImage *logo = GTK_IMAGE (gtk_builder_get_object (builder, "logo"));
957
 
        GdkPixbuf *logo_pixbuf = NULL;
958
 
        GError *error = NULL;
959
 
 
960
 
        if (g_path_is_absolute (value))
961
 
            path = g_strdup (value);
962
 
        else
963
 
            path = g_build_filename (GREETER_DATA_DIR, value, NULL);
964
 
 
965
 
        g_debug ("Loading logo %s", path);
966
 
        logo_pixbuf = gdk_pixbuf_new_from_file (path, &error);
967
 
        if (logo_pixbuf)
968
 
            gtk_image_set_from_pixbuf (logo, logo_pixbuf);
969
 
        else
970
 
           g_warning ("Failed to load logo: %s", error->message);
971
 
        g_clear_error (&error);
972
 
        g_object_unref (logo_pixbuf);
973
 
        g_free (path);
974
 
        g_free (value);
975
 
    }
 
1214
    user_avatar = GTK_IMAGE (gtk_builder_get_object (builder, "user_avatar"));
976
1215
 
977
1216
    gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "hostname_label")), lightdm_get_hostname ());
978
1217
 
979
1218
    /* Glade can't handle custom menuitems, so set them up manually */
 
1219
#ifdef HAVE_LIBINDICATOR
 
1220
    /* whitelisted indicator modules to show */
 
1221
    whitelist = g_key_file_get_string_list (config, "greeter", "show-indicators", &length, NULL);
 
1222
    menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "menubar"));
 
1223
    /* load indicators */
 
1224
    if (g_file_test (INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
 
1225
    {
 
1226
        const gchar *name;
 
1227
        dir = g_dir_open (INDICATOR_DIR, 0, NULL);
 
1228
 
 
1229
        while ((name = g_dir_read_name (dir)))
 
1230
        {
 
1231
            gboolean match = FALSE;
 
1232
            for (i = 0; i < length; ++i)
 
1233
                if ((match = (g_strcmp0 (name, whitelist[i]) == 0)))
 
1234
                    break;
 
1235
 
 
1236
            if (G_LIKELY (!match))
 
1237
            {
 
1238
                g_debug ("Ignoring module (not in whitelist): %s", name);
 
1239
                continue;
 
1240
            }
 
1241
 
 
1242
            if (load_module (name, menuitem))
 
1243
                ++indicators_loaded;
 
1244
        }
 
1245
 
 
1246
        g_dir_close (dir);
 
1247
    }
 
1248
 
 
1249
    if (length > 0)
 
1250
        g_strfreev (whitelist);
 
1251
 
 
1252
    if (indicators_loaded > 0)
 
1253
    {
 
1254
        gtk_widget_set_can_focus (menuitem, TRUE);
 
1255
        gtk_widget_show (menuitem);
 
1256
    }
 
1257
#endif
 
1258
 
980
1259
    menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem"));
 
1260
#if GTK_CHECK_VERSION (3, 0, 0)
981
1261
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
1262
#else
 
1263
    hbox = gtk_hbox_new (FALSE, 0);
 
1264
#endif
982
1265
    gtk_widget_show (hbox);
983
1266
    gtk_container_add (GTK_CONTAINER (menuitem), hbox);
984
1267
    image = gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_MENU);
986
1269
    gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
987
1270
 
988
1271
    menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "a11y_menuitem"));
 
1272
#if GTK_CHECK_VERSION (3, 0, 0)
989
1273
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
1274
#else
 
1275
    hbox = gtk_hbox_new (FALSE, 0);
 
1276
#endif
990
1277
    gtk_widget_show (hbox);
991
1278
    gtk_container_add (GTK_CONTAINER (menuitem), hbox);
992
1279
    image = gtk_image_new_from_icon_name ("preferences-desktop-accessibility", GTK_ICON_SIZE_MENU);
1072
1359
        load_user_list ();
1073
1360
        gtk_widget_hide (GTK_WIDGET (cancel_button));
1074
1361
        gtk_widget_show (GTK_WIDGET (user_combo));
1075
 
    } 
 
1362
    }
1076
1363
 
1077
1364
    gtk_builder_connect_signals(builder, greeter);
1078
1365
 
1095
1382
    if (default_background_pixbuf)
1096
1383
        g_object_unref (default_background_pixbuf);
1097
1384
    if (default_background_color)
1098
 
        gdk_rgba_free ( default_background_color);
 
1385
#if GTK_CHECK_VERSION (3, 0, 0)
 
1386
        gdk_rgba_free (default_background_color);
 
1387
#else
 
1388
        gdk_color_free (default_background_color);
 
1389
#endif
1099
1390
 
1100
1391
    return EXIT_SUCCESS;
1101
1392
}