aboutsummaryrefslogtreecommitdiff
path: root/debian/patches
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2009-04-02 16:51:24 +0200
committerGuido Günther <agx@sigxcpu.org>2009-04-02 16:51:24 +0200
commitcf0e693c1ab13540e101a7c02f0a27878f08bc90 (patch)
tree245c55c74ad9ac1bdb178128d28918598244cbfa /debian/patches
parentdocument changes and release 0.8+svn136-1 (diff)
downloadkrb5-auth-dialog-cf0e693c1ab13540e101a7c02f0a27878f08bc90.tar.gz
krb5-auth-dialog-cf0e693c1ab13540e101a7c02f0a27878f08bc90.tar.bz2
krb5-auth-dialog-cf0e693c1ab13540e101a7c02f0a27878f08bc90.zip
allow to set ticket flags via preferences dialog
Closes: #521251
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/0003-add-preferences-dialog.patch1973
-rw-r--r--debian/patches/series1
2 files changed, 1974 insertions, 0 deletions
diff --git a/debian/patches/0003-add-preferences-dialog.patch b/debian/patches/0003-add-preferences-dialog.patch
new file mode 100644
index 0000000..bd43749
--- /dev/null
+++ b/debian/patches/0003-add-preferences-dialog.patch
@@ -0,0 +1,1973 @@
+From: =?utf-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
+Date: Thu, 2 Apr 2009 16:48:38 +0200
+Subject: [PATCH] add preferences dialog
+
+Closes: #521251
+---
+ Makefile.am | 2 +-
+ configure.ac | 1 +
+ po/POTFILES.in | 5 +-
+ preferences/Makefile.am | 42 ++
+ preferences/krb5-auth-dialog-preferences.c | 618 ++++++++++++++++++++
+ .../krb5-auth-dialog-preferences.desktop.in | 12 +
+ preferences/krb5-auth-dialog-preferences.glade | 565 ++++++++++++++++++
+ src/Makefile.am | 2 +
+ src/krb5-auth-applet.c | 83 +++-
+ src/krb5-auth-dialog.c | 49 ++-
+ src/krb5-auth-dialog.schemas.in | 39 ++
+ src/krb5-auth-gconf-tools.c | 103 ++++
+ src/krb5-auth-gconf-tools.h | 41 ++
+ src/krb5-auth-gconf.c | 135 ++---
+ 14 files changed, 1594 insertions(+), 103 deletions(-)
+ create mode 100644 preferences/Makefile.am
+ create mode 100644 preferences/krb5-auth-dialog-preferences.c
+ create mode 100644 preferences/krb5-auth-dialog-preferences.desktop.in
+ create mode 100644 preferences/krb5-auth-dialog-preferences.glade
+ create mode 100644 src/krb5-auth-gconf-tools.c
+ create mode 100644 src/krb5-auth-gconf-tools.h
+
+diff --git a/Makefile.am b/Makefile.am
+index 51c4e5b..2be06e7 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-SUBDIRS = secmem gtksecentry src po etpo icons
++SUBDIRS = secmem gtksecentry src po etpo icons preferences
+
+ EXTRA_DIST = \
+ krb5-auth-dialog.spec
+diff --git a/configure.ac b/configure.ac
+index 89fb2fa..be95999 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -218,6 +218,7 @@ gtksecentry/Makefile
+ icons/Makefile
+ etpo/Makefile
+ po/Makefile.in
++preferences/Makefile
+ ])
+
+ AC_MSG_NOTICE([])
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index 8ee65fd..70977d4 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -4,6 +4,9 @@ src/krb5-auth-pwdialog.c
+ src/dummy-strings.c
+ src/krb5-auth-applet.c
+ src/krb5-auth-dialog.desktop.in
++src/krb5-auth-dialog.schemas.in
+ gtksecentry/gtksecentry.c
+ secmem/util.c
+-src/krb5-auth-dialog.schemas.in
++preferences/krb5-auth-dialog-preferences.c
++preferences/krb5-auth-dialog-preferences.desktop.in
++preferences/krb5-auth-dialog-preferences.glade
+diff --git a/preferences/Makefile.am b/preferences/Makefile.am
+new file mode 100644
+index 0000000..83541ea
+--- /dev/null
++++ b/preferences/Makefile.am
+@@ -0,0 +1,42 @@
++NULL =
++
++INCLUDES = \
++ -I $(top_srcdir)/src/ \
++ -DKA_DATA_DIR=\""$(pkgdatadir)"\" \
++ -DLOCALE_DIR=\""$(localedir)/"\" \
++ $(NULL)
++
++bin_PROGRAMS = krb5-auth-dialog-preferences
++
++schemadir = $(sysconfdir)/gconf/schemas
++
++krb5_auth_dialog_preferences_SOURCES = \
++ krb5-auth-dialog-preferences.c \
++ ../src/krb5-auth-gconf-tools.c \
++ ../src/krb5-auth-gconf-tools.h \
++ $(NULL)
++
++krb5_auth_dialog_preferences_LDADD = \
++ @GCONF_LIBS@ \
++ @GLADE_LIBS@ \
++ @GTK_LIBS@ \
++ $(NULL)
++
++desktopdir = $(datadir)/applications
++desktop_in_files = krb5-auth-dialog-preferences.desktop.in
++desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
++
++@INTLTOOL_DESKTOP_RULE@
++
++pkgdatadir = $(datadir)/krb5-auth-dialog
++pkgdata_DATA = \
++ krb5-auth-dialog-preferences.glade
++
++CLEANFILES = \
++ $(desktop_DATA) \
++ $(NULL)
++
++EXTRA_DIST = \
++ $(desktop_in_files) \
++ $(pkgdata_DATA) \
++ $(NULL)
+diff --git a/preferences/krb5-auth-dialog-preferences.c b/preferences/krb5-auth-dialog-preferences.c
+new file mode 100644
+index 0000000..e4d8a48
+--- /dev/null
++++ b/preferences/krb5-auth-dialog-preferences.c
+@@ -0,0 +1,618 @@
++/*
++ * Copyright (C) 2009 Guido Guenther <agx@sigxcup.org>
++ *
++ * 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 <gtk/gtk.h>
++#include <glib/gi18n.h>
++#include <glade/glade.h>
++
++#include "krb5-auth-gconf-tools.h"
++
++#define N_LISTENERS 7
++
++typedef struct {
++ GladeXML *xml;
++ GConfClient *client;
++
++ GtkWidget *dialog;
++ GtkWidget *principal_entry;
++ GtkWidget *pkuserid_entry;
++ GtkWidget *forwardable_toggle;
++ GtkWidget *proxiable_toggle;
++ GtkWidget *renewable_toggle;
++ GtkWidget *trayicon_toggle;
++ GtkWidget *prompt_mins_entry;
++
++ guint listeners [N_LISTENERS];
++ int n_listeners;
++} KaPreferencesDialog;
++
++
++static void
++ka_preferences_principal_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ const char *principal;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
++ return;
++
++ principal = gconf_value_get_string (entry->value);
++
++ if (!principal || !strlen(principal))
++ gtk_entry_set_text (GTK_ENTRY (dialog->principal_entry), "");
++ else {
++ const char *old_principal;
++
++ old_principal = gtk_entry_get_text (GTK_ENTRY (dialog->principal_entry));
++ if (!old_principal || (old_principal && strcmp (old_principal, principal)))
++ gtk_entry_set_text (GTK_ENTRY (dialog->principal_entry), principal);
++ }
++}
++
++
++static void
++ka_preferences_dialog_principal_changed (GtkEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ const char *principal;
++
++ principal = gtk_entry_get_text (entry);
++
++ if (!principal || !strlen(principal))
++ gconf_client_unset (dialog->client, KA_GCONF_KEY_PRINCIPAL, NULL);
++ else
++ gconf_client_set_string (dialog->client, KA_GCONF_KEY_PRINCIPAL, principal, NULL);
++}
++
++
++static void
++ka_preferences_dialog_setup_principal_entry (KaPreferencesDialog *dialog)
++{
++ char *principal = NULL;
++
++ dialog->principal_entry = glade_xml_get_widget (dialog->xml, "principal_entry");
++ g_assert (dialog->principal_entry != NULL);
++
++ if (!ka_gconf_get_string (dialog->client, KA_GCONF_KEY_PRINCIPAL, &principal))
++ g_warning ("Getting principal failed");
++
++ if (principal && strlen(principal))
++ gtk_entry_set_text (GTK_ENTRY (dialog->principal_entry), principal);
++ if (principal)
++ g_free (principal);
++
++ g_signal_connect (dialog->principal_entry, "changed",
++ G_CALLBACK (ka_preferences_dialog_principal_changed), dialog);
++
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_PRINCIPAL, NULL)) {
++ gtk_widget_set_sensitive (dialog->principal_entry, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_PRINCIPAL,
++ (GConfClientNotifyFunc) ka_preferences_principal_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++}
++
++
++static void
++ka_preferences_pkuserid_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ const char *pkuserid;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
++ return;
++
++ pkuserid = gconf_value_get_string (entry->value);
++
++ if (!pkuserid || !strlen(pkuserid))
++ gtk_entry_set_text (GTK_ENTRY (dialog->pkuserid_entry), "");
++ else {
++ const char *old_pkuserid;
++
++ old_pkuserid = gtk_entry_get_text (GTK_ENTRY (dialog->pkuserid_entry));
++ if (!old_pkuserid || (old_pkuserid && strcmp (old_pkuserid, pkuserid)))
++ gtk_entry_set_text (GTK_ENTRY (dialog->pkuserid_entry), pkuserid);
++ }
++}
++
++
++static void
++ka_preferences_dialog_pkuserid_changed (GtkEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ const char *pkuserid;
++
++ pkuserid = gtk_entry_get_text (entry);
++
++ if (!pkuserid || !strlen(pkuserid))
++ gconf_client_unset (dialog->client, KA_GCONF_KEY_PK_USERID, NULL);
++ else
++ gconf_client_set_string (dialog->client, KA_GCONF_KEY_PK_USERID, pkuserid, NULL);
++}
++
++
++static void
++ka_preferences_dialog_setup_pkuserid_entry (KaPreferencesDialog *dialog)
++{
++ char *pkuserid = NULL;
++
++ dialog->pkuserid_entry = glade_xml_get_widget (dialog->xml, "pkuserid_entry");
++ g_assert (dialog->pkuserid_entry != NULL);
++
++ if (!ka_gconf_get_string (dialog->client, KA_GCONF_KEY_PK_USERID, &pkuserid))
++ g_warning ("Getting pkuserid failed");
++
++ if (pkuserid && strlen(pkuserid))
++ gtk_entry_set_text (GTK_ENTRY (dialog->pkuserid_entry), pkuserid);
++ if (pkuserid)
++ g_free (pkuserid);
++
++ g_signal_connect (dialog->pkuserid_entry, "changed",
++ G_CALLBACK (ka_preferences_dialog_pkuserid_changed), dialog);
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_PK_USERID, NULL)) {
++ gtk_widget_set_sensitive (dialog->pkuserid_entry, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_PK_USERID,
++ (GConfClientNotifyFunc) ka_preferences_pkuserid_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++}
++
++
++static void
++ka_preferences_dialog_forwardable_toggled (GtkToggleButton *toggle,
++ KaPreferencesDialog *dialog)
++{
++ gboolean forwardable;
++
++ forwardable = gtk_toggle_button_get_active (toggle);
++
++ gconf_client_set_bool (dialog->client, KA_GCONF_KEY_FORWARDABLE, forwardable, NULL);
++}
++
++
++static void
++ka_preferences_dialog_forwardable_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ gboolean forwardable;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
++ return;
++
++ forwardable = gconf_value_get_bool (entry->value) != FALSE;
++
++ if (forwardable != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->forwardable_toggle)))
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->forwardable_toggle), forwardable);
++}
++
++
++static gboolean
++ka_preferences_dialog_setup_forwardable_toggle (KaPreferencesDialog *dialog)
++{
++ gboolean forwardable;
++
++ dialog->forwardable_toggle = glade_xml_get_widget (dialog->xml, "forwardable_toggle");
++ g_assert (dialog->forwardable_toggle != NULL);
++
++ forwardable = gconf_client_get_bool (dialog->client, KA_GCONF_KEY_FORWARDABLE, NULL);
++
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->forwardable_toggle), forwardable);
++
++ g_signal_connect (dialog->forwardable_toggle, "toggled",
++ G_CALLBACK (ka_preferences_dialog_forwardable_toggled), dialog);
++
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_FORWARDABLE, NULL)) {
++ gtk_widget_set_sensitive (dialog->forwardable_toggle, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_FORWARDABLE,
++ (GConfClientNotifyFunc) ka_preferences_dialog_forwardable_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++ return forwardable;
++}
++
++
++static void
++ka_preferences_dialog_proxiable_toggled (GtkToggleButton *toggle,
++ KaPreferencesDialog *dialog)
++{
++ gboolean proxiable;
++
++ proxiable = gtk_toggle_button_get_active (toggle);
++
++ gconf_client_set_bool (dialog->client, KA_GCONF_KEY_PROXIABLE, proxiable, NULL);
++}
++
++
++static void
++ka_preferences_dialog_proxiable_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ gboolean proxiable;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
++ return;
++
++ proxiable = gconf_value_get_bool (entry->value) != FALSE;
++
++ if (proxiable != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->proxiable_toggle)))
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->proxiable_toggle), proxiable);
++}
++
++
++static gboolean
++ka_preferences_dialog_setup_proxiable_toggle (KaPreferencesDialog *dialog)
++{
++ gboolean proxiable;
++
++ dialog->proxiable_toggle = glade_xml_get_widget (dialog->xml, "proxiable_toggle");
++ g_assert (dialog->proxiable_toggle != NULL);
++
++ proxiable = gconf_client_get_bool (dialog->client, KA_GCONF_KEY_PROXIABLE, NULL);
++
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->proxiable_toggle), proxiable);
++
++ g_signal_connect (dialog->proxiable_toggle, "toggled",
++ G_CALLBACK (ka_preferences_dialog_proxiable_toggled), dialog);
++
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_PROXIABLE, NULL)) {
++ gtk_widget_set_sensitive (dialog->proxiable_toggle, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_PROXIABLE,
++ (GConfClientNotifyFunc) ka_preferences_dialog_proxiable_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++ return proxiable;
++}
++
++
++static void
++ka_preferences_dialog_renewable_toggled (GtkToggleButton *toggle,
++ KaPreferencesDialog *dialog)
++{
++ gboolean renewable;
++
++ renewable = gtk_toggle_button_get_active (toggle);
++
++ gconf_client_set_bool (dialog->client, KA_GCONF_KEY_RENEWABLE, renewable, NULL);
++}
++
++
++static void
++ka_preferences_dialog_renewable_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ gboolean renewable;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
++ return;
++
++ renewable = gconf_value_get_bool (entry->value) != FALSE;
++
++ if (renewable != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->renewable_toggle)))
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->renewable_toggle), renewable);
++}
++
++
++static gboolean
++ka_preferences_dialog_setup_renewable_toggle (KaPreferencesDialog *dialog)
++{
++ gboolean renewable;
++
++ dialog->renewable_toggle = glade_xml_get_widget (dialog->xml, "renewable_toggle");
++ g_assert (dialog->renewable_toggle != NULL);
++
++ renewable = gconf_client_get_bool (dialog->client, KA_GCONF_KEY_RENEWABLE, NULL);
++
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->renewable_toggle), renewable);
++
++ g_signal_connect (dialog->renewable_toggle, "toggled",
++ G_CALLBACK (ka_preferences_dialog_renewable_toggled), dialog);
++
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_RENEWABLE, NULL)) {
++ gtk_widget_set_sensitive (dialog->renewable_toggle, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_RENEWABLE,
++ (GConfClientNotifyFunc) ka_preferences_dialog_renewable_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++ return renewable;
++}
++
++static void
++ka_preferences_dialog_trayicon_toggled (GtkToggleButton *toggle,
++ KaPreferencesDialog *dialog)
++{
++ gboolean trayicon;
++
++ trayicon = gtk_toggle_button_get_active (toggle);
++ gconf_client_set_bool (dialog->client, KA_GCONF_KEY_SHOW_TRAYICON, trayicon, NULL);
++}
++
++
++static void
++ka_preferences_dialog_trayicon_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ gboolean trayicon;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
++ return;
++
++ trayicon = gconf_value_get_bool (entry->value) != FALSE;
++
++ if (trayicon != gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->trayicon_toggle)))
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->trayicon_toggle), trayicon);
++}
++
++
++static gboolean
++ka_preferences_dialog_setup_trayicon_toggle (KaPreferencesDialog *dialog)
++{
++ gboolean trayicon;
++
++ dialog->trayicon_toggle = glade_xml_get_widget (dialog->xml, "trayicon_toggle");
++ g_assert (dialog->trayicon_toggle != NULL);
++
++ trayicon = gconf_client_get_bool (dialog->client, KA_GCONF_KEY_SHOW_TRAYICON, NULL);
++
++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->trayicon_toggle), trayicon);
++
++ g_signal_connect (dialog->trayicon_toggle, "toggled",
++ G_CALLBACK (ka_preferences_dialog_trayicon_toggled), dialog);
++
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_SHOW_TRAYICON, NULL)) {
++ gtk_widget_set_sensitive (dialog->trayicon_toggle, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_SHOW_TRAYICON,
++ (GConfClientNotifyFunc) ka_preferences_dialog_trayicon_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++ return trayicon;
++}
++
++
++static void
++ka_preferences_dialog_prompt_mins_changed (GtkSpinButton *button,
++ KaPreferencesDialog *dialog)
++{
++ gint prompt_mins;
++
++ prompt_mins = gtk_spin_button_get_value_as_int (button);
++ gconf_client_set_int (dialog->client, KA_GCONF_KEY_PROMPT_MINS, prompt_mins, NULL);
++}
++
++
++static void
++ka_preferences_dialog_prompt_mins_notify (GConfClient *client G_GNUC_UNUSED,
++ guint cnx_id G_GNUC_UNUSED,
++ GConfEntry *entry,
++ KaPreferencesDialog *dialog)
++{
++ gint prompt_mins;
++
++ if (!entry->value || entry->value->type != GCONF_VALUE_INT)
++ return;
++
++ prompt_mins = gconf_value_get_int (entry->value);
++
++ if (prompt_mins != gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (dialog->prompt_mins_entry)))
++ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prompt_mins_entry), prompt_mins);
++}
++
++
++static gint
++ka_preferences_dialog_setup_prompt_mins_entry (KaPreferencesDialog *dialog)
++{
++ gint prompt_mins;
++
++ dialog->prompt_mins_entry = glade_xml_get_widget (dialog->xml, "prompt_mins_entry");
++ g_assert (dialog->prompt_mins_entry != NULL);
++
++ prompt_mins = gconf_client_get_int (dialog->client, KA_GCONF_KEY_PROMPT_MINS, NULL);
++
++ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prompt_mins_entry), prompt_mins);
++
++ g_signal_connect (dialog->prompt_mins_entry, "value-changed",
++ G_CALLBACK (ka_preferences_dialog_prompt_mins_changed), dialog);
++
++ if (!gconf_client_key_is_writable (dialog->client, KA_GCONF_KEY_PROMPT_MINS, NULL)) {
++ gtk_widget_set_sensitive (dialog->prompt_mins_entry, FALSE);
++ }
++
++ dialog->listeners [dialog->n_listeners] = gconf_client_notify_add (dialog->client,
++ KA_GCONF_KEY_PROMPT_MINS,
++ (GConfClientNotifyFunc) ka_preferences_dialog_prompt_mins_notify,
++ dialog, NULL, NULL);
++ dialog->n_listeners++;
++ return prompt_mins;
++}
++
++
++
++static void
++ka_preferences_dialog_response (GtkWidget *widget,
++ int response,
++ KaPreferencesDialog *dialog)
++{
++ GError *error = NULL;
++
++ if (response != GTK_RESPONSE_HELP) {
++ gtk_widget_destroy (widget);
++ return;
++ }
++
++ gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (dialog->dialog)),
++ "ghelp:krb5-auth-dialog#preferences",
++ gtk_get_current_event_time (), &error);
++
++ if (error) {
++ GtkWidget *message_dialog;
++
++
++ message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog->dialog),
++ GTK_DIALOG_DESTROY_WITH_PARENT,
++ GTK_MESSAGE_ERROR,
++ GTK_BUTTONS_CLOSE,
++ _("There was an error displaying help:\n%s"),
++ error->message);
++ gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE);
++
++ g_signal_connect (message_dialog, "response",
++ G_CALLBACK (gtk_widget_destroy),
++ NULL);
++
++ gtk_widget_show (message_dialog);
++ g_error_free (error);
++ }
++}
++
++
++static void
++ka_preferences_dialog_destroyed (GtkWidget *widget G_GNUC_UNUSED,
++ KaPreferencesDialog *dialog)
++{
++ dialog->dialog = NULL;
++
++ gtk_main_quit ();
++}
++
++
++static gboolean
++ka_preferences_dialog_init(KaPreferencesDialog* dialog)
++{
++ dialog->xml = glade_xml_new (KA_DATA_DIR G_DIR_SEPARATOR_S
++ PACKAGE "-preferences.glade", NULL, NULL);
++
++ dialog->dialog = glade_xml_get_widget (dialog->xml, "krb5_auth_dialog_prefs");
++ g_assert (dialog->dialog);
++
++ g_signal_connect (dialog->dialog, "response",
++ G_CALLBACK (ka_preferences_dialog_response), dialog);
++ g_signal_connect (dialog->dialog, "destroy",
++ G_CALLBACK (ka_preferences_dialog_destroyed), dialog);
++
++ dialog->client = gconf_client_get_default ();
++ gconf_client_add_dir (dialog->client, KA_GCONF_PATH, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
++
++ ka_preferences_dialog_setup_principal_entry (dialog);
++ ka_preferences_dialog_setup_pkuserid_entry (dialog);
++ ka_preferences_dialog_setup_forwardable_toggle (dialog);
++ ka_preferences_dialog_setup_proxiable_toggle (dialog);
++ ka_preferences_dialog_setup_renewable_toggle (dialog);
++ ka_preferences_dialog_setup_trayicon_toggle (dialog);
++ ka_preferences_dialog_setup_prompt_mins_entry (dialog);
++
++ g_assert (dialog->n_listeners == N_LISTENERS);
++
++ gtk_widget_show (dialog->dialog);
++ return TRUE;
++}
++
++
++static void
++ka_preferences_dialog_finalize (KaPreferencesDialog *dialog)
++{
++ if (dialog->dialog)
++ gtk_widget_destroy (dialog->dialog);
++ dialog->dialog = NULL;
++
++ if (dialog->client) {
++ int i;
++
++ for (i = 0; i < dialog->n_listeners; i++) {
++ if (dialog->listeners [i])
++ gconf_client_notify_remove (dialog->client, dialog->listeners [i]);
++ dialog->listeners [i] = 0;
++ }
++ dialog->n_listeners = 0;
++
++ gconf_client_remove_dir (dialog->client, KA_GCONF_PATH, NULL);
++
++ g_object_unref (dialog->client);
++ dialog->client = NULL;
++ }
++
++ if (dialog->xml)
++ g_object_unref (dialog->xml);
++ dialog->xml = NULL;
++}
++
++int
++main (int argc, char *argv[])
++{
++ GOptionContext *context;
++ GError *error = NULL;
++ KaPreferencesDialog dialog = { NULL, };
++
++ const char *help_msg = "Run '" PACKAGE " --help' to see a full list of available command line options";
++ const GOptionEntry options [] = {
++ { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
++ };
++
++ context = g_option_context_new ("- Kerberos Authentication Configuration");
++ g_option_context_add_main_entries (context, options, NULL);
++ g_option_context_add_group (context, gtk_get_option_group (TRUE));
++ g_option_context_parse (context, &argc, &argv, &error);
++ if (error) {
++ g_print ("%s\n%s\n",
++ error->message,
++ help_msg);
++ g_error_free (error);
++ return 1;
++ }
++ textdomain (PACKAGE);
++ bind_textdomain_codeset (PACKAGE, "UTF-8");
++ bindtextdomain (PACKAGE, LOCALE_DIR);
++
++ g_set_application_name (_("Kerberos Authentication Configuration"));
++
++ ka_preferences_dialog_init(&dialog);
++ gtk_main ();
++ ka_preferences_dialog_finalize(&dialog);
++ return 0;
++}
+diff --git a/preferences/krb5-auth-dialog-preferences.desktop.in b/preferences/krb5-auth-dialog-preferences.desktop.in
+new file mode 100644
+index 0000000..d87e1e7
+--- /dev/null
++++ b/preferences/krb5-auth-dialog-preferences.desktop.in
+@@ -0,0 +1,12 @@
++[Desktop Entry]
++_Name=Network Authentication
++_Comment=Set your Kerberos network authenticaion preferences
++Exec=krb5-auth-dialog-preferences
++Icon=gtk-dialog-authentication
++Terminal=false
++Type=Application
++StartupNotify=true
++Categories=GNOME;GTK;Settings;X-GNOME-NetworkSettings;
++OnlyShowIn=GNOME;
++X-GNOME-Bugzilla-Bugzilla=GNOME
++X-GNOME-Bugzilla-Product=krb5-auth-dialog
+diff --git a/preferences/krb5-auth-dialog-preferences.glade b/preferences/krb5-auth-dialog-preferences.glade
+new file mode 100644
+index 0000000..128229d
+--- /dev/null
++++ b/preferences/krb5-auth-dialog-preferences.glade
+@@ -0,0 +1,565 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
++<!--Generated with glade3 3.4.5 on Thu Apr 2 16:29:44 2009 -->
++<glade-interface>
++ <widget class="GtkDialog" id="krb5_auth_dialog_prefs">
++ <property name="border_width">5</property>
++ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
++ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
++ <property name="has_separator">False</property>
++ <child internal-child="vbox">
++ <widget class="GtkVBox" id="dialog-vbox1">
++ <property name="visible">True</property>
++ <property name="spacing">2</property>
++ <child>
++ <widget class="GtkNotebook" id="notebook1">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <child>
++ <widget class="GtkVBox" id="vbox1">
++ <property name="visible">True</property>
++ <property name="border_width">12</property>
++ <property name="spacing">18</property>
++ <child>
++ <widget class="GtkVBox" id="vbox2">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkLabel" id="label4">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">&lt;b&gt;Kerberos User&lt;/b&gt;</property>
++ <property name="use_markup">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox1">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkImage" id="access">
++ <property name="visible">True</property>
++ <property name="yalign">0</property>
++ <property name="icon_size">6</property>
++ <property name="icon_name">gtk-dialog-authentication</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkVBox" id="vbox5">
++ <property name="visible">True</property>
++ <property name="spacing">6</property>
++ <child>
++ <widget class="GtkLabel" id="label6">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">Kerberos principal:</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox5">
++ <property name="visible">True</property>
++ <property name="spacing">6</property>
++ <child>
++ <widget class="GtkLabel" id="label8">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkEntry" id="principal_entry">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkLabel" id="label7">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">Pkinit userid: </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">2</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox6">
++ <property name="visible">True</property>
++ <property name="spacing">6</property>
++ <child>
++ <widget class="GtkLabel" id="label9">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkEntry" id="pkuserid_entry">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">3</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkVBox" id="vbox3">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkLabel" id="label5">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">&lt;b&gt;Ticket Options&lt;/b&gt;</property>
++ <property name="use_markup">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox2">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkImage" id="image1">
++ <property name="visible">True</property>
++ <property name="yalign">0</property>
++ <property name="icon_size">6</property>
++ <property name="icon_name">system-lock-screen</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkVBox" id="vbox4">
++ <property name="visible">True</property>
++ <property name="spacing">6</property>
++ <child>
++ <widget class="GtkLabel" id="label10">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Requested Kerberos tickets should be:</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox3">
++ <property name="visible">True</property>
++ <child>
++ <widget class="GtkLabel" id="label11">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkCheckButton" id="forwardable_toggle">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="label" translatable="yes">forwardable</property>
++ <property name="response_id">0</property>
++ <property name="draw_indicator">True</property>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox4">
++ <property name="visible">True</property>
++ <child>
++ <widget class="GtkLabel" id="label12">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkCheckButton" id="renewable_toggle">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="label" translatable="yes">renewable</property>
++ <property name="response_id">0</property>
++ <property name="draw_indicator">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">2</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox11">
++ <property name="visible">True</property>
++ <child>
++ <widget class="GtkLabel" id="label19">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkCheckButton" id="proxiable_toggle">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="label" translatable="yes">proxiable</property>
++ <property name="response_id">0</property>
++ <property name="draw_indicator">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">3</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ <child>
++ <widget class="GtkLabel" id="label1">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Kerberos</property>
++ </widget>
++ <packing>
++ <property name="type">tab</property>
++ <property name="tab_fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkVBox" id="vbox9">
++ <property name="visible">True</property>
++ <property name="border_width">12</property>
++ <property name="spacing">18</property>
++ <child>
++ <widget class="GtkVBox" id="vbox8">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkLabel" id="label17">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">&lt;b&gt;Notifications&lt;/b&gt;</property>
++ <property name="use_markup">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox9">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkImage" id="image3">
++ <property name="visible">True</property>
++ <property name="yalign">0</property>
++ <property name="stock">gtk-dialog-warning</property>
++ <property name="icon_size">6</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox8">
++ <property name="visible">True</property>
++ <property name="spacing">6</property>
++ <child>
++ <widget class="GtkLabel" id="label14">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkLabel" id="label15">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Warn every</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkSpinButton" id="prompt_mins_entry">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="adjustment">0 0 100 1 10 10</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">2</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkLabel" id="label16">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">minutes</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">3</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkVBox" id="vbox10">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkLabel" id="label18">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="label" translatable="yes">&lt;b&gt;Appearance&lt;/b&gt;</property>
++ <property name="use_markup">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkHBox" id="hbox10">
++ <property name="visible">True</property>
++ <property name="spacing">12</property>
++ <child>
++ <widget class="GtkImage" id="image2">
++ <property name="visible">True</property>
++ <property name="xalign">0</property>
++ <property name="yalign">0</property>
++ <property name="stock">gtk-zoom-in</property>
++ <property name="icon_size">6</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkVBox" id="vbox7">
++ <property name="visible">True</property>
++ <child>
++ <widget class="GtkHBox" id="hbox7">
++ <property name="visible">True</property>
++ <property name="spacing">6</property>
++ <child>
++ <widget class="GtkLabel" id="label13">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes"> </property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkCheckButton" id="trayicon_toggle">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="label" translatable="yes">Show tray icon</property>
++ <property name="response_id">0</property>
++ <property name="draw_indicator">True</property>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="fill">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ <child>
++ <widget class="GtkLabel" id="label2">
++ <property name="visible">True</property>
++ <property name="label" translatable="yes">Applet</property>
++ </widget>
++ <packing>
++ <property name="type">tab</property>
++ <property name="position">1</property>
++ <property name="tab_fill">False</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ <child internal-child="action_area">
++ <widget class="GtkHButtonBox" id="dialog-action_area1">
++ <property name="visible">True</property>
++ <property name="layout_style">GTK_BUTTONBOX_END</property>
++ <child>
++ <widget class="GtkButton" id="button2">
++ <property name="can_focus">True</property>
++ <property name="receives_default">True</property>
++ <property name="label" translatable="yes">gtk-help</property>
++ <property name="use_stock">True</property>
++ <property name="response_id">-11</property>
++ </widget>
++ </child>
++ <child>
++ <widget class="GtkButton" id="button1">
++ <property name="visible">True</property>
++ <property name="can_focus">True</property>
++ <property name="receives_default">True</property>
++ <property name="label" translatable="yes">gtk-close</property>
++ <property name="use_stock">True</property>
++ <property name="response_id">0</property>
++ </widget>
++ <packing>
++ <property name="position">1</property>
++ </packing>
++ </child>
++ </widget>
++ <packing>
++ <property name="expand">False</property>
++ <property name="pack_type">GTK_PACK_END</property>
++ </packing>
++ </child>
++ </widget>
++ </child>
++ </widget>
++</glade-interface>
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 1c74c84..4c16102 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -33,6 +33,8 @@ krb5_auth_dialog_SOURCES = \
+ krb5-auth-pwdialog.h \
+ krb5-auth-gconf.c \
+ krb5-auth-gconf.h \
++ krb5-auth-gconf-tools.c \
++ krb5-auth-gconf-tools.h \
+ krb5-auth-dbus.c \
+ krb5-auth-dbus.h \
+ dummy-strings.c
+diff --git a/src/krb5-auth-applet.c b/src/krb5-auth-applet.c
+index 34524df..daaef2e 100644
+--- a/src/krb5-auth-applet.c
++++ b/src/krb5-auth-applet.c
+@@ -43,6 +43,9 @@ enum
+ KA_PROP_PK_USERID,
+ KA_PROP_TRAYICON,
+ KA_PROP_PW_PROMPT_MINS,
++ KA_PROP_TGT_FORWARDABLE,
++ KA_PROP_TGT_PROXIABLE,
++ KA_PROP_TGT_RENEWABLE,
+ };
+
+ struct _KaApplet {
+@@ -73,6 +76,9 @@ struct _KaAppletPrivate
+ char* principal; /* the principal to request */
+ gboolean renewable; /* credentials renewable? */
+ char* pk_userid; /* "userid" for pkint */
++ gboolean tgt_forwardable; /* request a forwardable ticket */
++ gboolean tgt_renewable; /* request a renewable ticket */
++ gboolean tgt_proxiable; /* request a proxiable ticket */
+ };
+
+ static void
+@@ -106,6 +112,21 @@ ka_applet_set_property (GObject *object,
+ KA_DEBUG ("%s: %d", pspec->name, self->priv->pw_prompt_secs/60);
+ break;
+
++ case KA_PROP_TGT_FORWARDABLE:
++ self->priv->tgt_forwardable = g_value_get_boolean (value);
++ KA_DEBUG ("%s: %s", pspec->name, self->priv->tgt_forwardable ? "True" : "False");
++ break;
++
++ case KA_PROP_TGT_PROXIABLE:
++ self->priv->tgt_proxiable = g_value_get_boolean (value);
++ KA_DEBUG ("%s: %s", pspec->name, self->priv->tgt_proxiable ? "True" : "False");
++ break;
++
++ case KA_PROP_TGT_RENEWABLE:
++ self->priv->tgt_renewable = g_value_get_boolean (value);
++ KA_DEBUG ("%s: %s", pspec->name, self->priv->tgt_renewable ? "True" : "False");
++ break;
++
+ default:
+ /* We don't have any other property... */
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+@@ -139,6 +160,18 @@ ka_applet_get_property (GObject *object,
+ g_value_set_uint (value, self->priv->pw_prompt_secs / 60);
+ break;
+
++ case KA_PROP_TGT_FORWARDABLE:
++ g_value_set_boolean (value, self->priv->tgt_forwardable);
++ break;
++
++ case KA_PROP_TGT_PROXIABLE:
++ g_value_set_boolean (value, self->priv->tgt_proxiable);
++ break;
++
++ case KA_PROP_TGT_RENEWABLE:
++ g_value_set_boolean (value, self->priv->tgt_renewable);
++ break;
++
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+@@ -203,7 +236,7 @@ ka_applet_class_init(KaAppletClass *klass)
+
+ pspec = g_param_spec_string ("principal",
+ "Principal",
+- "Get/Set Kerberos Principal",
++ "Get/Set Kerberos principal",
+ "",
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class,
+@@ -211,7 +244,7 @@ ka_applet_class_init(KaAppletClass *klass)
+ pspec);
+
+ pspec = g_param_spec_string ("pk-userid",
+- "PKinit Identifier",
++ "PKinit identifier",
+ "Get/Set Pkinit identifier",
+ "",
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
+@@ -229,13 +262,40 @@ ka_applet_class_init(KaAppletClass *klass)
+ pspec);
+
+ pspec = g_param_spec_uint ("pw-prompt-mins",
+- "Password Prompting Interval",
+- "Password Prompting Interval in Minutes",
++ "Password prompting interval",
++ "Password prompting interval in minutes",
+ 0, G_MAXUINT, MINUTES_BEFORE_PROMPTING,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class,
+ KA_PROP_PW_PROMPT_MINS,
+ pspec);
++
++ pspec = g_param_spec_boolean("tgt-forwardable",
++ "Forwardable ticket",
++ "wether to request forwardable tickets",
++ FALSE,
++ G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
++ g_object_class_install_property (object_class,
++ KA_PROP_TGT_FORWARDABLE,
++ pspec);
++
++ pspec = g_param_spec_boolean("tgt-proxiable",
++ "Proxiable ticket",
++ "wether to request proxiable tickets",
++ FALSE,
++ G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
++ g_object_class_install_property (object_class,
++ KA_PROP_TGT_PROXIABLE,
++ pspec);
++
++ pspec = g_param_spec_boolean("tgt-renewable",
++ "Renewable ticket",
++ "wether to request renewable tickets",
++ FALSE,
++ G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
++ g_object_class_install_property (object_class,
++ KA_PROP_TGT_RENEWABLE,
++ pspec);
+ }
+
+
+@@ -372,6 +432,13 @@ ka_applet_menu_add_separator_item (GtkWidget* menu)
+ gtk_widget_show (menu_item);
+ }
+
++static void
++ka_applet_cb_preferences (GtkWidget* menuitem G_GNUC_UNUSED,
++ gpointer user_data G_GNUC_UNUSED)
++{
++ g_spawn_command_line_async ("krb5-auth-dialog-preferences", NULL);
++}
++
+
+ /* Free all resources and quit */
+ static void
+@@ -421,6 +488,14 @@ ka_applet_create_context_menu (KaApplet* applet)
+
+ ka_applet_menu_add_separator_item (menu);
+
++ /* Preferences */
++ menu_item = gtk_image_menu_item_new_with_mnemonic (_("_Preferences"));
++ g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_applet_cb_preferences), applet);
++ image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
++ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
++ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
++
++
+ /* About item */
+ menu_item = gtk_image_menu_item_new_with_mnemonic (_("_About"));
+ g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (ka_applet_cb_about_dialog), applet);
+diff --git a/src/krb5-auth-dialog.c b/src/krb5-auth-dialog.c
+index be6c29f..6b48d2b 100644
+--- a/src/krb5-auth-dialog.c
++++ b/src/krb5-auth-dialog.c
+@@ -378,9 +378,40 @@ out:
+ }
+
+
++/*
++ * set ticket options by looking at krb5.conf and gconf
++ */
++static void
++ka_set_ticket_options(KaApplet* applet,
++ krb5_get_init_creds_opt *out)
++{
++ gboolean flag;
++
++#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
++ krb5_get_init_creds_opt_set_default_flags(kcontext, PACKAGE,
++ krb5_principal_get_realm(kcontext, kprincipal), out);
++#endif
++ g_object_get(applet, "tgt-forwardable", &flag, NULL);
++ if (flag)
++ krb5_get_init_creds_opt_set_forwardable(out, flag);
++ g_object_get(applet, "tgt-proxiable", &flag, NULL);
++ if (flag)
++ krb5_get_init_creds_opt_set_proxiable(out, flag);
++ g_object_get(applet, "tgt-renewable", &flag, NULL);
++ if (flag) {
++ krb5_deltat r = 3600*24*30; /* 1 month */
++ krb5_get_init_creds_opt_set_renew_life (out, r);
++ }
++}
++
++
++/*
++ * set ticket options
++ * by looking at krb5.conf, the passed in creds and gconf
++ */
+ static void
+ set_options_from_creds(const KaApplet* applet,
+- krb5_context context G_GNUC_UNUSED,
++ krb5_context context,
+ krb5_creds *in,
+ krb5_get_init_creds_opt *out)
+ {
+@@ -388,8 +419,8 @@ set_options_from_creds(const KaApplet* applet,
+ int flag;
+
+ #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
+- krb5_get_init_creds_opt_set_default_flags(kcontext, PACKAGE,
+- krb5_principal_get_realm(kcontext, kprincipal), out);
++ krb5_get_init_creds_opt_set_default_flags(context, PACKAGE,
++ krb5_principal_get_realm(context, kprincipal), out);
+ #endif
+
+ flag = get_cred_forwardable(in) != 0;
+@@ -426,7 +457,7 @@ ka_auth_pkinit(KaApplet* applet, krb5_creds* creds, const char* pk_userid)
+ retval = krb5_get_init_creds_opt_alloc (kcontext, &opts);
+ if (retval)
+ goto out;
+- set_options_from_creds (applet, kcontext, creds, opts);
++ ka_set_ticket_options (applet, opts);
+
+ retval = krb5_get_init_creds_opt_set_pkinit(kcontext, opts,
+ kprincipal,
+@@ -461,7 +492,7 @@ ka_auth_password(KaApplet* applet, krb5_creds* creds)
+ retval = krb5_get_init_creds_opt_alloc (kcontext, &opts);
+ if (retval)
+ goto out;
+- set_options_from_creds (applet, kcontext, creds, opts);
++ ka_set_ticket_options (applet, opts);
+ retval = krb5_get_init_creds_password(kcontext, creds, kprincipal,
+ NULL, auth_dialog_prompter, applet,
+ 0, NULL, opts);
+@@ -477,9 +508,7 @@ ka_parse_name(KaApplet* applet, krb5_context krbcontext, krb5_principal* kprinc)
+ krb5_error_code ret;
+ gchar *principal = NULL;
+
+- g_object_get(applet, "principal", &principal,
+- NULL);
+-
++ g_object_get(applet, "principal", &principal, NULL);
+ ret = krb5_parse_name(krbcontext, principal,
+ kprinc);
+
+@@ -773,8 +802,7 @@ ka_check_credentials (KaApplet *applet, const char* newprincipal)
+ int retval;
+ char* principal;
+
+- g_object_get(applet, "principal", &principal,
+- NULL);
++ g_object_get(applet, "principal", &principal, NULL);
+
+ if (strlen(newprincipal)) {
+ krb5_principal knewprinc;
+@@ -817,7 +845,6 @@ gboolean
+ ka_grab_credentials (KaApplet* applet)
+ {
+ int retval;
+- gboolean retry;
+ int success = FALSE;
+ KaPwDialog *pwdialog = ka_applet_get_pwdialog(applet);
+
+diff --git a/src/krb5-auth-dialog.schemas.in b/src/krb5-auth-dialog.schemas.in
+index 2a3a707..13b05b2 100644
+--- a/src/krb5-auth-dialog.schemas.in
++++ b/src/krb5-auth-dialog.schemas.in
+@@ -51,5 +51,44 @@
+ <long>Start prompting/displaying notifications that many minutes before expiry</long>
+ </locale>
+ </schema>
++
++ <schema>
++ <key>/schemas/apps/::PACKAGE::/forwardable</key>
++ <applyto>/apps/::PACKAGE::/forwardable</applyto>
++ <owner>::PACKAGE::</owner>
++ <type>bool</type>
++ <default>0</default>
++
++ <locale name="C">
++ <short>Forwardable ticket</short>
++ <long>Requested tickets should be forwardable</long>
++ </locale>
++ </schema>
++
++ <schema>
++ <key>/schemas/apps/::PACKAGE::/renewable</key>
++ <applyto>/apps/::PACKAGE::/renewable</applyto>
++ <owner>::PACKAGE::</owner>
++ <type>bool</type>
++ <default>0</default>
++
++ <locale name="C">
++ <short>Renewable ticket</short>
++ <long>Requested tickets should be renewable</long>
++ </locale>
++ </schema>
++
++ <schema>
++ <key>/schemas/apps/::PACKAGE::/proxiable</key>
++ <applyto>/apps/::PACKAGE::/proxiable</applyto>
++ <owner>::PACKAGE::</owner>
++ <type>bool</type>
++ <default>0</default>
++
++ <locale name="C">
++ <short>Proxiable ticket</short>
++ <long>Requested tickets should be proxiable</long>
++ </locale>
++ </schema>
+ </schemalist>
+ </gconfschemafile>
+diff --git a/src/krb5-auth-gconf-tools.c b/src/krb5-auth-gconf-tools.c
+new file mode 100644
+index 0000000..e6541c1
+--- /dev/null
++++ b/src/krb5-auth-gconf-tools.c
+@@ -0,0 +1,103 @@
++/* Krb5 Auth Applet -- Acquire and release kerberos tickets
++ *
++ * (C) 2008,2009 Guido Guenther <agx@sigxcpu.org>
++ *
++ * 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 of the License, 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 <gconf/gconf-client.h>
++#include <krb5-auth-gconf-tools.h>
++
++gboolean
++ka_gconf_get_string (GConfClient* client,
++ const char* key,
++ char** value)
++{
++ GError* error = NULL;
++ gboolean success = FALSE;
++ GConfValue* gc_value;
++
++ g_return_val_if_fail (key != NULL, FALSE);
++ g_return_val_if_fail (*value == NULL, FALSE);
++
++ if ((gc_value = gconf_client_get (client, key, &error))) {
++ if (gc_value->type == GCONF_VALUE_STRING) {
++ *value = g_strdup (gconf_value_get_string (gc_value));
++ success = TRUE;
++ } else if (error) {
++ g_print (error->message);
++ g_error_free (error);
++ }
++ gconf_value_free (gc_value);
++ }
++ return success;
++}
++
++
++gboolean
++ka_gconf_get_int (GConfClient* client,
++ const char* key,
++ int* value)
++{
++ GError* error = NULL;
++ gboolean success = FALSE;
++ GConfValue* gc_value;
++
++ g_return_val_if_fail (key != NULL, FALSE);
++ g_return_val_if_fail (value != NULL, FALSE);
++
++ if ((gc_value = gconf_client_get (client, key, &error)))
++ {
++ if (gc_value->type == GCONF_VALUE_INT) {
++ *value = gconf_value_get_int (gc_value);
++ success = TRUE;
++ } else if (error) {
++ g_print (error->message);
++ g_error_free (error);
++ }
++ gconf_value_free (gc_value);
++ }
++ return success;
++}
++
++
++gboolean
++ka_gconf_get_bool (GConfClient* client,
++ const char* key,
++ gboolean* value)
++{
++ GError* error = NULL;
++ gboolean success = FALSE;
++ GConfValue* gc_value;
++
++ g_return_val_if_fail (key != NULL, FALSE);
++ g_return_val_if_fail (value != NULL, FALSE);
++
++ if ((gc_value = gconf_client_get (client, key, &error)))
++ {
++ if (gc_value->type == GCONF_VALUE_BOOL) {
++ *value = gconf_value_get_bool (gc_value);
++ success = TRUE;
++ } else if (error) {
++ g_print (error->message);
++ g_error_free (error);
++ }
++ gconf_value_free (gc_value);
++ }
++ return success;
++}
++
+diff --git a/src/krb5-auth-gconf-tools.h b/src/krb5-auth-gconf-tools.h
+new file mode 100644
+index 0000000..9786b2f
+--- /dev/null
++++ b/src/krb5-auth-gconf-tools.h
+@@ -0,0 +1,41 @@
++/* Krb5 Auth Applet -- Acquire and release kerberos tickets
++ *
++ * (C) 2008,2009 Guido Guenther <agx@sigxcpu.org>
++ *
++ * 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 of the License, 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.
++ *
++ */
++
++#ifndef KRB5_AUTH_GCONF_TOOLS_H
++#define KRB5_AUTH_GCONF_TOOLS_H
++
++#include "config.h"
++
++#include <gconf/gconf-client.h>
++
++#define KA_GCONF_PATH "/apps/" PACKAGE
++#define KA_GCONF_KEY_PRINCIPAL KA_GCONF_PATH "/principal"
++#define KA_GCONF_KEY_PK_USERID KA_GCONF_PATH "/pk_userid"
++#define KA_GCONF_KEY_PROMPT_MINS KA_GCONF_PATH "/prompt_minutes"
++#define KA_GCONF_KEY_SHOW_TRAYICON KA_GCONF_PATH "/show_trayicon"
++#define KA_GCONF_KEY_FORWARDABLE KA_GCONF_PATH "/forwardable"
++#define KA_GCONF_KEY_RENEWABLE KA_GCONF_PATH "/renewable"
++#define KA_GCONF_KEY_PROXIABLE KA_GCONF_PATH "/proxiable"
++
++gboolean ka_gconf_get_string (GConfClient* client, const char* key, char** value);
++gboolean ka_gconf_get_int (GConfClient* client, const char* key, int* value);
++gboolean ka_gconf_get_bool (GConfClient* client, const char* key, gboolean* value);
++
++#endif
+diff --git a/src/krb5-auth-gconf.c b/src/krb5-auth-gconf.c
+index 1481591..25eb555 100644
+--- a/src/krb5-auth-gconf.c
++++ b/src/krb5-auth-gconf.c
+@@ -22,94 +22,9 @@
+ #include <gconf/gconf-client.h>
+
+ #include "krb5-auth-applet.h"
++#include "krb5-auth-gconf-tools.h"
+ #include "krb5-auth-gconf.h"
+
+-#define KA_GCONF_PATH "/apps/" PACKAGE
+-#define KA_GCONF_KEY_PRINCIPAL KA_GCONF_PATH "/principal"
+-#define KA_GCONF_KEY_PK_USERID KA_GCONF_PATH "/pk_userid"
+-#define KA_GCONF_KEY_PROMPT_MINS KA_GCONF_PATH "/prompt_minutes"
+-#define KA_GCONF_KEY_SHOW_TRAYICON KA_GCONF_PATH "/show_trayicon"
+-
+-static gboolean
+-ka_gconf_get_string (GConfClient* client,
+- const char* key,
+- char** value)
+-{
+- GError* error = NULL;
+- gboolean success = FALSE;
+- GConfValue* gc_value;
+-
+- g_return_val_if_fail (key != NULL, FALSE);
+- g_return_val_if_fail (*value == NULL, FALSE);
+-
+- if ((gc_value = gconf_client_get (client, key, &error))) {
+- if (gc_value->type == GCONF_VALUE_STRING) {
+- *value = g_strdup (gconf_value_get_string (gc_value));
+- success = TRUE;
+- } else if (error) {
+- g_print (error->message);
+- g_error_free (error);
+- }
+- gconf_value_free (gc_value);
+- }
+- return success;
+-}
+-
+-
+-static gboolean
+-ka_gconf_get_int (GConfClient* client,
+- const char* key,
+- int* value)
+-{
+- GError* error = NULL;
+- gboolean success = FALSE;
+- GConfValue* gc_value;
+-
+- g_return_val_if_fail (key != NULL, FALSE);
+- g_return_val_if_fail (value != NULL, FALSE);
+-
+- if ((gc_value = gconf_client_get (client, key, &error)))
+- {
+- if (gc_value->type == GCONF_VALUE_INT) {
+- *value = gconf_value_get_int (gc_value);
+- success = TRUE;
+- } else if (error) {
+- g_print (error->message);
+- g_error_free (error);
+- }
+- gconf_value_free (gc_value);
+- }
+- return success;
+-}
+-
+-
+-static gboolean
+-ka_gconf_get_bool (GConfClient* client,
+- const char* key,
+- gboolean* value)
+-{
+- GError* error = NULL;
+- gboolean success = FALSE;
+- GConfValue* gc_value;
+-
+- g_return_val_if_fail (key != NULL, FALSE);
+- g_return_val_if_fail (value != NULL, FALSE);
+-
+- if ((gc_value = gconf_client_get (client, key, &error)))
+- {
+- if (gc_value->type == GCONF_VALUE_BOOL) {
+- *value = gconf_value_get_bool (gc_value);
+- success = TRUE;
+- } else if (error) {
+- g_print (error->message);
+- g_error_free (error);
+- }
+- gconf_value_free (gc_value);
+- }
+- return success;
+-}
+-
+-
+ static gboolean
+ ka_gconf_set_principal (GConfClient* client, KaApplet* applet)
+ {
+@@ -164,6 +79,45 @@ ka_gconf_set_show_trayicon (GConfClient* client, KaApplet* applet)
+ }
+
+
++static gboolean
++ka_gconf_set_tgt_forwardable (GConfClient* client, KaApplet* applet)
++{
++ gboolean forwardable = FALSE;
++
++ if(!ka_gconf_get_bool(client, KA_GCONF_KEY_FORWARDABLE, &forwardable)) {
++ forwardable = TRUE;
++ }
++ g_object_set(applet, "tgt-forwardable", forwardable, NULL);
++ return TRUE;
++}
++
++
++static gboolean
++ka_gconf_set_tgt_renewable (GConfClient* client, KaApplet* applet)
++{
++ gboolean renewable = FALSE;
++
++ if(!ka_gconf_get_bool(client, KA_GCONF_KEY_RENEWABLE, &renewable)) {
++ renewable = TRUE;
++ }
++ g_object_set(applet, "tgt-renewable", renewable, NULL);
++ return TRUE;
++}
++
++
++static gboolean
++ka_gconf_set_tgt_proxiable (GConfClient* client, KaApplet* applet)
++{
++ gboolean proxiable = FALSE;
++
++ if(!ka_gconf_get_bool(client, KA_GCONF_KEY_PROXIABLE, &proxiable)) {
++ proxiable = TRUE;
++ }
++ g_object_set(applet, "tgt-proxiable", proxiable, NULL);
++ return TRUE;
++}
++
++
+ static void
+ ka_gconf_key_changed_callback (GConfClient* client,
+ guint cnxn_id G_GNUC_UNUSED,
+@@ -186,6 +140,12 @@ ka_gconf_key_changed_callback (GConfClient* client,
+ ka_gconf_set_show_trayicon (client, applet);
+ } else if (g_strcmp0 (key, KA_GCONF_KEY_PK_USERID) == 0) {
+ ka_gconf_set_pk_userid (client, applet);
++ } else if (g_strcmp0 (key, KA_GCONF_KEY_FORWARDABLE) == 0) {
++ ka_gconf_set_tgt_forwardable (client, applet);
++ } else if (g_strcmp0 (key, KA_GCONF_KEY_RENEWABLE) == 0) {
++ ka_gconf_set_tgt_renewable (client, applet);
++ } else if (g_strcmp0 (key, KA_GCONF_KEY_PROXIABLE) == 0) {
++ ka_gconf_set_tgt_proxiable (client, applet);
+ } else
+ g_warning("Received notification for unknown gconf key %s", key);
+ return;
+@@ -216,6 +176,9 @@ ka_gconf_init (KaApplet* applet,
+ ka_gconf_set_prompt_mins (client, applet);
+ ka_gconf_set_show_trayicon (client, applet);
+ ka_gconf_set_pk_userid(client, applet);
++ ka_gconf_set_tgt_forwardable(client, applet);
++ ka_gconf_set_tgt_renewable(client, applet);
++ ka_gconf_set_tgt_proxiable(client, applet);
+
+ success = TRUE;
+ out:
+--
diff --git a/debian/patches/series b/debian/patches/series
index be39b47..2036199 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
0001-set-a-more-gnomeisch-invisible-char.patch
0002-add-dbus-service-file.patch
+0003-add-preferences-dialog.patch
bgstack15