Mercurial > pidgin
annotate src/gtkconn.c @ 13967:99b9b58b19dd
[gaim-migrate @ 16523]
Fix a crazy MSN crash. Basically it's possible to have more than one
slplink associated with a given switchboard, but our code did not
allow for that. I think it happens when you're in a multi-user
chat and you do stuff with multiple users that involves slplinks.
Like maybe file transfer and buddy icon related stuff.
Tracking this down took an ungodly amount of time, but thanks to
Meebo for letting me do it :-)
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 20 Jul 2006 07:31:15 +0000 |
parents | 69e02f13b525 |
children | 87797e287549 |
rev | line source |
---|---|
5717 | 1 /* |
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10211
diff
changeset
|
2 * @file gtkconn.c GTK+ Connection API |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10211
diff
changeset
|
3 * @ingroup gtkui |
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10211
diff
changeset
|
4 * |
5717 | 5 * gaim |
6 * | |
8046 | 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. | |
5717 | 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 */ | |
9791 | 25 #include "internal.h" |
26 #include "gtkgaim.h" | |
5717 | 27 |
28 #include "account.h" | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5746
diff
changeset
|
29 #include "debug.h" |
6460
ff4551719cc7
[gaim-migrate @ 6969]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
30 #include "notify.h" |
6216 | 31 #include "prefs.h" |
10643 | 32 #include "gtkblist.h" |
12404
7c7cb03e5475
[gaim-migrate @ 14711]
Richard Laager <rlaager@wiktel.com>
parents:
12296
diff
changeset
|
33 #include "gtkconn.h" |
7c7cb03e5475
[gaim-migrate @ 14711]
Richard Laager <rlaager@wiktel.com>
parents:
12296
diff
changeset
|
34 #include "gtkdialogs.h" |
10643 | 35 #include "gtkstatusbox.h" |
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10211
diff
changeset
|
36 #include "gtkstock.h" |
12404
7c7cb03e5475
[gaim-migrate @ 14711]
Richard Laager <rlaager@wiktel.com>
parents:
12296
diff
changeset
|
37 #include "gtkutils.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5746
diff
changeset
|
38 #include "util.h" |
5717 | 39 |
11523 | 40 #define INITIAL_RECON_DELAY 8000 |
11721 | 41 #define MAX_RECON_DELAY 600000 |
11523 | 42 |
43 typedef struct { | |
44 int delay; | |
45 guint timeout; | |
46 } GaimAutoRecon; | |
47 | |
13014 | 48 /** |
49 * Contains accounts that are auto-reconnecting. | |
50 * The key is a pointer to the GaimAccount and the | |
51 * value is a pointer to a GaimAutoRecon. | |
13013 | 52 */ |
13014 | 53 static GHashTable *hash = NULL; |
11523 | 54 |
13014 | 55 static void |
56 gaim_gtk_connection_connect_progress(GaimConnection *gc, | |
5717 | 57 const char *text, size_t step, size_t step_count) |
58 { | |
10643 | 59 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist(); |
60 if (!gtkblist) | |
61 return; | |
62 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), | |
63 (gaim_connections_get_connecting() != NULL)); | |
64 gtk_gaim_status_box_pulse_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox)); | |
5717 | 65 } |
13754 | 66 |
13014 | 67 static void |
68 gaim_gtk_connection_connected(GaimConnection *gc) | |
5717 | 69 { |
13014 | 70 GaimAccount *account; |
71 GaimGtkBuddyList *gtkblist; | |
72 | |
73 account = gaim_connection_get_account(gc); | |
74 gtkblist = gaim_gtk_blist_get_default_gtk_blist(); | |
75 | |
76 if (gtkblist != NULL) | |
77 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), | |
10643 | 78 (gaim_connections_get_connecting() != NULL)); |
12607 | 79 |
11536 | 80 if (hash != NULL) |
81 g_hash_table_remove(hash, account); | |
13014 | 82 |
13730 | 83 gaim_gtk_blist_update_account_error_state(account, NULL); |
5717 | 84 } |
85 | |
13014 | 86 static void |
87 gaim_gtk_connection_disconnected(GaimConnection *gc) | |
5717 | 88 { |
10643 | 89 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist(); |
90 if (!gtkblist) | |
91 return; | |
92 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), | |
93 (gaim_connections_get_connecting() != NULL)); | |
5883
f5b0c6073264
[gaim-migrate @ 6315]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
94 |
f5b0c6073264
[gaim-migrate @ 6315]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
95 if (gaim_connections_get_all() != NULL) |
f5b0c6073264
[gaim-migrate @ 6315]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
96 return; |
f5b0c6073264
[gaim-migrate @ 6315]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
97 |
9730 | 98 gaim_gtkdialogs_destroy_all(); |
5717 | 99 } |
100 | |
13014 | 101 static void |
102 gaim_gtk_connection_notice(GaimConnection *gc, | |
5717 | 103 const char *text) |
104 { | |
105 } | |
106 | |
7912 | 107 |
11523 | 108 static void |
109 free_auto_recon(gpointer data) | |
7493 | 110 { |
11523 | 111 GaimAutoRecon *info = data; |
7912 | 112 |
11523 | 113 if (info->timeout != 0) |
114 g_source_remove(info->timeout); | |
7912 | 115 |
11523 | 116 g_free(info); |
7493 | 117 } |
118 | |
11523 | 119 static gboolean |
120 do_signon(gpointer data) | |
7912 | 121 { |
11523 | 122 GaimAccount *account = data; |
123 GaimAutoRecon *info; | |
13374 | 124 GaimStatus *status; |
10916 | 125 |
13014 | 126 gaim_debug_info("autorecon", "do_signon called\n"); |
11523 | 127 g_return_val_if_fail(account != NULL, FALSE); |
128 info = g_hash_table_lookup(hash, account); | |
7912 | 129 |
11523 | 130 if (info) |
131 info->timeout = 0; | |
7912 | 132 |
13374 | 133 status = gaim_account_get_active_status(account); |
134 if (gaim_status_is_online(status)) | |
135 { | |
136 gaim_debug_info("autorecon", "calling gaim_account_connect\n"); | |
137 gaim_account_connect(account); | |
138 gaim_debug_info("autorecon", "done calling gaim_account_connect\n"); | |
139 } | |
7912 | 140 |
11523 | 141 return FALSE; |
7912 | 142 } |
143 | |
13014 | 144 static void |
145 gaim_gtk_connection_report_disconnect(GaimConnection *gc, const char *text) | |
7399 | 146 { |
7431 | 147 GaimAccount *account = NULL; |
11523 | 148 GaimAutoRecon *info; |
7808 | 149 |
11523 | 150 account = gaim_connection_get_account(gc); |
151 info = g_hash_table_lookup(hash, account); | |
7912 | 152 |
13031 | 153 gaim_gtk_blist_update_account_error_state(account, text); |
11523 | 154 if (!gc->wants_to_die) { |
12009 | 155 if (info == NULL) { |
11523 | 156 info = g_new0(GaimAutoRecon, 1); |
157 g_hash_table_insert(hash, account, info); | |
158 info->delay = INITIAL_RECON_DELAY; | |
7483 | 159 } else { |
11523 | 160 info->delay = MIN(2 * info->delay, MAX_RECON_DELAY); |
161 if (info->timeout != 0) | |
162 g_source_remove(info->timeout); | |
7483 | 163 } |
11523 | 164 info->timeout = g_timeout_add(info->delay, do_signon, account); |
11559 | 165 } else { |
13014 | 166 char *p, *s, *n=NULL ; |
167 if (info != NULL) | |
168 g_hash_table_remove(hash, account); | |
11721 | 169 |
13014 | 170 if (gaim_account_get_alias(account)) |
171 { | |
172 n = g_strdup_printf("%s (%s) (%s)", | |
173 gaim_account_get_username(account), | |
174 gaim_account_get_alias(account), | |
175 gaim_account_get_protocol_name(account)); | |
176 } | |
177 else | |
178 { | |
179 n = g_strdup_printf("%s (%s)", | |
180 gaim_account_get_username(account), | |
181 gaim_account_get_protocol_name(account)); | |
182 } | |
11721 | 183 |
13014 | 184 p = g_strdup_printf(_("%s disconnected"), n); |
13128 | 185 s = g_strdup_printf(_("%s was disconnected due to an error: %s\n" |
186 "Gaim will not attempt to reconnect the account until you " | |
13541
6818e4fc3616
[gaim-migrate @ 15918]
Richard Laager <rlaager@wiktel.com>
parents:
13374
diff
changeset
|
187 "correct the error and re-enable the account."), n, text); |
13014 | 188 gaim_notify_error(NULL, NULL, p, s); |
189 g_free(p); | |
190 g_free(s); | |
191 g_free(n); | |
192 | |
193 /* | |
194 * TODO: Do we really want to disable the account when it's | |
195 * disconnected by wants_to_die? This happens when you sign | |
196 * on from somewhere else, or when you enter an invalid password. | |
197 */ | |
198 gaim_account_set_enabled(account, GAIM_GTK_UI, FALSE); | |
7399 | 199 } |
200 } | |
201 | |
5717 | 202 static GaimConnectionUiOps conn_ui_ops = |
203 { | |
204 gaim_gtk_connection_connect_progress, | |
205 gaim_gtk_connection_connected, | |
206 gaim_gtk_connection_disconnected, | |
6460
ff4551719cc7
[gaim-migrate @ 6969]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
207 gaim_gtk_connection_notice, |
11523 | 208 gaim_gtk_connection_report_disconnect, |
5717 | 209 }; |
210 | |
7035
feb3d21a7794
[gaim-migrate @ 7598]
Christian Hammond <chipx86@chipx86.com>
parents:
6460
diff
changeset
|
211 GaimConnectionUiOps * |
feb3d21a7794
[gaim-migrate @ 7598]
Christian Hammond <chipx86@chipx86.com>
parents:
6460
diff
changeset
|
212 gaim_gtk_connections_get_ui_ops(void) |
5717 | 213 { |
214 return &conn_ui_ops; | |
215 } | |
13014 | 216 |
217 static void | |
218 account_removed_cb(GaimAccount *account, gpointer user_data) | |
219 { | |
220 g_hash_table_remove(hash, account); | |
221 | |
13730 | 222 gaim_gtk_blist_update_account_error_state(account, NULL); |
13014 | 223 } |
224 | |
225 | |
226 /************************************************************************** | |
227 * GTK+ connection glue | |
228 **************************************************************************/ | |
229 | |
230 void * | |
231 gaim_gtk_connection_get_handle(void) | |
232 { | |
233 static int handle; | |
234 | |
235 return &handle; | |
236 } | |
237 | |
238 void | |
239 gaim_gtk_connection_init(void) | |
240 { | |
241 hash = g_hash_table_new_full( | |
242 g_direct_hash, g_direct_equal, | |
243 NULL, free_auto_recon); | |
244 | |
245 gaim_signal_connect(gaim_accounts_get_handle(), "account-removed", | |
246 gaim_gtk_connection_get_handle(), | |
247 GAIM_CALLBACK(account_removed_cb), NULL); | |
248 } | |
249 | |
250 void | |
251 gaim_gtk_connection_uninit(void) | |
252 { | |
253 gaim_signals_disconnect_by_handle(gaim_gtk_connection_get_handle()); | |
254 | |
255 g_hash_table_destroy(hash); | |
256 } |