]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - greeters/gtk/lightdm-gtk-greeter.c
connect_to_server -> connect_sync, start_session -> start_session_sync
[sojka/lightdm.git] / greeters / gtk / lightdm-gtk-greeter.c
1 /*
2  * Copyright (C) 2010-2011 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 <stdlib.h>
13 #include <gtk/gtk.h>
14 #include <glib/gi18n.h>
15 #include <cairo.h>
16 #include <gdk-pixbuf/gdk-pixbuf.h>
17 #include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
18
19 #include "lightdm.h"
20
21 static LightDMGreeter *greeter;
22 static GtkWidget *window, *message_label, *user_view;
23 static GdkPixbuf *background_pixbuf = NULL;
24 static GtkWidget *prompt_box, *prompt_label, *prompt_entry, *session_combo;
25 static gchar *theme_name;
26
27 static gchar *
28 get_session ()
29 {
30     GtkTreeIter iter;
31     gchar *session;
32
33     if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (session_combo), &iter))
34         return g_strdup (lightdm_greeter_get_default_session_hint (greeter));
35
36     gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (session_combo)), &iter, 1, &session, -1);
37
38     return session;
39 }
40
41 static void
42 set_session (const gchar *session)
43 {
44     GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (session_combo));
45     GtkTreeIter iter;
46
47     if (!gtk_tree_model_get_iter_first (model, &iter))
48         return;
49   
50     do
51     {
52         gchar *s;
53         gboolean matched;
54         gtk_tree_model_get (model, &iter, 1, &s, -1);
55         matched = strcmp (s, session) == 0;
56         g_free (s);
57         if (matched)
58         {
59             gtk_combo_box_set_active_iter (GTK_COMBO_BOX (session_combo), &iter);
60             return;
61         }
62     } while (gtk_tree_model_iter_next (model, &iter));
63 }
64
65 static void
66 start_authentication (const gchar *username)
67 {
68     gtk_widget_hide (message_label);
69     gtk_label_set_text (GTK_LABEL (message_label), "");
70
71     if (strcmp (username, "*other") == 0)
72     {
73         lightdm_greeter_authenticate (greeter, NULL);
74     }
75     else if (strcmp (username, "*guest") == 0)
76     {
77         lightdm_greeter_authenticate_as_guest (greeter);
78     }
79     else
80     {
81         LightDMUser *user;
82         user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
83         if (user)
84             set_session (lightdm_user_get_session (user));
85         else
86             set_session (lightdm_greeter_get_default_session_hint (greeter));
87
88         lightdm_greeter_authenticate (greeter, username);
89     }
90 }
91
92 void user_treeview_row_activated_cb (GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *column);
93 G_MODULE_EXPORT
94 void
95 user_treeview_row_activated_cb (GtkWidget *widget, GtkTreePath *path, GtkTreeViewColumn *column)
96 {
97     GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));  
98     GtkTreeIter iter;
99     gchar *user;
100
101     gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path);
102     gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &user, -1);
103     start_authentication (user);
104     g_free (user);
105 }
106
107 static gboolean
108 idle_select_cb ()
109 {
110     GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
111     GtkTreeIter iter;
112     gchar *user;
113
114     if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (user_view)),
115                                          NULL, &iter))
116     {
117         gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &user, -1);
118         start_authentication (user);
119         g_free (user);
120     }
121
122     return FALSE;
123 }
124
125 gboolean user_treeview_button_press_event_cb (GtkWidget *widget, GdkEventButton *event);
126 G_MODULE_EXPORT
127 gboolean
128 user_treeview_button_press_event_cb (GtkWidget *widget, GdkEventButton *event)
129 {
130     /* Do it in the idle loop so the selection is done first */
131     g_idle_add (idle_select_cb, NULL);
132     return FALSE;
133 }
134
135 void login_cb (GtkWidget *widget);
136 G_MODULE_EXPORT
137 void
138 login_cb (GtkWidget *widget)
139 {
140     gtk_widget_set_sensitive (prompt_entry, FALSE);
141     if (!lightdm_greeter_get_in_authentication (greeter))
142         start_authentication (gtk_entry_get_text (GTK_ENTRY (prompt_entry)));
143     else
144         lightdm_greeter_respond (greeter, gtk_entry_get_text (GTK_ENTRY (prompt_entry)));
145     gtk_entry_set_text (GTK_ENTRY (prompt_entry), "");
146 }
147
148 void cancel_cb (GtkWidget *widget);
149 G_MODULE_EXPORT
150 void
151 cancel_cb (GtkWidget *widget)
152 {
153     lightdm_greeter_cancel_authentication (greeter);
154 }
155
156 static void
157 show_prompt_cb (LightDMGreeter *greeter, const gchar *text, LightDMPromptType type)
158 {
159     gtk_label_set_text (GTK_LABEL (prompt_label), text);
160     gtk_widget_set_sensitive (prompt_entry, TRUE);
161     gtk_entry_set_text (GTK_ENTRY (prompt_entry), "");
162     gtk_entry_set_visibility (GTK_ENTRY (prompt_entry), type != LIGHTDM_PROMPT_TYPE_SECRET);
163     gtk_widget_show (prompt_box);
164     gtk_widget_grab_focus (prompt_entry);
165 }
166
167 static void
168 show_message_cb (LightDMGreeter *greeter, const gchar *text, LightDMMessageType type)
169 {
170     gtk_label_set_text (GTK_LABEL (message_label), text);
171     gtk_widget_show (message_label);
172 }
173
174 static void
175 authentication_complete_cb (LightDMGreeter *greeter)
176 {
177     gtk_widget_hide (prompt_box);
178     gtk_label_set_text (GTK_LABEL (prompt_label), "");
179     gtk_entry_set_text (GTK_ENTRY (prompt_entry), "");
180
181     gtk_widget_grab_focus (user_view);
182
183     if (lightdm_greeter_get_is_authenticated (greeter))
184     {
185         gchar *session = get_session ();
186         if (lightdm_greeter_start_session_sync (greeter, session))
187             exit (EXIT_SUCCESS);
188         else
189             gtk_label_set_text (GTK_LABEL (message_label), "Failed to authenticate");
190         g_free (session);
191     }
192     else
193         gtk_label_set_text (GTK_LABEL (message_label), "Failed to authenticate");
194
195     gtk_widget_show (message_label);
196     if (lightdm_greeter_get_hide_users_hint (greeter))
197         lightdm_greeter_authenticate (greeter, NULL);
198 }
199
200 static void
201 autologin_timer_expired_cb (LightDMGreeter *greeter)
202 {
203     set_session (lightdm_greeter_get_default_session_hint (greeter));
204     if (lightdm_greeter_get_autologin_guest_hint (greeter))
205         lightdm_greeter_authenticate_as_guest (greeter);
206     else if (lightdm_greeter_get_autologin_user_hint (greeter))
207         lightdm_greeter_authenticate (greeter, lightdm_greeter_get_autologin_user_hint (greeter));
208 }
209
210 void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
211 G_MODULE_EXPORT
212 void
213 suspend_cb (GtkWidget *widget, LightDMGreeter *greeter)
214 {
215     lightdm_suspend ();
216 }
217
218 void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
219 G_MODULE_EXPORT
220 void
221 hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter)
222 {
223     lightdm_hibernate ();
224 }
225
226 static void
227 center_window (GtkWindow *window)
228 {
229     GtkAllocation allocation;
230     GdkDisplay *display;
231     GdkScreen *screen;
232     gint screen_width, screen_height;
233
234     gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
235     display = gdk_display_get_default ();
236     screen = gdk_display_get_default_screen (display);
237     screen_width = gdk_screen_get_width (screen);
238     screen_height = gdk_screen_get_height (screen);
239     gtk_window_move (GTK_WINDOW (window),
240                      (screen_width - allocation.width) / 2,
241                      (screen_height - allocation.height) / 2);
242 }
243
244 void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
245 G_MODULE_EXPORT
246 void
247 restart_cb (GtkWidget *widget, LightDMGreeter *greeter)
248 {
249     GtkWidget *dialog;
250
251     dialog = gtk_message_dialog_new (NULL,
252                                      GTK_DIALOG_MODAL,
253                                      GTK_MESSAGE_OTHER,
254                                      GTK_BUTTONS_NONE,
255                                      "%s", _("Are you sure you want to close all programs and restart the computer?"));
256     gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), gtk_image_new_from_icon_name ("system-restart", GTK_ICON_SIZE_DIALOG));
257     gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Cancel"), FALSE, _("Restart"), TRUE, NULL);
258     gtk_widget_show_all (dialog);
259     center_window (GTK_WINDOW (dialog));
260
261     if (gtk_dialog_run (GTK_DIALOG (dialog)))
262         lightdm_restart ();
263     gtk_widget_destroy (dialog);
264 }
265
266 void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
267 G_MODULE_EXPORT
268 void
269 shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter)
270 {
271     GtkWidget *dialog;
272
273     dialog = gtk_message_dialog_new (NULL,
274                                      GTK_DIALOG_MODAL,
275                                      GTK_MESSAGE_OTHER,
276                                      GTK_BUTTONS_NONE,
277                                      "%s", _("Are you sure you want to close all programs and shutdown the computer?"));
278     gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_DIALOG));
279     gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Cancel"), FALSE, _("Shutdown"), TRUE, NULL);
280     gtk_widget_show_all (dialog);
281     center_window (GTK_WINDOW (dialog));
282
283     if (gtk_dialog_run (GTK_DIALOG (dialog)))
284         lightdm_shutdown ();
285     gtk_widget_destroy (dialog);
286 }
287
288 static void
289 user_added_cb (LightDMUserList *user_list, LightDMUser *user)
290 {
291     GtkTreeModel *model;
292     GtkTreeIter iter;
293
294     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
295
296     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
297     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
298                         0, lightdm_user_get_name (user),
299                         1, lightdm_user_get_display_name (user),
300                         /*2, pixbuf,*/
301                         -1);
302 }
303
304 static gboolean
305 get_user_iter (const gchar *username, GtkTreeIter *iter)
306 {
307     GtkTreeModel *model;
308
309     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
310   
311     if (!gtk_tree_model_get_iter_first (model, iter))
312         return FALSE;
313     do
314     {
315         gchar *name;
316         gboolean matched;
317
318         gtk_tree_model_get (model, iter, 0, &name, -1);
319         matched = strcmp (name, username) == 0;
320         g_free (name);
321         if (matched)
322             return TRUE;
323     } while (gtk_tree_model_iter_next (model, iter));
324
325     return FALSE;
326 }
327
328 static void
329 user_changed_cb (LightDMUserList *user_list, LightDMUser *user)
330 {
331     GtkTreeModel *model;
332     GtkTreeIter iter;
333
334     if (!get_user_iter (lightdm_user_get_name (user), &iter))
335         return;
336
337     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
338     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
339                         0, lightdm_user_get_name (user),
340                         1, lightdm_user_get_display_name (user),
341                         /*2, pixbuf,*/
342                         -1);
343 }
344
345 static void
346 user_removed_cb (LightDMUserList *user_list, LightDMUser *user)
347 {
348     GtkTreeModel *model;
349     GtkTreeIter iter;
350
351     if (!get_user_iter (lightdm_user_get_name (user), &iter))
352         return;
353
354     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));  
355     gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
356 }
357
358 void a11y_font_cb (GtkWidget *widget);
359 G_MODULE_EXPORT
360 void
361 a11y_font_cb (GtkWidget *widget)
362 {
363     if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
364         g_object_set (gtk_settings_get_default (), "gtk-font-name", "Ubuntu 20", NULL);
365     else
366         g_object_set (gtk_settings_get_default (), "gtk-font-name", "Ubuntu 10", NULL);
367 }
368
369 void a11y_contrast_cb (GtkWidget *widget);
370 G_MODULE_EXPORT
371 void
372 a11y_contrast_cb (GtkWidget *widget)
373 {
374     if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
375         g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrastInverse", NULL);
376     else
377         g_object_set (gtk_settings_get_default (), "gtk-theme-name", theme_name, NULL);
378 }
379
380 static void
381 sigterm_cb (int signum)
382 {
383     exit (0);
384 }
385
386 gboolean draw_background_cb (GtkWidget *widget, cairo_t *context);
387 G_MODULE_EXPORT
388 gboolean
389 draw_background_cb (GtkWidget *widget, cairo_t *context)
390 {
391     if (background_pixbuf)
392         gdk_cairo_set_source_pixbuf (context, background_pixbuf, 0.0, 0.0);
393     else
394         cairo_set_source_rgb (context, 0, 0, 0);
395     cairo_fill (context);
396
397     return FALSE;
398 }
399
400 static void
401 load_user_list ()
402 {
403     const GList *items, *item;
404     GtkTreeModel *model;
405     GtkTreeIter iter;
406
407     g_signal_connect (lightdm_user_list_get_instance (), "user-added", G_CALLBACK (user_added_cb), NULL);
408     g_signal_connect (lightdm_user_list_get_instance (), "user-changed", G_CALLBACK (user_changed_cb), NULL);
409     g_signal_connect (lightdm_user_list_get_instance (), "user-removed", G_CALLBACK (user_removed_cb), NULL);
410
411     items = lightdm_user_list_get_users (lightdm_user_list_get_instance ());
412
413     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
414     for (item = items; item; item = item->next)
415     {
416         LightDMUser *user = item->data;
417         const gchar *image;
418         GdkPixbuf *pixbuf = NULL;
419
420         image = lightdm_user_get_image (user);
421         if (image)
422             pixbuf = gdk_pixbuf_new_from_file_at_scale (image, 64, 64, TRUE, NULL);
423         if (!pixbuf)
424             pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
425                                                "stock_person",
426                                                64,
427                                                GTK_ICON_LOOKUP_USE_BUILTIN,
428                                                NULL);
429         /*if (!pixbuf)
430         {
431             pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 64, 64);
432             memset (gdk_pixbuf_get_pixels (pixbuf), 0, gdk_pixbuf_get_height (pixbuf) * gdk_pixbuf_get_rowstride (pixbuf) * gdk_pixbuf_get_n_channels (pixbuf));
433         }*/
434
435         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
436         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
437                             0, lightdm_user_get_name (user),
438                             1, lightdm_user_get_display_name (user),
439                             2, pixbuf,
440                             -1);
441     }
442     if (lightdm_greeter_get_has_guest_account_hint (greeter))
443     {
444         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
445         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
446                             0, "*guest",
447                             1, "Guest Account",
448                             2, gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "stock_person", 64, 0, NULL),
449                             -1);
450     }
451
452     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
453     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
454                         0, "*other",
455                         1, "Other...",
456                         2, gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "stock_person", 64, 0, NULL),
457                         -1);
458 }
459
460 int
461 main(int argc, char **argv)
462 {
463     GdkWindow *root;
464     GdkDisplay *display;
465     GdkScreen *screen;
466     gint screen_width, screen_height;
467     GtkBuilder *builder;
468     GtkTreeModel *model;
469     const GList *items, *item;
470     GtkTreeIter iter;
471     GtkCellRenderer *renderer;
472     gchar *rc_file, *background_image;
473     GError *error = NULL;
474
475     /* Disable global menus */
476     unsetenv ("UBUNTU_MENUPROXY");
477
478     signal (SIGTERM, sigterm_cb);
479   
480     gtk_init (&argc, &argv);
481
482     greeter = lightdm_greeter_new ();
483     g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);  
484     g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
485     g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
486     g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (autologin_timer_expired_cb), NULL);
487     if (!lightdm_greeter_connect_sync (greeter))
488         return EXIT_FAILURE;
489
490     display = gdk_display_get_default ();
491     screen = gdk_display_get_default_screen (display);
492     screen_width = gdk_screen_get_width (screen);
493     screen_height = gdk_screen_get_height (screen);
494
495     g_object_get (gtk_settings_get_default (), "gtk-theme-name", &theme_name, NULL);
496     rc_file = NULL; // FIXME
497     if (rc_file)
498     {
499         gchar *path = g_build_filename (GREETER_DATA_DIR, rc_file, NULL);
500         g_free (rc_file);
501         gtk_rc_add_default_file (path);
502         g_free (path);
503     }
504
505     builder = gtk_builder_new ();
506     if (!gtk_builder_add_from_file (builder, GREETER_DATA_DIR "/greeter.ui", &error))
507     {
508         g_warning ("Error loading UI: %s", error->message);
509         return EXIT_FAILURE;
510     }
511     g_clear_error (&error);
512     window = GTK_WIDGET (gtk_builder_get_object (builder, "greeter_window"));
513     prompt_box = GTK_WIDGET (gtk_builder_get_object (builder, "prompt_box"));
514     prompt_label = GTK_WIDGET (gtk_builder_get_object (builder, "prompt_label"));
515     prompt_entry = GTK_WIDGET (gtk_builder_get_object (builder, "prompt_entry"));
516     message_label = GTK_WIDGET (gtk_builder_get_object (builder, "message_label"));
517     session_combo = GTK_WIDGET (gtk_builder_get_object (builder, "session_combobox"));
518   
519     gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "hostname_label")), lightdm_get_hostname ());
520
521     background_image = NULL; // FIXME
522     if (background_image)
523     {
524         gchar *path;
525         GdkPixbuf *pixbuf;
526         GError *error = NULL;
527
528         path = g_build_filename (GREETER_DATA_DIR, background_image, NULL);
529         g_free (background_image);
530         pixbuf = gdk_pixbuf_new_from_file (path, &error);
531         if (!pixbuf)
532            g_warning ("Failed to load background: %s", error->message);
533         g_clear_error (&error);
534         g_free (path);
535
536         if (pixbuf)
537         {
538             background_pixbuf = gdk_pixbuf_scale_simple (pixbuf, screen_width, screen_height, GDK_INTERP_BILINEAR);
539             g_object_unref (pixbuf);
540         }
541     }
542
543     /* Set the background */
544     root = gdk_get_default_root_window ();
545     gdk_window_set_cursor (root, gdk_cursor_new (GDK_LEFT_PTR));
546     if (background_pixbuf)
547     {
548         //GdkPixmap *pixmap;
549
550         //gdk_pixbuf_render_pixmap_and_mask_for_colormap (background_pixbuf, gdk_window_get_colormap (root), &pixmap, NULL, 0);
551         //gdk_window_set_back_pixmap (root, pixmap, FALSE);
552     }
553
554     if (!lightdm_get_can_suspend ())
555         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "suspend_menuitem")));
556     if (!lightdm_get_can_hibernate ())
557         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "hibernate_menuitem")));
558     if (!lightdm_get_can_restart ())
559         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "restart_menuitem")));
560     if (!lightdm_get_can_shutdown ())
561         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "shutdown_menuitem")));
562
563     user_view = GTK_WIDGET (gtk_builder_get_object (builder, "user_treeview"));
564     gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (user_view), 0, "Face", gtk_cell_renderer_pixbuf_new(), "pixbuf", 2, NULL);
565     gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (user_view), 1, "Name", gtk_cell_renderer_text_new(), "text", 1, NULL);
566
567     if (lightdm_greeter_get_hide_users_hint (greeter))
568         lightdm_greeter_authenticate (greeter, NULL);
569     else
570     {
571         load_user_list ();
572         gtk_widget_show (user_view);
573     }
574   
575     // FIXME: Select the requested user if lightdm_greeter_get_select_user_hint () set
576
577     renderer = gtk_cell_renderer_text_new();
578     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (session_combo), renderer, TRUE);
579     gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (session_combo), renderer, "text", 0);
580     model = gtk_combo_box_get_model (GTK_COMBO_BOX (session_combo));
581     items = lightdm_get_sessions ();
582     for (item = items; item; item = item->next)
583     {
584         LightDMSession *session = item->data;
585
586         gtk_widget_show (session_combo);
587         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
588         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
589                             0, lightdm_session_get_name (session),
590                             1, lightdm_session_get_key (session),
591                             -1);
592     }
593     set_session (lightdm_greeter_get_default_session_hint (greeter));
594
595     gtk_window_set_default_size (GTK_WINDOW (window), screen_width, screen_height);
596     gtk_builder_connect_signals(builder, greeter);
597     gtk_widget_show (window);
598
599     gtk_widget_grab_focus (user_view);
600
601     gtk_main ();
602
603     return EXIT_SUCCESS;
604 }