]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - greeters/gtk/lightdm-gtk-greeter.c
Support hide-users hint
[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/greeter.h"
20
21 static LdmGreeter *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 (ldm_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         ldm_greeter_login_with_user_prompt (greeter);
74     }
75     else if (strcmp (username, "*guest") == 0)
76     {
77         ldm_greeter_login_as_guest (greeter);
78     }
79     else
80     {
81         LdmUser *user;
82         user = ldm_greeter_get_user_by_name (greeter, username);
83         if (user)
84             set_session (ldm_user_get_session (user));
85         else
86             set_session (ldm_greeter_get_default_session_hint (greeter));
87
88         ldm_greeter_login (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 (!ldm_greeter_get_in_authentication (greeter))
142         start_authentication (gtk_entry_get_text (GTK_ENTRY (prompt_entry)));
143     else
144         ldm_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     ldm_greeter_cancel_authentication (greeter);
154 }
155
156 static void
157 show_prompt_cb (LdmGreeter *greeter, const gchar *text, LdmPromptType 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 != LDM_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 (LdmGreeter *greeter, const gchar *text, LdmMessageType 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 (LdmGreeter *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 (ldm_greeter_get_is_authenticated (greeter))
184     {
185         gchar *session = get_session ();
186         ldm_greeter_start_session (greeter, session);
187         g_free (session);
188     }
189     else
190     {
191         gtk_label_set_text (GTK_LABEL (message_label), "Failed to authenticate");
192         gtk_widget_show (message_label);
193         if (ldm_greeter_get_hide_users_hint (greeter))
194             ldm_greeter_login_with_user_prompt (greeter);
195     }
196 }
197
198 static void
199 autologin_timer_expired_cb (LdmGreeter *greeter)
200 {
201     set_session (ldm_greeter_get_default_session_hint (greeter));
202     if (ldm_greeter_get_autologin_guest_hint (greeter))
203         ldm_greeter_login_as_guest (greeter);
204     else if (ldm_greeter_get_autologin_user_hint (greeter))
205         ldm_greeter_login (greeter, ldm_greeter_get_autologin_user_hint (greeter));
206 }
207
208 void suspend_cb (GtkWidget *widget, LdmGreeter *greeter);
209 G_MODULE_EXPORT
210 void
211 suspend_cb (GtkWidget *widget, LdmGreeter *greeter)
212 {
213     ldm_greeter_suspend (greeter);
214 }
215
216 void hibernate_cb (GtkWidget *widget, LdmGreeter *greeter);
217 G_MODULE_EXPORT
218 void
219 hibernate_cb (GtkWidget *widget, LdmGreeter *greeter)
220 {
221     ldm_greeter_hibernate (greeter);
222 }
223
224 static void
225 center_window (GtkWindow *window)
226 {
227     GtkAllocation allocation;
228     GdkDisplay *display;
229     GdkScreen *screen;
230     gint screen_width, screen_height;
231
232     gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
233     display = gdk_display_get_default ();
234     screen = gdk_display_get_default_screen (display);
235     screen_width = gdk_screen_get_width (screen);
236     screen_height = gdk_screen_get_height (screen);
237     gtk_window_move (GTK_WINDOW (window),
238                      (screen_width - allocation.width) / 2,
239                      (screen_height - allocation.height) / 2);
240 }
241
242 void restart_cb (GtkWidget *widget, LdmGreeter *greeter);
243 G_MODULE_EXPORT
244 void
245 restart_cb (GtkWidget *widget, LdmGreeter *greeter)
246 {
247     GtkWidget *dialog;
248
249     dialog = gtk_message_dialog_new (NULL,
250                                      GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
251                                      GTK_MESSAGE_OTHER,
252                                      GTK_BUTTONS_NONE,
253                                      "%s", _("Are you sure you want to close all programs and restart the computer?"));
254     gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), gtk_image_new_from_icon_name ("system-restart", GTK_ICON_SIZE_DIALOG));
255     gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Cancel"), FALSE, _("Restart"), TRUE, NULL);
256     gtk_widget_show_all (dialog);
257     center_window (GTK_WINDOW (dialog));
258
259     if (gtk_dialog_run (GTK_DIALOG (dialog)))
260         ldm_greeter_restart (greeter);
261     gtk_widget_destroy (dialog);
262 }
263
264 void shutdown_cb (GtkWidget *widget, LdmGreeter *greeter);
265 G_MODULE_EXPORT
266 void
267 shutdown_cb (GtkWidget *widget, LdmGreeter *greeter)
268 {
269     GtkWidget *dialog;
270
271     dialog = gtk_message_dialog_new (NULL,
272                                      GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
273                                      GTK_MESSAGE_OTHER,
274                                      GTK_BUTTONS_NONE,
275                                      "%s", _("Are you sure you want to close all programs and shutdown the computer?"));
276     gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_DIALOG));
277     gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("Cancel"), FALSE, _("Shutdown"), TRUE, NULL);
278     gtk_widget_show_all (dialog);
279     center_window (GTK_WINDOW (dialog));
280
281     if (gtk_dialog_run (GTK_DIALOG (dialog)))
282         ldm_greeter_shutdown (greeter);
283     gtk_widget_destroy (dialog);
284 }
285
286 static gboolean
287 fade_timer_cb (gpointer data)
288 {
289     gdouble opacity;
290
291     opacity = gtk_window_get_opacity (GTK_WINDOW (window));
292     opacity -= 0.1;
293     if (opacity <= 0)
294     {
295         gtk_main_quit ();
296         return FALSE;
297     }
298     gtk_window_set_opacity (GTK_WINDOW (window), opacity);
299
300     return TRUE;
301 }
302
303 static void
304 user_added_cb (LdmGreeter *greeter, LdmUser *user)
305 {
306     GtkTreeModel *model;
307     GtkTreeIter iter;
308
309     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
310
311     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
312     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
313                         0, ldm_user_get_name (user),
314                         1, ldm_user_get_display_name (user),
315                         /*2, pixbuf,*/
316                         -1);
317 }
318
319 static gboolean
320 get_user_iter (const gchar *username, GtkTreeIter *iter)
321 {
322     GtkTreeModel *model;
323
324     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
325   
326     if (!gtk_tree_model_get_iter_first (model, iter))
327         return FALSE;
328     do
329     {
330         gchar *name;
331         gboolean matched;
332
333         gtk_tree_model_get (model, iter, 0, &name, -1);
334         matched = strcmp (name, username) == 0;
335         g_free (name);
336         if (matched)
337             return TRUE;
338     } while (gtk_tree_model_iter_next (model, iter));
339
340     return FALSE;
341 }
342
343 static void
344 user_changed_cb (LdmGreeter *greeter, LdmUser *user)
345 {
346     GtkTreeModel *model;
347     GtkTreeIter iter;
348
349     if (!get_user_iter (ldm_user_get_name (user), &iter))
350         return;
351
352     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
353     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
354                         0, ldm_user_get_name (user),
355                         1, ldm_user_get_display_name (user),
356                         /*2, pixbuf,*/
357                         -1);
358 }
359
360 static void
361 user_removed_cb (LdmGreeter *greeter, LdmUser *user)
362 {
363     GtkTreeModel *model;
364     GtkTreeIter iter;
365
366     if (!get_user_iter (ldm_user_get_name (user), &iter))
367         return;
368
369     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));  
370     gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
371 }
372
373 static void
374 quit_cb (LdmGreeter *greeter, const gchar *username)
375 {
376     /* Fade out the greeter */
377     g_timeout_add (40, (GSourceFunc) fade_timer_cb, NULL);
378 }
379
380 void a11y_font_cb (GtkWidget *widget);
381 G_MODULE_EXPORT
382 void
383 a11y_font_cb (GtkWidget *widget)
384 {
385     if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
386         g_object_set (gtk_settings_get_default (), "gtk-font-name", "Ubuntu 20", NULL);
387     else
388         g_object_set (gtk_settings_get_default (), "gtk-font-name", "Ubuntu 10", NULL);
389 }
390
391 void a11y_contrast_cb (GtkWidget *widget);
392 G_MODULE_EXPORT
393 void
394 a11y_contrast_cb (GtkWidget *widget)
395 {
396     if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)))
397         g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrastInverse", NULL);
398     else
399         g_object_set (gtk_settings_get_default (), "gtk-theme-name", theme_name, NULL);
400 }
401
402 static void
403 sigterm_cb (int signum)
404 {
405     exit (0);
406 }
407
408 gboolean draw_background_cb (GtkWidget *widget, GdkEventExpose *event);
409 G_MODULE_EXPORT
410 gboolean
411 draw_background_cb (GtkWidget *widget, GdkEventExpose *event)
412 {
413     cairo_t *context;
414     GtkAllocation allocation;
415
416     context = gdk_cairo_create (GDK_DRAWABLE (gtk_widget_get_window (widget)));
417
418     gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
419     if (background_pixbuf)
420         gdk_cairo_set_source_pixbuf (context, background_pixbuf, 0.0, 0.0);
421     else
422         cairo_set_source_rgb (context, 0, 0, 0);
423     cairo_fill (context);
424
425     cairo_destroy (context);
426
427     return FALSE;
428 }
429
430 static void
431 load_user_list ()
432 {
433     const GList *items, *item;
434     GtkTreeModel *model;
435     GtkTreeIter iter;
436
437     g_signal_connect (greeter, "user-added", G_CALLBACK (user_added_cb), NULL);
438     g_signal_connect (greeter, "user-changed", G_CALLBACK (user_changed_cb), NULL);  
439     items = ldm_greeter_get_users (greeter);
440
441     model = gtk_tree_view_get_model (GTK_TREE_VIEW (user_view));
442     for (item = items; item; item = item->next)
443     {
444         LdmUser *user = item->data;
445         const gchar *image;
446         GdkPixbuf *pixbuf = NULL;
447
448         image = ldm_user_get_image (user);
449         if (image)
450         {
451             gchar *path;
452
453             path = g_filename_from_uri (image, NULL, NULL);
454             if (path)
455                 pixbuf = gdk_pixbuf_new_from_file_at_scale (path, 64, 64, TRUE, NULL);
456             g_free (path);
457         }
458         if (!pixbuf)
459             pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
460                                                "stock_person",
461                                                64,
462                                                GTK_ICON_LOOKUP_USE_BUILTIN,
463                                                NULL);
464         /*if (!pixbuf)
465         {
466             pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 64, 64);
467             memset (gdk_pixbuf_get_pixels (pixbuf), 0, gdk_pixbuf_get_height (pixbuf) * gdk_pixbuf_get_rowstride (pixbuf) * gdk_pixbuf_get_n_channels (pixbuf));
468         }*/
469
470         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
471         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
472                             0, ldm_user_get_name (user),
473                             1, ldm_user_get_display_name (user),
474                             2, pixbuf,
475                             -1);
476     }
477     if (ldm_greeter_get_has_guest_account_hint (greeter))
478     {
479         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
480         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
481                             0, "*guest",
482                             1, "Guest Account",
483                             2, gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "stock_person", 64, 0, NULL),
484                             -1);
485     }
486
487     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
488     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
489                         0, "*other",
490                         1, "Other...",
491                         2, gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "stock_person", 64, 0, NULL),
492                         -1);
493 }
494
495 static void
496 connected_cb (LdmGreeter *greeter)
497 {
498     GdkWindow *root;
499     GdkDisplay *display;
500     GdkScreen *screen;
501     gint screen_width, screen_height;
502     GtkBuilder *builder;
503     GtkTreeModel *model;
504     const GList *items, *item;
505     GtkTreeIter iter;
506     GtkCellRenderer *renderer;
507     gchar *rc_file, *background_image;
508     GError *error = NULL;
509
510     display = gdk_display_get_default ();
511     screen = gdk_display_get_default_screen (display);
512     screen_width = gdk_screen_get_width (screen);
513     screen_height = gdk_screen_get_height (screen);
514
515     g_object_get (gtk_settings_get_default (), "gtk-theme-name", &theme_name, NULL);
516     rc_file = NULL; // FIXME
517     if (rc_file)
518     {
519         gchar *path = g_build_filename (GREETER_DATA_DIR, rc_file, NULL);
520         g_free (rc_file);
521         gtk_rc_add_default_file (path);
522         g_free (path);
523     }
524
525     builder = gtk_builder_new ();
526     if (!gtk_builder_add_from_file (builder, GREETER_DATA_DIR "/greeter.ui", &error))
527     {
528         g_warning ("Error loading UI: %s", error->message);
529         return;
530     }
531     g_clear_error (&error);
532     window = GTK_WIDGET (gtk_builder_get_object (builder, "greeter_window"));
533     prompt_box = GTK_WIDGET (gtk_builder_get_object (builder, "prompt_box"));
534     prompt_label = GTK_WIDGET (gtk_builder_get_object (builder, "prompt_label"));
535     prompt_entry = GTK_WIDGET (gtk_builder_get_object (builder, "prompt_entry"));
536     message_label = GTK_WIDGET (gtk_builder_get_object (builder, "message_label"));
537     session_combo = GTK_WIDGET (gtk_builder_get_object (builder, "session_combobox"));
538   
539     gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "hostname_label")), ldm_greeter_get_hostname (greeter));
540
541     background_image = NULL; // FIXME
542     if (background_image)
543     {
544         gchar *path;
545         GdkPixbuf *pixbuf;
546         GError *error = NULL;
547
548         path = g_build_filename (GREETER_DATA_DIR, background_image, NULL);
549         g_free (background_image);
550         pixbuf = gdk_pixbuf_new_from_file (path, &error);
551         if (!pixbuf)
552            g_warning ("Failed to load background: %s", error->message);
553         g_clear_error (&error);
554         g_free (path);
555
556         if (pixbuf)
557         {
558             background_pixbuf = gdk_pixbuf_scale_simple (pixbuf, screen_width, screen_height, GDK_INTERP_BILINEAR);
559             g_object_unref (pixbuf);
560         }
561     }
562
563     /* Set the background */
564     root = gdk_get_default_root_window ();
565     gdk_window_set_cursor (root, gdk_cursor_new (GDK_LEFT_PTR));
566     if (background_pixbuf)
567     {
568         GdkPixmap *pixmap;
569
570         gdk_pixbuf_render_pixmap_and_mask_for_colormap (background_pixbuf, gdk_window_get_colormap (root), &pixmap, NULL, 0);
571         gdk_window_set_back_pixmap (root, pixmap, FALSE);
572     }
573
574     if (!ldm_greeter_get_can_suspend (greeter))
575         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "suspend_menuitem")));
576     if (!ldm_greeter_get_can_hibernate (greeter))
577         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "hibernate_menuitem")));
578     if (!ldm_greeter_get_can_restart (greeter))
579         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "restart_menuitem")));
580     if (!ldm_greeter_get_can_shutdown (greeter))
581         gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "shutdown_menuitem")));
582
583     user_view = GTK_WIDGET (gtk_builder_get_object (builder, "user_treeview"));
584     gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (user_view), 0, "Face", gtk_cell_renderer_pixbuf_new(), "pixbuf", 2, NULL);
585     gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (user_view), 1, "Name", gtk_cell_renderer_text_new(), "text", 1, NULL);
586
587     if (ldm_greeter_get_hide_users_hint (greeter))
588         ldm_greeter_login_with_user_prompt (greeter);
589     else
590     {
591         load_user_list ();
592         gtk_widget_show (user_view);
593     }
594   
595     // FIXME: Select the requested user if ldm_greeter_get_timed_login_user () && ldm_greeter_get_timed_login_delay () == 0
596
597     renderer = gtk_cell_renderer_text_new();
598     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (session_combo), renderer, TRUE);
599     gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (session_combo), renderer, "text", 0);
600     model = gtk_combo_box_get_model (GTK_COMBO_BOX (session_combo));
601     items = ldm_greeter_get_sessions (greeter);
602     for (item = items; item; item = item->next)
603     {
604         LdmSession *session = item->data;
605
606         gtk_list_store_append (GTK_LIST_STORE (model), &iter);
607         gtk_list_store_set (GTK_LIST_STORE (model), &iter,
608                             0, ldm_session_get_name (session),
609                             1, ldm_session_get_key (session),
610                             -1);
611     }
612     set_session (ldm_greeter_get_default_session_hint (greeter));
613
614     gtk_window_set_default_size (GTK_WINDOW (window), screen_width, screen_height);
615     gtk_builder_connect_signals(builder, greeter);
616     gtk_widget_show (window);
617
618     gtk_widget_grab_focus (user_view);
619 }
620
621 int
622 main(int argc, char **argv)
623 {
624     /* Disable global menus */
625     unsetenv ("UBUNTU_MENUPROXY");
626
627     signal (SIGTERM, sigterm_cb);
628   
629     g_type_init ();
630
631     greeter = ldm_greeter_new ();
632     g_signal_connect (G_OBJECT (greeter), "connected", G_CALLBACK (connected_cb), NULL);
633     g_signal_connect (G_OBJECT (greeter), "show-prompt", G_CALLBACK (show_prompt_cb), NULL);  
634     g_signal_connect (G_OBJECT (greeter), "show-message", G_CALLBACK (show_message_cb), NULL);
635     g_signal_connect (G_OBJECT (greeter), "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
636     g_signal_connect (G_OBJECT (greeter), "autologin-timer-expired", G_CALLBACK (autologin_timer_expired_cb), NULL);
637     g_signal_connect (G_OBJECT (greeter), "user-removed", G_CALLBACK (user_removed_cb), NULL);
638     g_signal_connect (G_OBJECT (greeter), "quit", G_CALLBACK (quit_cb), NULL);
639     ldm_greeter_connect_to_server (greeter);
640
641     gtk_init (&argc, &argv);
642
643     gtk_main ();
644
645     return 0;
646 }