File gnome-screensaver-finger-print.patch of Package gnome-screensaver

Index: configure.ac
===================================================================
--- configure.ac.orig
+++ configure.ac
@@ -677,6 +677,21 @@ if test "x$have_libgnomekbdui" = "xyes";
 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 ---------------------------------------------------------------------------
 
Index: src/gnome-screensaver-dialog.c
===================================================================
--- src/gnome-screensaver-dialog.c.orig
+++ src/gnome-screensaver-dialog.c
@@ -31,6 +31,11 @@
 #include <unistd.h>
 #include <signal.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>
@@ -74,6 +79,12 @@ static GOptionEntry entries [] = {
         { 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)
 {
@@ -360,12 +371,118 @@ quit_timeout_cb (gpointer data)
         return FALSE;
 }
 
+#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);
@@ -568,6 +685,22 @@ lock_initialization (int     *argc,
         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)
@@ -587,6 +720,34 @@ main (int    argc,
                 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);
@@ -599,7 +760,7 @@ 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);
@@ -644,6 +805,14 @@ main (int    argc,
         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 ();
 
Index: src/Makefile.am
===================================================================
--- src/Makefile.am.orig
+++ src/Makefile.am
@@ -29,6 +29,7 @@ INCLUDES =							\
 	$(LIBGNOMEKBDUI_CFLAGS)					\
 	$(LIBNOTIFY_CFLAGS)					\
 	$(SYSTEMD_CFLAGS)					\
+	$(LIBFPRINT_CFLAGS)					\
 	$(NULL)
 
 bin_PROGRAMS = \
@@ -154,6 +155,7 @@ gnome_screensaver_dialog_LDADD =	\
 	$(AUTH_LIBS)			\
 	$(LIBGNOMEKBDUI_LIBS)		\
 	$(LIBNOTIFY_LIBS)		\
+	$(LIBFPRINT_LIBS)		\
 	$(NULL)
 
 BUILT_SOURCES = 		\