[gcr] gcr: Add 'new-prompt' signal to GcrSystemPrompter



commit a64e3bf65a741c0787e280d77c5b43a192a571ad
Author: Stef Walter <stefw collabora co uk>
Date:   Mon Jan 9 15:33:07 2012 +0100

    gcr: Add 'new-prompt' signal to GcrSystemPrompter
    
     * A signal which creates and returns a prompt. The first new-prompt
       signal handler to return a non-null GcrPrompt 'wins'
     * This is for use in gnome-shell where we can't set a prompt-gtype

 gcr/gcr-marshal.list      |    1 +
 gcr/gcr-system-prompter.c |   54 ++++++++++++++++++++++++++++++++++++++++++--
 gcr/gcr-system-prompter.h |   12 ++++++++++
 3 files changed, 64 insertions(+), 3 deletions(-)
---
diff --git a/gcr/gcr-marshal.list b/gcr/gcr-marshal.list
index 5e36589..d2eda8f 100644
--- a/gcr/gcr-marshal.list
+++ b/gcr/gcr-marshal.list
@@ -1,5 +1,6 @@
 BOOLEAN:INT
 BOOLEAN:BOXED
+OBJECT:VOID
 VOID:STRING,BOXED
 VOID:BOXED
 VOID:STRING
diff --git a/gcr/gcr-system-prompter.c b/gcr/gcr-system-prompter.c
index 82195f7..c86e97c 100644
--- a/gcr/gcr-system-prompter.c
+++ b/gcr/gcr-system-prompter.c
@@ -30,6 +30,7 @@
 #include "gcr-enum-types-base.h"
 #include "gcr-internal.h"
 #include "gcr-library.h"
+#include "gcr-marshal.h"
 #include "gcr-prompt.h"
 #include "gcr-secret-exchange.h"
 #include "gcr-system-prompter.h"
@@ -61,6 +62,8 @@
 
 /**
  * GcrSystemPrompterClass:
+ * @parent_class: parent class
+ * @new_prompt: default handler for the GcrSystemPrompter::new-prompt signal
  *
  * The class for #GcrSystemPrompter.
  */
@@ -81,8 +84,9 @@ enum {
 	PROP_PROMPTING
 };
 
-struct _GcrSystemPrompterClass {
-	GObjectClass parent_class;
+enum {
+	NEW_PROMPT,
+	LAST_SIGNAL,
 };
 
 struct _GcrSystemPrompterPrivate {
@@ -97,6 +101,8 @@ struct _GcrSystemPrompterPrivate {
 	GQueue waiting;
 };
 
+static guint signals[LAST_SIGNAL] = { 0, };
+
 G_DEFINE_TYPE (GcrSystemPrompter, gcr_system_prompter, G_TYPE_OBJECT);
 
 typedef struct {
@@ -222,7 +228,9 @@ active_prompt_create (GcrSystemPrompter *self,
 	active->refs = 1;
 	active->prompter = g_object_ref (self);
 	active->cancellable = g_cancellable_new ();
-	active->prompt = g_object_new (self->pv->prompt_type, NULL);
+	g_signal_emit (self, signals[NEW_PROMPT], 0, &active->prompt);
+	g_return_val_if_fail (active->prompt != NULL, NULL);
+
 	active->notify_sig = g_signal_connect (active->prompt, "notify", G_CALLBACK (on_prompt_notify), active);
 	active->changed = g_hash_table_new (g_direct_hash, g_direct_equal);
 
@@ -324,6 +332,27 @@ gcr_system_prompter_finalize (GObject *obj)
 	G_OBJECT_CLASS (gcr_system_prompter_parent_class)->finalize (obj);
 }
 
+static GcrPrompt *
+gcr_system_prompter_new_prompt (GcrSystemPrompter *self)
+{
+	g_return_val_if_fail (self->pv->prompt_type != 0, NULL);
+	return g_object_new (self->pv->prompt_type, NULL);
+}
+
+static gboolean
+gcr_system_prompter_new_prompt_acculmulator (GSignalInvocationHint *ihint,
+                                             GValue *return_accu,
+                                             const GValue *handler_return,
+                                             gpointer user_data)
+{
+	if (g_value_get_object (handler_return) != NULL) {
+		g_value_copy (handler_return, return_accu);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 static void
 gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
 {
@@ -334,6 +363,8 @@ gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
 	gobject_class->dispose = gcr_system_prompter_dispose;
 	gobject_class->finalize = gcr_system_prompter_finalize;
 
+	klass->new_prompt = gcr_system_prompter_new_prompt;
+
 	g_type_class_add_private (gobject_class, sizeof (GcrSystemPrompterPrivate));
 
 	/**
@@ -369,6 +400,21 @@ gcr_system_prompter_class_init (GcrSystemPrompterClass *klass)
 	           g_param_spec_boolean ("prompting", "Prompting", "Whether prompting or not",
 	                                 FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+	/**
+	 * GcrSystemPrompter::new-prompt:
+	 *
+	 * Signal emitted to create a new prompt when needed.
+	 *
+	 * The default implementation of this signal creates a prompt of the type
+	 * gcr_system_prompter_get_prompt_type().
+	 *
+	 * Returns: (transfer full): the new prompt
+	 */
+	signals[NEW_PROMPT] = g_signal_new ("new-prompt", GCR_TYPE_SYSTEM_PROMPTER, G_SIGNAL_RUN_LAST,
+	                                    G_STRUCT_OFFSET (GcrSystemPrompterClass, new_prompt),
+	                                    gcr_system_prompter_new_prompt_acculmulator, NULL,
+	                                    _gcr_marshal_OBJECT__VOID,
+	                                    GCR_TYPE_PROMPT, 0, G_TYPE_NONE);
 }
 
 static GVariantBuilder *
@@ -579,6 +625,8 @@ prompt_next_ready (GcrSystemPrompter *self)
 	g_assert (active == NULL);
 
 	active = active_prompt_create (self, callback);
+	g_return_if_fail (active != NULL);
+
 	prompt_send_ready (active, GCR_DBUS_PROMPT_REPLY_NONE, NULL);
 }
 
diff --git a/gcr/gcr-system-prompter.h b/gcr/gcr-system-prompter.h
index f6f04d3..189ab83 100644
--- a/gcr/gcr-system-prompter.h
+++ b/gcr/gcr-system-prompter.h
@@ -28,6 +28,7 @@
 #ifndef __GCR_SYSTEM_PROMPTER_H__
 #define __GCR_SYSTEM_PROMPTER_H__
 
+#include "gcr-prompt.h"
 #include "gcr-secret-exchange.h"
 #include "gcr-types.h"
 
@@ -58,6 +59,17 @@ struct _GcrSystemPrompter {
 	GcrSystemPrompterPrivate *pv;
 };
 
+struct _GcrSystemPrompterClass {
+	GObjectClass parent_class;
+
+	/* signals */
+
+	GcrPrompt *    (* new_prompt)     (GcrSystemPrompter *self);
+
+	/*< private >*/
+	gpointer padding[7];
+};
+
 GType                  gcr_system_prompter_get_type                (void) G_GNUC_CONST;
 
 GcrSystemPrompter *    gcr_system_prompter_new                     (GcrSystemPrompterMode mode,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]