im.pidgin.cpw.resiak.disconnectreason: 7d0f6877ed2d6879f6cb69989b5eb04d633c1c93

resiak at soc.pidgin.im resiak at soc.pidgin.im
Sat Oct 27 13:51:18 EDT 2007


-----------------------------------------------------------------
Revision: 7d0f6877ed2d6879f6cb69989b5eb04d633c1c93
Ancestor: 317b14176c8bcdd9ca54500d252f6a9efa6f2579
Author: resiak at soc.pidgin.im
Date: 2007-10-27T17:26:17
Branch: im.pidgin.cpw.resiak.disconnectreason

Modified files:
        doc/account-signals.dox libpurple/account.c
        libpurple/account.h

ChangeLog: 

Make PurpleAccount keep track of the last connection error suffered (or not, if
the account is happily connected or is disconnected without error).  Add a
signal which fires when the current error changes, and an accessor to get the
current error.  The error itself is stored inside a private struct.

-------------- next part --------------
============================================================
--- doc/account-signals.dox	416caefbaa4b7971aedb3e4b0acf1933f182c97b
+++ doc/account-signals.dox	d22e0c89753f0ac1c592e54b25e3c6369035f5d5
@@ -12,6 +12,7 @@
   @signal account-authorization-requested
   @signal account-authorization-denied
   @signal account-authorization-granted
+  @signal account-error-changed
  @endsignals
 
  @see account.h
@@ -141,5 +142,17 @@ void (*account_authorization_granted)(Pu
   @since 2.3.0
  @endsignaldef
 
+ @signaldef account-error-changed
+  @signalproto
+void (*account_error_changed)(PurpleAccount *account, const PurpleAccountCurrentError *current_error);
+  @endsignalproto
+  @signaldesc
+   Emitted when @a account's error changes.
+  @param account       The account whose error has changed.
+  @param current_error The account's current error, or @c NULL if it has no error.
+  @see purple_account_get_current_error()
+  @since 2.3.0
+ @endsignaldef
+
  */
 // vim: syntax=c.doxygen tw=75 et
============================================================
--- libpurple/account.c	619314d2997f1441f4a9f8524867bcd23584dab9
+++ libpurple/account.c	38d2e4fafde1c709cb025e302889e586e85a11c0
@@ -41,6 +41,14 @@
 #include "util.h"
 #include "xmlnode.h"
 
+typedef struct
+{
+	PurpleAccountCurrentError *current_error;
+} PurpleAccountPrivate;
+
+#define PURPLE_ACCOUNT_GET_PRIVATE(account) \
+	((PurpleAccountPrivate *) (account->priv))
+
 /* TODO: Should use PurpleValue instead of this?  What about "ui"? */
 typedef struct
 {
@@ -77,6 +85,8 @@ static GList *handles = NULL;
 
 static GList *handles = NULL;
 
+static void clear_current_error(PurpleAccount *account);
+
 /*********************************************************************
  * Writing to disk                                                   *
  *********************************************************************/
@@ -827,6 +837,7 @@ purple_account_new(const char *username,
 purple_account_new(const char *username, const char *protocol_id)
 {
 	PurpleAccount *account = NULL;
+	PurpleAccountPrivate *priv = NULL;
 	PurplePlugin *prpl = NULL;
 	PurplePluginProtocolInfo *prpl_info = NULL;
 	PurpleStatusType *status_type;
@@ -841,6 +852,8 @@ purple_account_new(const char *username,
 
 	account = g_new0(PurpleAccount, 1);
 	PURPLE_DBUS_REGISTER_POINTER(account, PurpleAccount);
+	priv = g_new0(PurpleAccountPrivate, 1);
+	account->priv = priv;
 
 	purple_account_set_username(account, username);
 
@@ -881,6 +894,7 @@ purple_account_destroy(PurpleAccount *ac
 void
 purple_account_destroy(PurpleAccount *account)
 {
+	PurpleAccountPrivate *priv = NULL;
 	GList *l;
 
 	g_return_if_fail(account != NULL);
@@ -912,6 +926,10 @@ purple_account_destroy(PurpleAccount *ac
 	if(account->system_log)
 		purple_log_free(account->system_log);
 
+	priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+	g_free(priv->current_error);
+	g_free(priv);
+
 	PURPLE_DBUS_UNREGISTER_POINTER(account);
 	g_free(account);
 }
@@ -2214,6 +2232,53 @@ gboolean purple_account_supports_offline
 	return prpl_info->offline_message(buddy);
 }
 
+static void
+clear_current_error(PurpleAccount *account)
+{
+	PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+	if (priv->current_error)
+	{
+		g_free (priv->current_error);
+		priv->current_error = NULL;
+	}
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-error-changed",
+	                   account, priv->current_error);
+}
+
+static void
+signed_on_cb(PurpleConnection *gc,
+             gpointer unused)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	clear_current_error(account);
+}
+
+static void
+connection_error_cb(PurpleConnection *gc,
+                    PurpleConnectionError err,
+                    const gchar *desc,
+                    gpointer unused)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+
+	if (!priv->current_error)
+		priv->current_error = g_new0(PurpleAccountCurrentError, 1);
+	priv->current_error->reason = err;
+	priv->current_error->description = desc;
+
+	purple_signal_emit(purple_accounts_get_handle(), "account-error-changed",
+	                   account, priv->current_error);
+}
+
+const PurpleAccountCurrentError *
+purple_account_get_current_error(PurpleAccount *account)
+{
+	PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account);
+	return priv->current_error;
+}
+
 void
 purple_accounts_add(PurpleAccount *account)
 {
@@ -2238,6 +2303,7 @@ purple_accounts_remove(PurpleAccount *ac
 
 	schedule_accounts_save();
 
+	clear_current_error(account);
 	purple_signal_emit(purple_accounts_get_handle(), "account-removed", account);
 }
 
@@ -2443,6 +2509,7 @@ purple_accounts_init(void)
 purple_accounts_init(void)
 {
 	void *handle = purple_accounts_get_handle();
+	void *conn_handle = purple_connections_get_handle();
 
 	purple_signal_register(handle, "account-connecting",
 						 purple_marshal_VOID__POINTER, NULL, 1,
@@ -2513,6 +2580,15 @@ purple_accounts_init(void)
 										PURPLE_SUBTYPE_ACCOUNT),
 						purple_value_new(PURPLE_TYPE_STRING));
 
+	purple_signal_register(handle, "account-error-changed",
+	                       purple_marshal_VOID__POINTER_POINTER, NULL, 2,
+	                       purple_value_new(PURPLE_TYPE_SUBTYPE,
+	                                        PURPLE_SUBTYPE_ACCOUNT),
+	                       purple_value_new(PURPLE_TYPE_POINTER));
+
+	purple_signal_connect(conn_handle, "signed-on", handle,
+	                      PURPLE_CALLBACK(signed_on_cb), NULL);
+
 	load_accounts();
 
 }
@@ -2520,6 +2596,7 @@ purple_accounts_uninit(void)
 void
 purple_accounts_uninit(void)
 {
+	gpointer handle = purple_accounts_get_handle();
 	if (save_timer != 0)
 	{
 		purple_timeout_remove(save_timer);
@@ -2527,5 +2604,6 @@ purple_accounts_uninit(void)
 		sync_accounts();
 	}
 
-	purple_signals_unregister_by_instance(purple_accounts_get_handle());
+	purple_signals_disconnect_by_handle(handle);
+	purple_signals_unregister_by_instance(handle);
 }
============================================================
--- libpurple/account.h	f48b8e6b688a5aebdcc74511f2d3f7d8e36abc64
+++ libpurple/account.h	da0e3b8520363230289ba5ec6798b79f8027d83f
@@ -140,8 +140,19 @@ struct _PurpleAccount
 	void *ui_data;              /**< The UI can put data here.              */
 	PurpleAccountRegistrationCb registration_cb;
 	void *registration_cb_user_data;
+
+	gpointer priv;              /**< Pointer to opaque private data. */
 };
 
+/** The error most recently encountered on an account. */
+typedef struct
+{
+	/** The type of error. */
+	PurpleConnectionError reason;
+	/** A localised, human-readable description of the error. */
+	const char *description;
+} PurpleAccountCurrentError;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -893,6 +904,16 @@ gboolean purple_account_supports_offline
  */
 gboolean purple_account_supports_offline_message(PurpleAccount *account, PurpleBuddy *buddy);
 
+/**
+ * Get the error that caused the account to be disconnected, or @c NULL if the
+ * account is happily connected or disconnected without an error.
+ *
+ * @param account The account whose error should be retrieved.
+ * @constreturn   The type of error and a human-readable description of the
+ *                current error, or @c NULL if there is no current error.
+ */
+const PurpleAccountCurrentError *purple_account_get_current_error(PurpleAccount *account);
+
 /*@}*/
 
 /**************************************************************************/


More information about the Commits mailing list