]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - greeters/ldm-gtk-greeter.c
Add language information
[sojka/lightdm.git] / greeters / ldm-gtk-greeter.c
1 /*
2  * Copyright (C) 2010 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  * 
5  * This program is free software: you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License as published by the Free Software
7  * Foundation, either version 3 of the License, or (at your option) any later
8  * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
9  * license.
10  */
11
12 #include <gtk/gtk.h>
13 #include <glib/gi18n.h>
14
15 #include "greeter.h"
16
17 static LdmGreeter *greeter;
18 static GtkListStore *user_model;
19 static GtkWidget *user_window, *vbox, *label, *user_view;
20 static GtkWidget *username_entry, *password_entry;
21 static GtkWidget *panel_window;
22
23 static void
24 user_view_activate_cb (GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *column)
25 {
26     GtkTreeIter iter;
27     gchar *user;
28
29     gtk_tree_model_get_iter (GTK_TREE_MODEL (user_model), &iter, path);
30     gtk_tree_model_get (GTK_TREE_MODEL (user_model), &iter, 0, &user, -1);
31
32     gtk_entry_set_text (GTK_ENTRY (username_entry), user);
33     ldm_greeter_start_authentication (greeter, user);
34
35     g_free (user);
36 }
37
38 static void
39 username_activate_cb (GtkWidget *widget)
40 {
41     ldm_greeter_start_authentication (greeter, gtk_entry_get_text (GTK_ENTRY (widget)));
42 }
43
44 static void
45 password_activate_cb (GtkWidget *widget)
46 {
47     gtk_widget_set_sensitive (widget, FALSE);
48     ldm_greeter_provide_secret (greeter, gtk_entry_get_text (GTK_ENTRY (widget)));
49 }
50
51 static void
52 show_prompt_cb (LdmGreeter *greeter, const gchar *text)
53 {
54     gtk_widget_show (password_entry);
55     gtk_widget_set_sensitive (password_entry, TRUE);
56     gtk_widget_grab_focus (password_entry);
57 }
58
59 static void
60 show_message_cb (LdmGreeter *greeter, const gchar *text)
61 {
62     gtk_widget_show (label);
63     gtk_label_set_text (GTK_LABEL (label), text);
64 }
65
66 static void
67 authentication_complete_cb (LdmGreeter *greeter)
68 {
69     if (ldm_greeter_get_is_authenticated (greeter))
70     {
71         ldm_greeter_login (greeter);
72     }
73     else
74     {
75         gtk_widget_show (label);
76         gtk_label_set_text (GTK_LABEL (label), "Failed to authenticate");
77         gtk_entry_set_text (GTK_ENTRY (password_entry), "");
78         gtk_widget_grab_focus (username_entry);
79     }
80 }
81
82 static void
83 timed_login_cb (LdmGreeter *greeter, const gchar *username)
84 {
85     ldm_greeter_login (greeter);
86 }
87
88 static void
89 quit_cb (LdmGreeter *greeter, const gchar *username)
90 {
91     gtk_main_quit ();
92 }
93
94 static void
95 layout_changed_cb (GtkWidget *widget)
96 {
97     if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
98         ldm_greeter_set_layout (greeter, g_object_get_data (G_OBJECT (widget), "layout"));
99 }
100
101 static void
102 session_changed_cb (GtkWidget *widget)
103 {
104     if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
105         ldm_greeter_set_session (greeter, g_object_get_data (G_OBJECT (widget), "key"));
106 }
107
108 int
109 main(int argc, char **argv)
110 {
111     GdkWindow *root;
112     const GList *items, *item;
113     GSList *session_radio_list = NULL, *language_radio_list = NULL, *layout_radio_list = NULL;
114     GtkCellRenderer *renderer;
115     GdkDisplay *display;
116     GdkScreen *screen;
117     gint screen_width, screen_height;
118     GtkAllocation allocation;
119     GtkWidget *option_menu, *power_menu;
120     GtkWidget *menu_bar, *menu, *menu_item;
121     GdkColor background_color;
122     gint n_power_items = 0;
123
124     gtk_init (&argc, &argv);
125
126     greeter = ldm_greeter_new ();
127
128     g_signal_connect (G_OBJECT (greeter), "show-prompt", G_CALLBACK (show_prompt_cb), NULL);  
129     g_signal_connect (G_OBJECT (greeter), "show-message", G_CALLBACK (show_message_cb), NULL);
130     g_signal_connect (G_OBJECT (greeter), "show-error", G_CALLBACK (show_message_cb), NULL);
131     g_signal_connect (G_OBJECT (greeter), "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
132     g_signal_connect (G_OBJECT (greeter), "timed-login", G_CALLBACK (timed_login_cb), NULL);
133     g_signal_connect (G_OBJECT (greeter), "quit", G_CALLBACK (quit_cb), NULL);
134
135     ldm_greeter_connect (greeter);
136
137     display = gdk_display_get_default ();
138     screen = gdk_display_get_default_screen (display);
139     screen_width = gdk_screen_get_width (screen);
140     screen_height = gdk_screen_get_height (screen);
141   
142     root = gdk_get_default_root_window ();
143     gdk_window_set_cursor (root, gdk_cursor_new (GDK_LEFT_PTR));
144     gdk_color_parse ("#000000", &background_color);
145     gdk_color_alloc (gdk_window_get_colormap (root), &background_color);
146     gdk_window_set_back_pixmap (root, NULL, TRUE);
147     gdk_window_set_background (root, &background_color);
148     gdk_window_clear(root);
149
150     user_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
151     gtk_window_set_decorated (GTK_WINDOW (user_window), FALSE);
152     gtk_window_set_resizable (GTK_WINDOW (user_window), FALSE);
153     gtk_container_set_border_width (GTK_CONTAINER (user_window), 12);
154     g_signal_connect (user_window, "delete-event", gtk_main_quit, NULL);
155
156     vbox = gtk_vbox_new (FALSE, 6);
157     gtk_container_add (GTK_CONTAINER (user_window), vbox);
158
159     label = gtk_label_new ("");
160     gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
161     gtk_widget_set_no_show_all (label, TRUE);    
162
163     user_model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF);
164     items = ldm_greeter_get_users (greeter);
165     for (item = items; item; item = item->next)
166     {
167         LdmUser *user = item->data;
168         GtkTreeIter iter;
169         const gchar *image;
170         GdkPixbuf *pixbuf = NULL;
171
172         image = ldm_user_get_image (user);
173         if (image[0] != '\0')
174         {
175             gchar *path;
176
177             path = g_filename_from_uri (image, NULL, NULL);
178             if (path)
179                 pixbuf = gdk_pixbuf_new_from_file_at_scale (path, 64, 64, TRUE, NULL);
180             g_free (path);
181         }
182         if (!pixbuf)
183             pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
184                                                "stock_person",
185                                                64,
186                                                0,
187                                                NULL);
188       
189         gtk_list_store_append (GTK_LIST_STORE (user_model), &iter);
190         gtk_list_store_set (GTK_LIST_STORE (user_model), &iter,
191                             0, ldm_user_get_name (user),
192                             1, ldm_user_get_display_name (user),
193                             2, pixbuf,
194                             -1);
195     }
196
197     user_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (user_model));
198     gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (user_view), FALSE);
199     gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (user_view), GTK_TREE_VIEW_GRID_LINES_NONE);
200
201     renderer = gtk_cell_renderer_pixbuf_new();
202     gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (user_view), 0, "User", renderer, "pixbuf", 2, NULL);
203
204     renderer = gtk_cell_renderer_text_new();
205     gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (user_view), 1, "User", renderer, "text", 1, NULL);
206
207     gtk_box_pack_start (GTK_BOX (vbox), user_view, FALSE, FALSE, 0);
208     g_signal_connect (user_view, "row-activated", G_CALLBACK (user_view_activate_cb), NULL);
209
210     username_entry = gtk_entry_new ();
211     gtk_box_pack_start (GTK_BOX (vbox), username_entry, FALSE, FALSE, 0);
212     g_signal_connect (username_entry, "activate", G_CALLBACK (username_activate_cb), NULL);
213     gtk_widget_set_no_show_all (username_entry, TRUE);
214
215     password_entry = gtk_entry_new ();
216     //gtk_entry_set_visibility (GTK_ENTRY (password_entry), FALSE);
217     gtk_widget_set_sensitive (password_entry, FALSE);
218     gtk_box_pack_start (GTK_BOX (vbox), password_entry, FALSE, FALSE, 0);
219     g_signal_connect (password_entry, "activate", G_CALLBACK (password_activate_cb), NULL);
220     gtk_widget_set_no_show_all (password_entry, TRUE);
221
222     gtk_widget_show_all (user_window);
223   
224     /* Center the window */
225     gtk_widget_get_allocation (user_window, &allocation);
226     gtk_window_move (GTK_WINDOW (user_window),
227                      (screen_width - allocation.width) / 2,
228                      (screen_height - allocation.height) / 2);
229
230     panel_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
231     gtk_window_set_decorated (GTK_WINDOW (panel_window), FALSE);
232     gtk_window_set_resizable (GTK_WINDOW (panel_window), FALSE);
233     gtk_window_set_default_size (GTK_WINDOW (panel_window), screen_width, 10);
234
235     menu_bar = gtk_menu_bar_new ();
236     gtk_container_add (GTK_CONTAINER (panel_window), menu_bar);
237
238     menu_item = gtk_image_menu_item_new ();
239     gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), gtk_image_new_from_icon_name ("access", GTK_ICON_SIZE_LARGE_TOOLBAR));
240     gtk_menu_item_set_label (GTK_MENU_ITEM (menu_item), ""); // NOTE: Needed to make the icon show as selected
241     gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
242     gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), menu_item);
243
244     menu = gtk_menu_new ();
245     gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
246     gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_item_new_with_label ("?1"));
247     gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_item_new_with_label ("?2"));
248     gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_menu_item_new_with_label ("?3"));
249
250     menu_item = gtk_menu_item_new_with_label (_("Options"));
251     gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), menu_item);
252     option_menu = gtk_menu_new ();
253     gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), option_menu);
254
255     menu_item = gtk_menu_item_new_with_label (_("Language"));
256     gtk_menu_shell_append (GTK_MENU_SHELL (option_menu), menu_item);
257     menu = gtk_menu_new ();
258     gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
259     items = ldm_greeter_get_languages (greeter);
260     for (item = items; item; item = item->next)
261     {
262         LdmLanguage *language = item->data;
263         gchar *label;
264       
265         if (ldm_language_get_name (language)[0] == '\0')
266             label = g_strdup (ldm_language_get_code (language));
267         else
268             label = g_strdup_printf ("%s - %s", ldm_language_get_name (language), ldm_language_get_territory (language));
269
270         menu_item = gtk_radio_menu_item_new_with_label (language_radio_list, label);
271         language_radio_list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_item));
272         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
273
274         if (g_str_equal (ldm_language_get_code (language), ldm_greeter_get_language (greeter)))
275             gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
276
277         //g_object_set_data (G_OBJECT (menu_item), "language", g_strdup (ldm_language_get_code (language)));
278         //g_signal_connect (menu_item, "toggled", G_CALLBACK (language_changed_cb), NULL);
279     }
280
281     menu_item = gtk_menu_item_new_with_label (_("Keyboard Layout"));
282     gtk_menu_shell_append (GTK_MENU_SHELL (option_menu), menu_item);
283     menu = gtk_menu_new ();
284     gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
285     items = ldm_greeter_get_layouts (greeter);
286     for (item = items; item; item = item->next)
287     {
288         LdmLayout *layout = item->data;
289
290         menu_item = gtk_radio_menu_item_new_with_label (layout_radio_list, ldm_layout_get_description (layout));
291         layout_radio_list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_item));
292         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
293
294         if (g_str_equal (ldm_layout_get_name (layout), ldm_greeter_get_layout (greeter)))
295             gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
296
297         g_object_set_data (G_OBJECT (menu_item), "layout", g_strdup (ldm_layout_get_name (layout)));
298         g_signal_connect (menu_item, "toggled", G_CALLBACK (layout_changed_cb), NULL);
299     }
300
301     menu_item = gtk_menu_item_new_with_label (_("Session"));
302     gtk_menu_shell_append (GTK_MENU_SHELL (option_menu), menu_item);
303     menu = gtk_menu_new ();
304     gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
305     items = ldm_greeter_get_sessions (greeter);
306     for (item = items; item; item = item->next)
307     {
308         LdmSession *session = item->data;
309
310         menu_item = gtk_radio_menu_item_new_with_label (session_radio_list, ldm_session_get_name (session));
311         session_radio_list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_item));
312         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
313
314         if (g_str_equal (ldm_session_get_key (session), ldm_greeter_get_session (greeter)))
315             gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
316
317         g_object_set_data (G_OBJECT (menu_item), "key", g_strdup (ldm_session_get_key (session)));
318         g_signal_connect (menu_item, "toggled", G_CALLBACK (session_changed_cb), NULL);
319     }
320
321     power_menu = gtk_menu_new ();
322     if (ldm_greeter_get_can_suspend (greeter))
323     {
324         gtk_menu_shell_append (GTK_MENU_SHELL (power_menu), gtk_menu_item_new_with_label ("Suspend"));
325         n_power_items++;
326     }
327     if (ldm_greeter_get_can_hibernate (greeter))
328     {
329         gtk_menu_shell_append (GTK_MENU_SHELL (power_menu), gtk_menu_item_new_with_label ("Hibernate"));
330         n_power_items++;
331     }
332     if (ldm_greeter_get_can_restart (greeter))
333     {
334         gtk_menu_shell_append (GTK_MENU_SHELL (power_menu), gtk_menu_item_new_with_label ("Restart..."));
335         n_power_items++;
336     }
337     if (ldm_greeter_get_can_shutdown (greeter))
338     {
339         gtk_menu_shell_append (GTK_MENU_SHELL (power_menu), gtk_menu_item_new_with_label ("Shutdown..."));
340         n_power_items++;
341     }
342     if (n_power_items > 0)
343     {
344         menu_item = gtk_image_menu_item_new ();
345         gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
346         gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menu_item), TRUE);
347         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_LARGE_TOOLBAR));
348         gtk_menu_item_set_label (GTK_MENU_ITEM (menu_item), ""); // NOTE: Needed to make the icon show as selected
349         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
350         gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), menu_item);
351     }
352
353     gtk_widget_show_all (panel_window);
354
355     gtk_widget_get_allocation (panel_window, &allocation);
356     gtk_widget_set_size_request (GTK_WIDGET (panel_window), screen_width, allocation.height);  
357     gtk_window_move (GTK_WINDOW (panel_window), 0, screen_height - allocation.height);
358
359     gtk_main ();
360
361     return 0;
362 }