comparison pidgin/gtkconn.c @ 15374:5fe8042783c1

Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author Sean Egan <seanegan@gmail.com>
date Sat, 20 Jan 2007 02:32:10 +0000
parents
children d54794a47c56
comparison
equal deleted inserted replaced
15373:f79e0f4df793 15374:5fe8042783c1
1 /*
2 * @file gtkconn.c GTK+ Connection API
3 * @ingroup gtkui
4 *
5 * gaim
6 *
7 * Gaim is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25 #include "internal.h"
26 #include "gtkgaim.h"
27
28 #include "account.h"
29 #include "debug.h"
30 #include "notify.h"
31 #include "prefs.h"
32 #include "gtkblist.h"
33 #include "gtkconn.h"
34 #include "gtkdialogs.h"
35 #include "gtkstatusbox.h"
36 #include "gaimstock.h"
37 #include "gtkutils.h"
38 #include "util.h"
39
40 #define INITIAL_RECON_DELAY_MIN 8000
41 #define INITIAL_RECON_DELAY_MAX 60000
42
43 #define MAX_RECON_DELAY 600000
44
45 typedef struct {
46 int delay;
47 guint timeout;
48 } GaimAutoRecon;
49
50 /**
51 * Contains accounts that are auto-reconnecting.
52 * The key is a pointer to the GaimAccount and the
53 * value is a pointer to a GaimAutoRecon.
54 */
55 static GHashTable *hash = NULL;
56
57 static void
58 gaim_gtk_connection_connect_progress(GaimConnection *gc,
59 const char *text, size_t step, size_t step_count)
60 {
61 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
62 if (!gtkblist)
63 return;
64 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox),
65 (gaim_connections_get_connecting() != NULL));
66 gtk_gaim_status_box_pulse_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox));
67 }
68
69 static void
70 gaim_gtk_connection_connected(GaimConnection *gc)
71 {
72 GaimAccount *account;
73 GaimGtkBuddyList *gtkblist;
74
75 account = gaim_connection_get_account(gc);
76 gtkblist = gaim_gtk_blist_get_default_gtk_blist();
77
78 if (gtkblist != NULL)
79 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox),
80 (gaim_connections_get_connecting() != NULL));
81
82 g_hash_table_remove(hash, account);
83
84 gaim_gtk_blist_update_account_error_state(account, NULL);
85 }
86
87 static void
88 gaim_gtk_connection_disconnected(GaimConnection *gc)
89 {
90 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
91 if (!gtkblist)
92 return;
93 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox),
94 (gaim_connections_get_connecting() != NULL));
95
96 if (gaim_connections_get_all() != NULL)
97 return;
98
99 gaim_gtkdialogs_destroy_all();
100 }
101
102 static void
103 free_auto_recon(gpointer data)
104 {
105 GaimAutoRecon *info = data;
106
107 if (info->timeout != 0)
108 g_source_remove(info->timeout);
109
110 g_free(info);
111 }
112
113 static gboolean
114 do_signon(gpointer data)
115 {
116 GaimAccount *account = data;
117 GaimAutoRecon *info;
118 GaimStatus *status;
119
120 gaim_debug_info("autorecon", "do_signon called\n");
121 g_return_val_if_fail(account != NULL, FALSE);
122 info = g_hash_table_lookup(hash, account);
123
124 if (info)
125 info->timeout = 0;
126
127 status = gaim_account_get_active_status(account);
128 if (gaim_status_is_online(status))
129 {
130 gaim_debug_info("autorecon", "calling gaim_account_connect\n");
131 gaim_account_connect(account);
132 gaim_debug_info("autorecon", "done calling gaim_account_connect\n");
133 }
134
135 return FALSE;
136 }
137
138 static void
139 gaim_gtk_connection_report_disconnect(GaimConnection *gc, const char *text)
140 {
141 GaimAccount *account = NULL;
142 GaimAutoRecon *info;
143
144 account = gaim_connection_get_account(gc);
145 info = g_hash_table_lookup(hash, account);
146
147 gaim_gtk_blist_update_account_error_state(account, text);
148 if (!gc->wants_to_die) {
149 if (info == NULL) {
150 info = g_new0(GaimAutoRecon, 1);
151 g_hash_table_insert(hash, account, info);
152 info->delay = g_random_int_range(INITIAL_RECON_DELAY_MIN, INITIAL_RECON_DELAY_MAX);
153 } else {
154 info->delay = MIN(2 * info->delay, MAX_RECON_DELAY);
155 if (info->timeout != 0)
156 g_source_remove(info->timeout);
157 }
158 info->timeout = g_timeout_add(info->delay, do_signon, account);
159 } else {
160 char *p, *s, *n=NULL ;
161 if (info != NULL)
162 g_hash_table_remove(hash, account);
163
164 if (gaim_account_get_alias(account))
165 {
166 n = g_strdup_printf("%s (%s) (%s)",
167 gaim_account_get_username(account),
168 gaim_account_get_alias(account),
169 gaim_account_get_protocol_name(account));
170 }
171 else
172 {
173 n = g_strdup_printf("%s (%s)",
174 gaim_account_get_username(account),
175 gaim_account_get_protocol_name(account));
176 }
177
178 p = g_strdup_printf(_("%s disconnected"), n);
179 s = g_strdup_printf(_("%s\n\n"
180 "Gaim will not attempt to reconnect the account until you "
181 "correct the error and re-enable the account."), text);
182 gaim_notify_error(NULL, NULL, p, s);
183 g_free(p);
184 g_free(s);
185 g_free(n);
186
187 /*
188 * TODO: Do we really want to disable the account when it's
189 * disconnected by wants_to_die? This happens when you sign
190 * on from somewhere else, or when you enter an invalid password.
191 */
192 gaim_account_set_enabled(account, GAIM_GTK_UI, FALSE);
193 }
194 }
195
196 static void gaim_gtk_connection_network_connected ()
197 {
198 GList *list = gaim_accounts_get_all_active();
199 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
200
201 if(gtkblist)
202 gtk_gaim_status_box_set_network_available(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), TRUE);
203
204 while (list) {
205 GaimAccount *account = (GaimAccount*)list->data;
206 g_hash_table_remove(hash, account);
207 if (gaim_account_is_disconnected(account))
208 do_signon(account);
209 list = list->next;
210 }
211 }
212
213 static void gaim_gtk_connection_network_disconnected ()
214 {
215 GList *l = gaim_accounts_get_all_active();
216 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
217 GaimPluginProtocolInfo *prpl_info = NULL;
218 GaimConnection *gc = NULL;
219
220 if(gtkblist)
221 gtk_gaim_status_box_set_network_available(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), FALSE);
222
223 while (l) {
224 GaimAccount *a = (GaimAccount*)l->data;
225 if (!gaim_account_is_disconnected(a)) {
226 gc = gaim_account_get_connection(a);
227 if (gc && gc->prpl)
228 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
229 if (prpl_info) {
230 if (prpl_info->keepalive)
231 prpl_info->keepalive(gc);
232 else
233 gaim_account_disconnect(a);
234 }
235 }
236 l = l->next;
237 }
238 }
239
240 static void gaim_gtk_connection_notice(GaimConnection *gc, const char *text)
241 { }
242
243 static GaimConnectionUiOps conn_ui_ops =
244 {
245 gaim_gtk_connection_connect_progress,
246 gaim_gtk_connection_connected,
247 gaim_gtk_connection_disconnected,
248 gaim_gtk_connection_notice,
249 gaim_gtk_connection_report_disconnect,
250 gaim_gtk_connection_network_connected,
251 gaim_gtk_connection_network_disconnected
252 };
253
254 GaimConnectionUiOps *
255 gaim_gtk_connections_get_ui_ops(void)
256 {
257 return &conn_ui_ops;
258 }
259
260 static void
261 account_removed_cb(GaimAccount *account, gpointer user_data)
262 {
263 g_hash_table_remove(hash, account);
264
265 gaim_gtk_blist_update_account_error_state(account, NULL);
266 }
267
268
269 /**************************************************************************
270 * GTK+ connection glue
271 **************************************************************************/
272
273 void *
274 gaim_gtk_connection_get_handle(void)
275 {
276 static int handle;
277
278 return &handle;
279 }
280
281 void
282 gaim_gtk_connection_init(void)
283 {
284 hash = g_hash_table_new_full(
285 g_direct_hash, g_direct_equal,
286 NULL, free_auto_recon);
287
288 gaim_signal_connect(gaim_accounts_get_handle(), "account-removed",
289 gaim_gtk_connection_get_handle(),
290 GAIM_CALLBACK(account_removed_cb), NULL);
291 }
292
293 void
294 gaim_gtk_connection_uninit(void)
295 {
296 gaim_signals_disconnect_by_handle(gaim_gtk_connection_get_handle());
297
298 g_hash_table_destroy(hash);
299 }