Minor changelog updates
[pidgin-git.git] / pidgin / gtkconn.c
blob2a020684dee014a33a8dc4b46051618b623d9b62
1 /*
2 * @file gtkconn.c GTK+ Connection API
3 * @ingroup pidgin
4 */
6 /* pidgin
8 * Pidgin is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 #include "internal.h"
27 #include "pidgin.h"
29 #include "account.h"
30 #include "debug.h"
31 #include "notify.h"
32 #include "prefs.h"
33 #include "gtkblist.h"
34 #include "gtkconn.h"
35 #include "gtkdialogs.h"
36 #include "gtkstatusbox.h"
37 #include "pidginstock.h"
38 #include "gtkutils.h"
39 #include "util.h"
41 #define INITIAL_RECON_DELAY_MIN 8000
42 #define INITIAL_RECON_DELAY_MAX 60000
44 #define MAX_RECON_DELAY 600000
46 typedef struct {
47 int delay;
48 guint timeout;
49 } PidginAutoRecon;
51 /**
52 * Contains accounts that are auto-reconnecting.
53 * The key is a pointer to the PurpleAccount and the
54 * value is a pointer to a PidginAutoRecon.
56 static GHashTable *hash = NULL;
58 static void
59 pidgin_connection_connect_progress(PurpleConnection *gc,
60 const char *text, size_t step, size_t step_count)
62 PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
63 if (!gtkblist)
64 return;
65 pidgin_status_box_set_connecting(PIDGIN_STATUS_BOX(gtkblist->statusbox),
66 (purple_connections_get_connecting() != NULL));
67 pidgin_status_box_pulse_connecting(PIDGIN_STATUS_BOX(gtkblist->statusbox));
70 static void
71 pidgin_connection_connected(PurpleConnection *gc)
73 PurpleAccount *account;
74 PidginBuddyList *gtkblist;
76 account = purple_connection_get_account(gc);
77 gtkblist = pidgin_blist_get_default_gtk_blist();
79 if (gtkblist != NULL)
80 pidgin_status_box_set_connecting(PIDGIN_STATUS_BOX(gtkblist->statusbox),
81 (purple_connections_get_connecting() != NULL));
83 g_hash_table_remove(hash, account);
85 pidgin_blist_update_account_error_state(account, NULL);
88 static void
89 pidgin_connection_disconnected(PurpleConnection *gc)
91 PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
92 if (!gtkblist)
93 return;
94 pidgin_status_box_set_connecting(PIDGIN_STATUS_BOX(gtkblist->statusbox),
95 (purple_connections_get_connecting() != NULL));
97 if (purple_connections_get_all() != NULL)
98 return;
100 pidgin_dialogs_destroy_all();
103 static void
104 free_auto_recon(gpointer data)
106 PidginAutoRecon *info = data;
108 if (info->timeout != 0)
109 g_source_remove(info->timeout);
111 g_free(info);
114 static gboolean
115 do_signon(gpointer data)
117 PurpleAccount *account = data;
118 PidginAutoRecon *info;
119 PurpleStatus *status;
121 purple_debug_info("autorecon", "do_signon called\n");
122 g_return_val_if_fail(account != NULL, FALSE);
123 info = g_hash_table_lookup(hash, account);
125 if (info)
126 info->timeout = 0;
128 status = purple_account_get_active_status(account);
129 if (purple_status_is_online(status))
131 purple_debug_info("autorecon", "calling purple_account_connect\n");
132 purple_account_connect(account);
133 purple_debug_info("autorecon", "done calling purple_account_connect\n");
136 return FALSE;
139 static void
140 pidgin_connection_report_disconnect(PurpleConnection *gc, const char *text)
142 PurpleAccount *account = NULL;
143 PidginAutoRecon *info;
145 account = purple_connection_get_account(gc);
146 info = g_hash_table_lookup(hash, account);
148 pidgin_blist_update_account_error_state(account, text);
149 if (!gc->wants_to_die) {
150 if (info == NULL) {
151 info = g_new0(PidginAutoRecon, 1);
152 g_hash_table_insert(hash, account, info);
153 info->delay = g_random_int_range(INITIAL_RECON_DELAY_MIN, INITIAL_RECON_DELAY_MAX);
154 } else {
155 info->delay = MIN(2 * info->delay, MAX_RECON_DELAY);
156 if (info->timeout != 0)
157 g_source_remove(info->timeout);
159 info->timeout = g_timeout_add(info->delay, do_signon, account);
160 } else {
161 char *p, *s, *n=NULL ;
162 if (info != NULL)
163 g_hash_table_remove(hash, account);
165 if (purple_account_get_alias(account))
167 n = g_strdup_printf("%s (%s) (%s)",
168 purple_account_get_username(account),
169 purple_account_get_alias(account),
170 purple_account_get_protocol_name(account));
172 else
174 n = g_strdup_printf("%s (%s)",
175 purple_account_get_username(account),
176 purple_account_get_protocol_name(account));
179 p = g_strdup_printf(_("%s disconnected"), n);
180 s = g_strdup_printf(_("%s\n\n"
181 "%s will not attempt to reconnect the account until you "
182 "correct the error and re-enable the account."), text, PIDGIN_NAME);
183 purple_notify_error(NULL, NULL, p, s);
184 g_free(p);
185 g_free(s);
186 g_free(n);
189 * TODO: Do we really want to disable the account when it's
190 * disconnected by wants_to_die? This happens when you sign
191 * on from somewhere else, or when you enter an invalid password.
193 purple_account_set_enabled(account, PIDGIN_UI, FALSE);
197 static void pidgin_connection_network_connected ()
199 GList *list = purple_accounts_get_all_active();
200 PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
202 if(gtkblist)
203 pidgin_status_box_set_network_available(PIDGIN_STATUS_BOX(gtkblist->statusbox), TRUE);
205 while (list) {
206 PurpleAccount *account = (PurpleAccount*)list->data;
207 g_hash_table_remove(hash, account);
208 if (purple_account_is_disconnected(account))
209 do_signon(account);
210 list = list->next;
214 static void pidgin_connection_network_disconnected ()
216 GList *l = purple_accounts_get_all_active();
217 PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist();
218 PurplePluginProtocolInfo *prpl_info = NULL;
219 PurpleConnection *gc = NULL;
221 if(gtkblist)
222 pidgin_status_box_set_network_available(PIDGIN_STATUS_BOX(gtkblist->statusbox), FALSE);
224 while (l) {
225 PurpleAccount *a = (PurpleAccount*)l->data;
226 if (!purple_account_is_disconnected(a)) {
227 gc = purple_account_get_connection(a);
228 if (gc && gc->prpl)
229 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
230 if (prpl_info) {
231 if (prpl_info->keepalive)
232 prpl_info->keepalive(gc);
233 else
234 purple_account_disconnect(a);
237 l = l->next;
241 static void pidgin_connection_notice(PurpleConnection *gc, const char *text)
244 static PurpleConnectionUiOps conn_ui_ops =
246 pidgin_connection_connect_progress,
247 pidgin_connection_connected,
248 pidgin_connection_disconnected,
249 pidgin_connection_notice,
250 pidgin_connection_report_disconnect,
251 pidgin_connection_network_connected,
252 pidgin_connection_network_disconnected,
253 NULL,
254 NULL,
255 NULL,
256 NULL
259 PurpleConnectionUiOps *
260 pidgin_connections_get_ui_ops(void)
262 return &conn_ui_ops;
265 static void
266 account_removed_cb(PurpleAccount *account, gpointer user_data)
268 g_hash_table_remove(hash, account);
270 pidgin_blist_update_account_error_state(account, NULL);
274 /**************************************************************************
275 * GTK+ connection glue
276 **************************************************************************/
278 void *
279 pidgin_connection_get_handle(void)
281 static int handle;
283 return &handle;
286 void
287 pidgin_connection_init(void)
289 hash = g_hash_table_new_full(
290 g_direct_hash, g_direct_equal,
291 NULL, free_auto_recon);
293 purple_signal_connect(purple_accounts_get_handle(), "account-removed",
294 pidgin_connection_get_handle(),
295 PURPLE_CALLBACK(account_removed_cb), NULL);
298 void
299 pidgin_connection_uninit(void)
301 purple_signals_disconnect_by_handle(pidgin_connection_get_handle());
303 g_hash_table_destroy(hash);