780 lines
28 KiB
C
780 lines
28 KiB
C
/* gnome-about-me-fingerprint.h
|
|
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <glib/gi18n.h>
|
|
#include <gio/gio.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "um-fingerprint-dialog.h"
|
|
|
|
#include "fingerprint-strings.h"
|
|
|
|
/* Retrieve a widget from the UI object */
|
|
#define WID(s) GTK_WIDGET (gtk_builder_get_object (dialog, s))
|
|
|
|
/* Translate fprintd strings */
|
|
#define TR(s) dgettext("fprintd", s)
|
|
|
|
/* This must match the number of images on the 2nd page in the UI file */
|
|
#define MAX_ENROLL_STAGES 5
|
|
|
|
static GDBusProxy *manager = NULL;
|
|
static GDBusConnection *connection = NULL;
|
|
static gboolean is_disable = FALSE;
|
|
|
|
enum {
|
|
STATE_NONE,
|
|
STATE_CLAIMED,
|
|
STATE_ENROLLING
|
|
};
|
|
|
|
typedef struct {
|
|
GtkWidget *label1;
|
|
GtkWidget *label2;
|
|
|
|
GtkWidget *ass;
|
|
GtkBuilder *dialog;
|
|
|
|
GDBusProxy *device;
|
|
gboolean is_swipe;
|
|
int num_enroll_stages;
|
|
int num_stages_done;
|
|
char *name;
|
|
const char *finger;
|
|
gint state;
|
|
} EnrollData;
|
|
|
|
static void create_manager (void)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
|
if (connection == NULL) {
|
|
g_warning ("Failed to connect to session bus: %s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
manager = g_dbus_proxy_new_sync (connection,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"net.reactivated.Fprint",
|
|
"/net/reactivated/Fprint/Manager",
|
|
"net.reactivated.Fprint.Manager",
|
|
NULL,
|
|
&error);
|
|
if (manager == NULL) {
|
|
g_warning ("Failed to create fingerprint manager proxy: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
}
|
|
|
|
static GDBusProxy *
|
|
get_first_device (void)
|
|
{
|
|
GDBusProxy *device;
|
|
GVariant *result;
|
|
char *device_str = NULL;
|
|
GError *error = NULL;
|
|
|
|
result = g_dbus_proxy_call_sync (manager,
|
|
"GetDefaultDevice",
|
|
g_variant_new ("()"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
NULL,
|
|
NULL);
|
|
if (result == NULL)
|
|
return NULL;
|
|
if (!g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)")))
|
|
g_warning ("net.reactivated.Fprint.Manager.GetDefaultDevice returns unknown result %s", g_variant_get_type_string (result));
|
|
else
|
|
g_variant_get (result, "(o)", &device_str);
|
|
g_variant_unref (result);
|
|
|
|
if (device_str == NULL)
|
|
return NULL;
|
|
|
|
device = g_dbus_proxy_new_sync (connection,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"net.reactivated.Fprint",
|
|
device_str,
|
|
"net.reactivated.Fprint.Device",
|
|
NULL,
|
|
&error);
|
|
if (device == NULL) {
|
|
g_warning ("Failed to create fingerprint device proxy: %s", error->message);
|
|
g_error_free (error);
|
|
}
|
|
|
|
g_free (device_str);
|
|
|
|
return device;
|
|
}
|
|
|
|
static const char *
|
|
get_reason_for_error (const char *dbus_error)
|
|
{
|
|
if (g_str_equal (dbus_error, "net.reactivated.Fprint.Error.PermissionDenied"))
|
|
return N_("You are not allowed to access the device. Contact your system administrator.");
|
|
if (g_str_equal (dbus_error, "net.reactivated.Fprint.Error.AlreadyInUse"))
|
|
return N_("The device is already in use.");
|
|
if (g_str_equal (dbus_error, "net.reactivated.Fprint.Error.Internal"))
|
|
return N_("An internal error occurred.");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static GtkWidget *
|
|
get_error_dialog (const char *title,
|
|
const char *dbus_error,
|
|
GtkWindow *parent)
|
|
{
|
|
GtkWidget *error_dialog;
|
|
const char *reason;
|
|
|
|
if (dbus_error == NULL)
|
|
g_warning ("get_error_dialog called with reason == NULL");
|
|
|
|
error_dialog =
|
|
gtk_message_dialog_new (parent,
|
|
GTK_DIALOG_MODAL,
|
|
GTK_MESSAGE_ERROR,
|
|
GTK_BUTTONS_OK,
|
|
"%s", title);
|
|
reason = get_reason_for_error (dbus_error);
|
|
gtk_message_dialog_format_secondary_text
|
|
(GTK_MESSAGE_DIALOG (error_dialog), "%s", reason ? _(reason) : _(dbus_error));
|
|
|
|
gtk_window_set_title (GTK_WINDOW (error_dialog), ""); /* as per HIG */
|
|
gtk_container_set_border_width (GTK_CONTAINER (error_dialog), 5);
|
|
gtk_dialog_set_default_response (GTK_DIALOG (error_dialog),
|
|
GTK_RESPONSE_OK);
|
|
gtk_window_set_modal (GTK_WINDOW (error_dialog), TRUE);
|
|
gtk_window_set_position (GTK_WINDOW (error_dialog), GTK_WIN_POS_CENTER_ON_PARENT);
|
|
|
|
return error_dialog;
|
|
}
|
|
|
|
gboolean
|
|
set_fingerprint_label (GtkWidget *label1,
|
|
GtkWidget *label2)
|
|
{
|
|
GDBusProxy *device;
|
|
GVariant *result;
|
|
GVariantIter *fingers;
|
|
GError *error = NULL;
|
|
|
|
if (manager == NULL) {
|
|
create_manager ();
|
|
if (manager == NULL) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
device = get_first_device ();
|
|
if (device == NULL)
|
|
return FALSE;
|
|
|
|
result = g_dbus_proxy_call_sync (device, "ListEnrolledFingers", g_variant_new ("(s)", ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
|
|
if (!result) {
|
|
if (!g_dbus_error_is_remote_error (error) ||
|
|
strcmp (g_dbus_error_get_remote_error(error), "net.reactivated.Fprint.Error.NoEnrolledPrints") != 0) {
|
|
g_object_unref (device);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (result && g_variant_is_of_type (result, G_VARIANT_TYPE ("(as)")))
|
|
g_variant_get (result, "(as)", &fingers);
|
|
else
|
|
fingers = NULL;
|
|
|
|
if (fingers == NULL || g_variant_iter_n_children (fingers) == 0) {
|
|
is_disable = FALSE;
|
|
gtk_label_set_text (GTK_LABEL (label1), _("Disabled"));
|
|
gtk_label_set_text (GTK_LABEL (label2), _("Disabled"));
|
|
} else {
|
|
is_disable = TRUE;
|
|
gtk_label_set_text (GTK_LABEL (label1), _("Enabled"));
|
|
gtk_label_set_text (GTK_LABEL (label2), _("Enabled"));
|
|
}
|
|
|
|
if (result != NULL)
|
|
g_variant_unref (result);
|
|
if (fingers != NULL)
|
|
g_variant_iter_free (fingers);
|
|
g_object_unref (device);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
delete_fingerprints (void)
|
|
{
|
|
GDBusProxy *device;
|
|
GVariant *result;
|
|
|
|
if (manager == NULL) {
|
|
create_manager ();
|
|
if (manager == NULL)
|
|
return;
|
|
}
|
|
|
|
device = get_first_device ();
|
|
if (device == NULL)
|
|
return;
|
|
|
|
result = g_dbus_proxy_call_sync (device, "DeleteEnrolledFingers", g_variant_new ("(s)", ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL);
|
|
if (result)
|
|
g_variant_unref (result);
|
|
|
|
g_object_unref (device);
|
|
}
|
|
|
|
static void
|
|
delete_fingerprints_question (GtkWindow *parent,
|
|
GtkWidget *label1,
|
|
GtkWidget *label2,
|
|
UmUser *user)
|
|
{
|
|
GtkWidget *question;
|
|
GtkWidget *button;
|
|
|
|
question = gtk_message_dialog_new (parent,
|
|
GTK_DIALOG_MODAL,
|
|
GTK_MESSAGE_QUESTION,
|
|
GTK_BUTTONS_NONE,
|
|
_("Delete registered fingerprints?"));
|
|
gtk_dialog_add_button (GTK_DIALOG (question), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
|
|
gtk_window_set_modal (GTK_WINDOW (question), TRUE);
|
|
|
|
button = gtk_button_new_with_mnemonic (_("_Delete Fingerprints"));
|
|
gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
|
|
gtk_widget_set_can_default (button, TRUE);
|
|
gtk_widget_show (button);
|
|
gtk_dialog_add_action_widget (GTK_DIALOG (question), button, GTK_RESPONSE_OK);
|
|
|
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (question),
|
|
_("Do you want to delete your registered fingerprints so fingerprint login is disabled?"));
|
|
gtk_container_set_border_width (GTK_CONTAINER (question), 5);
|
|
gtk_dialog_set_default_response (GTK_DIALOG (question), GTK_RESPONSE_OK);
|
|
gtk_window_set_position (GTK_WINDOW (question), GTK_WIN_POS_CENTER_ON_PARENT);
|
|
gtk_window_set_modal (GTK_WINDOW (question), TRUE);
|
|
|
|
if (gtk_dialog_run (GTK_DIALOG (question)) == GTK_RESPONSE_OK) {
|
|
delete_fingerprints ();
|
|
set_fingerprint_label (label1, label2);
|
|
}
|
|
|
|
gtk_widget_destroy (question);
|
|
}
|
|
|
|
static gboolean
|
|
enroll_start (EnrollData *data, GError **error)
|
|
{
|
|
GVariant *result;
|
|
|
|
result = g_dbus_proxy_call_sync (data->device, "EnrollStart", g_variant_new ("(s)", data->finger), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
|
|
if (result == NULL)
|
|
return FALSE;
|
|
g_variant_unref (result);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
enroll_stop (EnrollData *data, GError **error)
|
|
{
|
|
GVariant *result;
|
|
|
|
result = g_dbus_proxy_call_sync (data->device, "EnrollStop", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
|
|
if (result == NULL)
|
|
return FALSE;
|
|
g_variant_unref (result);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
claim (EnrollData *data, GError **error)
|
|
{
|
|
GVariant *result;
|
|
|
|
result = g_dbus_proxy_call_sync (data->device, "Claim", g_variant_new ("(s)", ""), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
|
|
if (result == NULL)
|
|
return FALSE;
|
|
g_variant_unref (result);
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
release (EnrollData *data, GError **error)
|
|
{
|
|
GVariant *result;
|
|
|
|
result = g_dbus_proxy_call_sync (data->device, "Release", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
|
|
if (result == NULL)
|
|
return FALSE;
|
|
g_variant_unref (result);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
enroll_data_destroy (EnrollData *data)
|
|
{
|
|
switch (data->state) {
|
|
case STATE_ENROLLING:
|
|
enroll_stop (data, NULL);
|
|
/* fall-through */
|
|
case STATE_CLAIMED:
|
|
release (data, NULL);
|
|
/* fall-through */
|
|
case STATE_NONE:
|
|
g_free (data->name);
|
|
g_object_unref (data->device);
|
|
g_object_unref (data->dialog);
|
|
gtk_widget_destroy (data->ass);
|
|
|
|
g_free (data);
|
|
}
|
|
}
|
|
|
|
static const char *
|
|
selected_finger (GtkBuilder *dialog)
|
|
{
|
|
int index;
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("radiobutton1")))) {
|
|
gtk_widget_set_sensitive (WID ("finger_combobox"), FALSE);
|
|
return "right-index-finger";
|
|
}
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("radiobutton2")))) {
|
|
gtk_widget_set_sensitive (WID ("finger_combobox"), FALSE);
|
|
return "left-index-finger";
|
|
}
|
|
gtk_widget_set_sensitive (WID ("finger_combobox"), TRUE);
|
|
index = gtk_combo_box_get_active (GTK_COMBO_BOX (WID ("finger_combobox")));
|
|
switch (index) {
|
|
case 0:
|
|
return "left-thumb";
|
|
case 1:
|
|
return "left-middle-finger";
|
|
case 2:
|
|
return "left-ring-finger";
|
|
case 3:
|
|
return "left-little-finger";
|
|
case 4:
|
|
return "right-thumb";
|
|
case 5:
|
|
return "right-middle-finger";
|
|
case 6:
|
|
return "right-ring-finger";
|
|
case 7:
|
|
return "right-little-finger";
|
|
default:
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
finger_radio_button_toggled (GtkToggleButton *button, EnrollData *data)
|
|
{
|
|
GtkBuilder *dialog = data->dialog;
|
|
char *msg;
|
|
|
|
data->finger = selected_finger (data->dialog);
|
|
|
|
msg = g_strdup_printf (TR(finger_str_to_msg (data->finger, data->is_swipe)), data->name);
|
|
gtk_label_set_text (GTK_LABEL (WID("enroll-label")), msg);
|
|
g_free (msg);
|
|
}
|
|
|
|
static void
|
|
finger_combobox_changed (GtkComboBox *combobox, EnrollData *data)
|
|
{
|
|
GtkBuilder *dialog = data->dialog;
|
|
char *msg;
|
|
|
|
data->finger = selected_finger (data->dialog);
|
|
|
|
msg = g_strdup_printf (TR(finger_str_to_msg (data->finger, data->is_swipe)), data->name);
|
|
gtk_label_set_text (GTK_LABEL (WID("enroll-label")), msg);
|
|
g_free (msg);
|
|
}
|
|
|
|
static void
|
|
assistant_cancelled (GtkAssistant *ass, EnrollData *data)
|
|
{
|
|
GtkWidget *label1, *label2;
|
|
|
|
label1 = data->label1;
|
|
label2 = data->label2;
|
|
|
|
enroll_data_destroy (data);
|
|
set_fingerprint_label (label1, label2);
|
|
}
|
|
|
|
static void
|
|
enroll_result (EnrollData *data, const char *result, gboolean done)
|
|
{
|
|
GtkBuilder *dialog = data->dialog;
|
|
char *msg;
|
|
|
|
if (g_str_equal (result, "enroll-completed") || g_str_equal (result, "enroll-stage-passed")) {
|
|
char *name, *path;
|
|
|
|
data->num_stages_done++;
|
|
name = g_strdup_printf ("image%d", data->num_stages_done);
|
|
path = g_build_filename (UM_PIXMAP_DIR, "print_ok.png", NULL);
|
|
gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
|
|
g_free (name);
|
|
g_free (path);
|
|
}
|
|
if (g_str_equal (result, "enroll-completed")) {
|
|
gtk_label_set_text (GTK_LABEL (WID ("status-label")), _("Done!"));
|
|
gtk_label_set_text (GTK_LABEL (WID("enroll-label")), "");
|
|
gtk_assistant_set_page_complete (GTK_ASSISTANT (data->ass), WID ("page2"), TRUE);
|
|
}
|
|
|
|
if (done != FALSE) {
|
|
enroll_stop (data, NULL);
|
|
data->state = STATE_CLAIMED;
|
|
if (g_str_equal (result, "enroll-completed") == FALSE) {
|
|
/* The enrollment failed, restart it */
|
|
enroll_start (data, NULL);
|
|
data->state = STATE_ENROLLING;
|
|
result = "enroll-retry-scan";
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
msg = g_strdup_printf (TR(enroll_result_str_to_msg (result, data->is_swipe)), data->name);
|
|
gtk_label_set_text (GTK_LABEL (WID ("status-label")), msg);
|
|
g_free (msg);
|
|
}
|
|
|
|
static void
|
|
device_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, EnrollData *data)
|
|
{
|
|
if (strcmp (signal_name, "EnrollStatus") == 0) {
|
|
if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sb)"))) {
|
|
gchar *result;
|
|
gboolean done;
|
|
|
|
g_variant_get (parameters, "(&sb)", &result, &done);
|
|
enroll_result (data, result, done);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
assistant_prepare (GtkAssistant *ass, GtkWidget *page, EnrollData *data)
|
|
{
|
|
const char *name;
|
|
|
|
name = g_object_get_data (G_OBJECT (page), "name");
|
|
if (name == NULL)
|
|
return;
|
|
|
|
if (g_str_equal (name, "enroll")) {
|
|
GError *error = NULL;
|
|
GtkBuilder *dialog = data->dialog;
|
|
char *path;
|
|
guint i;
|
|
GVariant *result;
|
|
gint num_enroll_stages;
|
|
|
|
if (!claim (data, &error)) {
|
|
GtkWidget *d;
|
|
char *msg;
|
|
|
|
/* translators:
|
|
* The variable is the name of the device, for example:
|
|
* "Could you not access "Digital Persona U.are.U 4000/4000B" device */
|
|
msg = g_strdup_printf (_("Could not access '%s' device"), data->name);
|
|
d = get_error_dialog (msg, error->message, GTK_WINDOW (data->ass));
|
|
g_error_free (error);
|
|
gtk_dialog_run (GTK_DIALOG (d));
|
|
gtk_widget_destroy (d);
|
|
g_free (msg);
|
|
|
|
enroll_data_destroy (data);
|
|
|
|
return;
|
|
}
|
|
data->state = STATE_CLAIMED;
|
|
|
|
result = g_dbus_connection_call_sync (connection,
|
|
"net.reactivated.Fprint",
|
|
g_dbus_proxy_get_object_path (data->device),
|
|
"org.freedesktop.DBus.Properties",
|
|
"Get",
|
|
g_variant_new ("(ss)", "net.reactivated.Fprint.Device", "num-enroll-stages"),
|
|
G_VARIANT_TYPE ("(v)"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
NULL,
|
|
&error);
|
|
num_enroll_stages = 0;
|
|
if (result) {
|
|
GVariant *v;
|
|
|
|
g_variant_get (result, "(v)", &v);
|
|
num_enroll_stages = g_variant_get_int32 (v);
|
|
|
|
g_variant_unref (result);
|
|
g_variant_unref (v);
|
|
}
|
|
|
|
if (num_enroll_stages < 1) {
|
|
GtkWidget *d;
|
|
char *msg;
|
|
|
|
/* translators:
|
|
* The variable is the name of the device, for example:
|
|
* "Could you not access "Digital Persona U.are.U 4000/4000B" device */
|
|
msg = g_strdup_printf (_("Could not access '%s' device"), data->name);
|
|
d = get_error_dialog (msg, "net.reactivated.Fprint.Error.Internal", GTK_WINDOW (data->ass));
|
|
gtk_dialog_run (GTK_DIALOG (d));
|
|
gtk_widget_destroy (d);
|
|
g_free (msg);
|
|
|
|
enroll_data_destroy (data);
|
|
return;
|
|
}
|
|
|
|
data->num_enroll_stages = num_enroll_stages;
|
|
|
|
/* Hide the extra "bulbs" if not needed */
|
|
for (i = MAX_ENROLL_STAGES; i > data->num_enroll_stages; i--) {
|
|
char *name;
|
|
|
|
name = g_strdup_printf ("image%d", i);
|
|
gtk_widget_hide (WID (name));
|
|
g_free (name);
|
|
}
|
|
/* And set the right image */
|
|
{
|
|
char *filename;
|
|
|
|
filename = g_strdup_printf ("%s.png", data->finger);
|
|
path = g_build_filename (UM_PIXMAP_DIR, filename, NULL);
|
|
g_free (filename);
|
|
}
|
|
for (i = 1; i <= data->num_enroll_stages; i++) {
|
|
char *name;
|
|
name = g_strdup_printf ("image%d", i);
|
|
gtk_image_set_from_file (GTK_IMAGE (WID (name)), path);
|
|
g_free (name);
|
|
}
|
|
g_free (path);
|
|
|
|
g_signal_connect (data->device, "g-signal", G_CALLBACK (device_signal_cb), data);
|
|
|
|
if (!enroll_start (data, &error)) {
|
|
GtkWidget *d;
|
|
char *msg;
|
|
|
|
/* translators:
|
|
* The variable is the name of the device, for example:
|
|
* "Could you not access "Digital Persona U.are.U 4000/4000B" device */
|
|
msg = g_strdup_printf (_("Could not start finger capture on '%s' device"), data->name);
|
|
d = get_error_dialog (msg, error->message, GTK_WINDOW (data->ass));
|
|
g_error_free (error);
|
|
gtk_dialog_run (GTK_DIALOG (d));
|
|
gtk_widget_destroy (d);
|
|
g_free (msg);
|
|
|
|
enroll_data_destroy (data);
|
|
|
|
return;
|
|
}
|
|
data->state = STATE_ENROLLING;;
|
|
} else {
|
|
if (data->state == STATE_ENROLLING) {
|
|
enroll_stop (data, NULL);
|
|
data->state = STATE_CLAIMED;
|
|
}
|
|
if (data->state == STATE_CLAIMED) {
|
|
release (data, NULL);
|
|
data->state = STATE_NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
enroll_fingerprints (GtkWindow *parent,
|
|
GtkWidget *label1,
|
|
GtkWidget *label2,
|
|
UmUser *user)
|
|
{
|
|
GDBusProxy *device;
|
|
GtkBuilder *dialog;
|
|
EnrollData *data;
|
|
GtkWidget *ass;
|
|
const char *filename;
|
|
char *msg;
|
|
GVariant *result;
|
|
GError *error = NULL;
|
|
|
|
device = NULL;
|
|
|
|
if (manager == NULL) {
|
|
create_manager ();
|
|
if (manager != NULL)
|
|
device = get_first_device ();
|
|
} else {
|
|
device = get_first_device ();
|
|
}
|
|
|
|
if (manager == NULL || device == NULL) {
|
|
GtkWidget *d;
|
|
|
|
d = get_error_dialog (_("Could not access any fingerprint readers"),
|
|
_("Please contact your system administrator for help."),
|
|
parent);
|
|
gtk_dialog_run (GTK_DIALOG (d));
|
|
gtk_widget_destroy (d);
|
|
return;
|
|
}
|
|
|
|
data = g_new0 (EnrollData, 1);
|
|
data->device = device;
|
|
data->label1 = label1;
|
|
data->label2 = label2;
|
|
|
|
/* Get some details about the device */
|
|
result = g_dbus_connection_call_sync (connection,
|
|
"net.reactivated.Fprint",
|
|
g_dbus_proxy_get_object_path (data->device),
|
|
"org.freedesktop.DBus.Properties",
|
|
"GetAll",
|
|
g_variant_new ("(s)", "net.reactivated.Fprint.Device"),
|
|
G_VARIANT_TYPE ("(a{sv})"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
NULL,
|
|
NULL);
|
|
if (result) {
|
|
GVariant *props;
|
|
gchar *scan_type;
|
|
|
|
g_variant_get (result, "(@a{sv})", &props);
|
|
g_variant_lookup (props, "name", "s", &data->name);
|
|
g_variant_lookup (props, "scan-type", "s", &scan_type);
|
|
if (g_strcmp0 (scan_type, "swipe") == 0)
|
|
data->is_swipe = TRUE;
|
|
g_free (scan_type);
|
|
g_variant_unref (props);
|
|
g_variant_unref (result);
|
|
}
|
|
|
|
dialog = gtk_builder_new ();
|
|
filename = UIDIR "/account-fingerprint.ui";
|
|
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
|
filename = "data/account-fingerprint.ui";
|
|
if (!gtk_builder_add_from_file (dialog, filename, &error)) {
|
|
g_error ("%s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
data->dialog = dialog;
|
|
|
|
ass = WID ("assistant");
|
|
gtk_window_set_title (GTK_WINDOW (ass), _("Enable Fingerprint Login"));
|
|
gtk_window_set_transient_for (GTK_WINDOW (ass), parent);
|
|
gtk_window_set_modal (GTK_WINDOW (ass), TRUE);
|
|
gtk_window_set_resizable (GTK_WINDOW (ass), FALSE);
|
|
gtk_window_set_type_hint (GTK_WINDOW (ass), GDK_WINDOW_TYPE_HINT_DIALOG);
|
|
|
|
g_signal_connect (G_OBJECT (ass), "cancel",
|
|
G_CALLBACK (assistant_cancelled), data);
|
|
g_signal_connect (G_OBJECT (ass), "close",
|
|
G_CALLBACK (assistant_cancelled), data);
|
|
g_signal_connect (G_OBJECT (ass), "prepare",
|
|
G_CALLBACK (assistant_prepare), data);
|
|
|
|
/* Page 1 */
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (WID ("finger_combobox")), 0);
|
|
|
|
g_signal_connect (G_OBJECT (WID ("radiobutton1")), "toggled",
|
|
G_CALLBACK (finger_radio_button_toggled), data);
|
|
g_signal_connect (G_OBJECT (WID ("radiobutton2")), "toggled",
|
|
G_CALLBACK (finger_radio_button_toggled), data);
|
|
g_signal_connect (G_OBJECT (WID ("radiobutton3")), "toggled",
|
|
G_CALLBACK (finger_radio_button_toggled), data);
|
|
g_signal_connect (G_OBJECT (WID ("finger_combobox")), "changed",
|
|
G_CALLBACK (finger_combobox_changed), data);
|
|
|
|
data->finger = selected_finger (dialog);
|
|
|
|
g_object_set_data (G_OBJECT (WID("page1")), "name", "intro");
|
|
|
|
/* translators:
|
|
* The variable is the name of the device, for example:
|
|
* "To enable fingerprint login, you need to save one of your fingerprints, using the
|
|
* 'Digital Persona U.are.U 4000/4000B' device."
|
|
*/
|
|
msg = g_strdup_printf (_("To enable fingerprint login, you need to save one of your fingerprints, using the '%s' device."),
|
|
data->name);
|
|
gtk_label_set_text (GTK_LABEL (WID("intro-label")), msg);
|
|
g_free (msg);
|
|
|
|
gtk_assistant_set_page_complete (GTK_ASSISTANT (ass), WID("page1"), TRUE);
|
|
|
|
gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page1"), _("Selecting finger"));
|
|
gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page2"), _("Enrolling fingerprints"));
|
|
gtk_assistant_set_page_title (GTK_ASSISTANT (ass), WID("page3"), _("Summary"));
|
|
|
|
/* Page 2 */
|
|
g_object_set_data (G_OBJECT (WID("page2")), "name", "enroll");
|
|
|
|
msg = g_strdup_printf (TR(finger_str_to_msg (data->finger, data->is_swipe)), data->name);
|
|
gtk_label_set_text (GTK_LABEL (WID("enroll-label")), msg);
|
|
g_free (msg);
|
|
|
|
/* Page 3 */
|
|
g_object_set_data (G_OBJECT (WID("page3")), "name", "summary");
|
|
|
|
data->ass = ass;
|
|
gtk_widget_show_all (ass);
|
|
}
|
|
|
|
void
|
|
fingerprint_button_clicked (GtkWindow *parent,
|
|
GtkWidget *label1,
|
|
GtkWidget *label2,
|
|
UmUser *user)
|
|
{
|
|
bindtextdomain ("fprintd", GNOMELOCALEDIR);
|
|
bind_textdomain_codeset ("fprintd", "UTF-8");
|
|
|
|
if (is_disable != FALSE) {
|
|
delete_fingerprints_question (parent, label1, label2, user);
|
|
} else {
|
|
enroll_fingerprints (parent, label1, label2, user);
|
|
}
|
|
}
|
|
|