Index: configure.ac
===================================================================
--- configure.ac.orig
+++ configure.ac
@@ -915,10 +915,25 @@ if test "x$have_libnotify" = "xyes"; the
   AC_SUBST(LIBNOTIFY_LIBS)
   AC_DEFINE(WITH_LIBNOTIFY, 1, [Define for libnotify support])
 fi
 
 dnl ---------------------------------------------------------------------------
+dnl libfprint
+dnl ---------------------------------------------------------------------------
+
+have_libfprint=yes
+AC_ARG_WITH(libfprint,[  --without-libfprint         disable finger print support])
+if test x$with_libfprint != xno; then
+	PKG_CHECK_MODULES(LIBFPRINT, libfprint, have_libfprint=yes, have_libfprint=no)
+fi
+if test "x$have_libfprint" = "xyes"; then
+  AC_SUBST(LIBFPRINT_CFLAGS)
+  AC_SUBST(LIBFPRINT_LIBS)
+  AC_DEFINE(WITH_LIBFPRINT, 1, [Define for finger print support])
+fi
+
+dnl ---------------------------------------------------------------------------
 dnl Finish
 dnl ---------------------------------------------------------------------------
 
 AC_SUBST(AUTH_LIBS)
 AC_SUBST(SAVER_LIBS)
Index: src/gnome-screensaver-dialog.c
===================================================================
--- src/gnome-screensaver-dialog.c.orig
+++ src/gnome-screensaver-dialog.c
@@ -28,10 +28,15 @@
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
+#ifdef WITH_LIBFPRINT
+#include <pthread.h>
+#include <signal.h>
+#include <libfprint/fprint.h>
+#endif
 #include <glib/gi18n.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 
 #include "gs-lock-plug.h"
@@ -64,10 +69,16 @@ static GOptionEntry entries [] = {
         { "away-message", 0, 0, G_OPTION_ARG_STRING, &away_message,
           N_("Message to show in the dialog"), N_("MESSAGE") },
         { NULL }
 };
 
+#ifdef WITH_LIBFPRINT
+static struct fp_dscv_dev *fp_ddev, **fp_discovered_devs;
+static struct fp_dev *fp_dev;
+static struct fp_print_data *fp_data;
+#endif
+
 static char *
 get_id_string (GtkWidget *widget)
 {
         char *id = NULL;
 
@@ -331,16 +342,122 @@ response_cb (GSLockPlug *plug,
             (response_id == GTK_RESPONSE_DELETE_EVENT)) {
                 quit_response_cancel ();
         }
 }
 
+#ifdef WITH_LIBFPRINT
+typedef struct {
+        gchar *message;
+        GSLockPlug *plug;
+} AuthMessageHandlerIdleData;
+
+static gboolean
+auth_message_handler_idle_cb (AuthMessageHandlerIdleData *idle_data)
+{
+        char *response;
+
+        auth_message_handler (GS_AUTH_MESSAGE_TEXT_INFO,
+                              idle_data->message,
+                              &response,
+                              idle_data->plug);
+
+        g_free (idle_data->message);
+        g_free (idle_data);
+
+        return FALSE;
+}
+
+static void
+auth_message_handler_idle (const gchar *message, GSLockPlug *plug)
+{
+        AuthMessageHandlerIdleData *idle_data;
+
+        idle_data = g_new0 (AuthMessageHandlerIdleData, 1);
+        idle_data->message = g_strdup (message);
+        idle_data->plug = plug;
+
+        g_idle_add ((GSourceFunc) auth_message_handler_idle_cb, idle_data);
+}
+
+static gpointer
+fprint_thread_func (gpointer user_data)
+{
+        GSLockPlug *plug = (GSLockPlug *) user_data;
+
+        if (fp_dev && fp_data) {
+                gboolean result = FALSE;
+                gboolean retry;
+                struct fp_img *img = NULL;
+
+                auth_message_handler_idle (_("Please enter password or swipe your finger"), plug);
+
+                do {
+                        int r;
+
+                        retry = FALSE;
+
+                        r = fp_verify_finger_img (fp_dev, fp_data, &img);
+                        fp_img_free (img);
+
+                        switch (r) {
+                        case FP_VERIFY_NO_MATCH :
+                                retry = TRUE;
+                                break;
+                        case FP_VERIFY_MATCH :
+                                result = TRUE;
+                                break;
+                        case FP_VERIFY_RETRY :
+                                retry = TRUE;
+                                auth_message_handler_idle (_("Scan didn't quite work. Please try again"),
+                                                           plug);
+                                break;
+                        case FP_VERIFY_RETRY_TOO_SHORT :
+                                retry = TRUE;
+                                auth_message_handler_idle (_("Swipe was too short. Please try again"),
+                                                           plug);
+                                break;
+                        case FP_VERIFY_RETRY_CENTER_FINGER :
+                                retry = TRUE;
+                                auth_message_handler_idle (_("Please center your finger on the sensor and try again"),
+                                                           plug);
+                                break;
+                        case FP_VERIFY_RETRY_REMOVE_FINGER :
+                                retry = TRUE;
+                                auth_message_handler_idle (_("Please remove finger from the sensor and try again"),
+                                                           plug);
+                                break;
+                        default :
+                                retry = TRUE;
+                                g_debug ("Finger print verification failed with error: %d", r);
+                                break;
+                        }
+                } while (retry);
+
+                if (result) {
+                        g_idle_add ((GSourceFunc) quit_response_ok, NULL);
+                }
+        }
+
+        return NULL;
+}
+#endif
+
 static gboolean
 auth_check_idle (GSLockPlug *plug)
 {
         gboolean     res;
         gboolean     again;
         static guint loop_counter = 0;
+#ifdef WITH_LIBFPRINT
+        static pthread_t fprint_thread = -1;
+
+        if (fp_dev && fp_data && fprint_thread == -1) {
+                if (pthread_create (&fprint_thread, NULL, fprint_thread_func, plug)) {
+                        gs_debug ("Thread creation for finger print auth failed");
+                }
+        }
+#endif
 
         again = TRUE;
         res = do_auth_check (plug);
 
         if (res) {
@@ -527,10 +644,26 @@ lock_initialization (int     *argc,
 #endif /* NO_LOCKING */
 
         return TRUE;
 }
 
+#ifdef WITH_LIBFPRINT
+static struct fp_dscv_dev
+*discover_fingerprint_device (struct fp_dscv_dev **discovered_devs)
+{
+        struct fp_dscv_dev *ddev = discovered_devs[0];
+	struct fp_driver *drv;
+	if (!ddev)
+		return NULL;
+
+	drv = fp_dscv_dev_get_driver (ddev);
+	g_debug ("Found device claimed by %s driver\n", fp_driver_get_full_name (drv));
+
+	return ddev;
+}
+#endif
+
 int
 main (int    argc,
       char **argv)
 {
         GError *error = NULL;
@@ -546,10 +679,38 @@ main (int    argc,
 
         if (! g_thread_supported ()) {
                 g_thread_init (NULL);
         }
 
+#ifdef WITH_LIBFPRINT
+        /* Initialize fprint for fingerprint reading for authentication */
+        if (fp_init () < 0) {
+		g_debug ("Failed to initialize libfprint");
+        } else {
+		fp_data = NULL;
+		fp_discovered_devs = fp_discover_devs ();
+		if (fp_discovered_devs) {
+			fp_ddev = discover_fingerprint_device (fp_discovered_devs);
+			if (fp_ddev) {
+				fp_dev = fp_dev_open (fp_ddev);
+				if (fp_dev) {
+					if (fp_print_data_load (fp_dev, RIGHT_INDEX, &fp_data) == 0) {
+					} else {
+						g_debug ("Failed to load fingerprint");
+						g_debug ("Did you remember to enroll your right index finger first?");
+					}
+				} else
+					g_debug ("Could not open fingerprint device");
+			} else
+				g_debug ("No fingerprint devices detected");
+
+			fp_dscv_devs_free (fp_discovered_devs);
+		} else
+			g_debug ("Could not discover fingerprint devices");
+	}
+#endif
+
         g_type_init ();
 
         gs_profile_start (NULL);
 
         if (! privileged_initialization (&argc, argv, verbose)) {
@@ -558,11 +719,11 @@ main (int    argc,
         }
 
         error = NULL;
         if (! gtk_init_with_args (&argc, &argv, NULL, entries, NULL, &error)) {
                 if (error != NULL) {
-                        fprintf (stderr, "%s", error->message);
+                        g_debug ("%s", error->message);
                         g_error_free (error);
                 }
                 exit (1);
         }
 
@@ -601,10 +762,18 @@ main (int    argc,
         gtk_main ();
 
         if (xvkbd_running)
                 kill (xvkbd_pid, 9);
 
+#ifdef WITH_LIBFPRINT
+        fp_print_data_free (fp_data);
+        if (fp_dev)
+                fp_dev_close (fp_dev);
+
+        fp_exit ();
+#endif
+
         gs_profile_end (NULL);
         gs_debug_shutdown ();
 
         return 0;
 }
Index: src/Makefile.am
===================================================================
--- src/Makefile.am.orig
+++ src/Makefile.am
@@ -29,10 +29,11 @@ INCLUDES =							\
 	$(AUTH_CFLAGS)						\
 	$(DEBUG_CFLAGS)						\
 	$(DBUS_CFLAGS)						\
 	$(LIBGNOMEKBDUI_CFLAGS)					\
 	$(LIBNOTIFY_CFLAGS)					\
+	$(LIBFPRINT_CFLAGS)					\
 	$(NULL)
 
 bin_PROGRAMS = \
 	gnome-screensaver		\
 	gnome-screensaver-command	\
@@ -148,10 +149,11 @@ gnome_screensaver_dialog_LDADD =	\
 	$(GNOME_SCREENSAVER_DIALOG_LIBS)\
 	$(SAVER_LIBS)			\
 	$(AUTH_LIBS)			\
 	$(LIBGNOMEKBDUI_LIBS)		\
 	$(LIBNOTIFY_LIBS)		\
+	$(LIBFPRINT_LIBS)		\
 	$(NULL)
 
 BUILT_SOURCES = 		\
 	gs-marshal.c 		\
 	gs-marshal.h		\
