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