comparison src/gtkconn.c @ 11523:1116993aadd2

[gaim-migrate @ 13771] Incorporated Autorecon's code into the core. Removed the Disconnected window Shows connection errors in status box. This works _ok_ when signed on with a single account, but won't currently Handle multiple accounts at all. I wanted to get this in before going to bed tonight, so I can work on it later, though. Feel free to help. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Mon, 12 Sep 2005 06:46:43 +0000
parents ad9a61894d9b
children 16796e09b9c1
comparison
equal deleted inserted replaced
11522:a26eb48d1953 11523:1116993aadd2
36 36
37 #include "gtkblist.h" 37 #include "gtkblist.h"
38 #include "gtkdialogs.h" 38 #include "gtkdialogs.h"
39 #include "gtkutils.h" 39 #include "gtkutils.h"
40 40
41 #define INITIAL_RECON_DELAY 8000
42 #define MAX_RECON_DELAY 2048000
43
44 typedef struct {
45 int delay;
46 guint timeout;
47 } GaimAutoRecon;
48
49 static GHashTable *hash = NULL;
50 static GSList *accountReconnecting = NULL;
51
41 static void gaim_gtk_connection_connect_progress(GaimConnection *gc, 52 static void gaim_gtk_connection_connect_progress(GaimConnection *gc,
42 const char *text, size_t step, size_t step_count) 53 const char *text, size_t step, size_t step_count)
43 { 54 {
44 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist(); 55 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
45 if (!gtkblist) 56 if (!gtkblist)
50 } 61 }
51 62
52 static void gaim_gtk_connection_connected(GaimConnection *gc) 63 static void gaim_gtk_connection_connected(GaimConnection *gc)
53 { 64 {
54 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist(); 65 GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
66 GaimAccount *account = NULL;
55 if (!gtkblist) 67 if (!gtkblist)
56 return; 68 return;
57 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), 69 gtk_gaim_status_box_set_connecting(GTK_GAIM_STATUS_BOX(gtkblist->statusbox),
58 (gaim_connections_get_connecting() != NULL)); 70 (gaim_connections_get_connecting() != NULL));
71 account = gaim_connection_get_account(gc);
72 g_hash_table_remove(hash, account);
73 if (accountReconnecting == NULL)
74 return;
75 accountReconnecting = g_slist_remove(accountReconnecting, account);
76 if (accountReconnecting == NULL)
77 gtk_gaim_status_box_set_error(GTK_GAIM_STATUS_BOX(gtkblist->statusbox), NULL);
59 gaim_gtk_blist_update_protocol_actions(); 78 gaim_gtk_blist_update_protocol_actions();
60 } 79 }
61 80
62 static void gaim_gtk_connection_disconnected(GaimConnection *gc) 81 static void gaim_gtk_connection_disconnected(GaimConnection *gc)
63 { 82 {
77 static void gaim_gtk_connection_notice(GaimConnection *gc, 96 static void gaim_gtk_connection_notice(GaimConnection *gc,
78 const char *text) 97 const char *text)
79 { 98 {
80 } 99 }
81 100
82 /*
83 * The next couple of functions deal with the disconnected dialog
84 */
85 struct disconnect_window {
86 GtkWidget *window;
87 GtkWidget *treeview;
88 GtkWidget *sw;
89 GtkWidget *label;
90 GtkWidget *reconnect_btn;
91 GtkWidget *reconnectall_btn;
92 };
93 static struct disconnect_window *disconnect_window = NULL;
94 101
95 static void disconnect_connection_change_cb(GaimConnection *gc, void *data); 102 static void
103 free_auto_recon(gpointer data)
104 {
105 GaimAutoRecon *info = data;
96 106
97 /* 107 if (info->timeout != 0)
98 * Destroy the dialog and remove the signals associated with it. 108 g_source_remove(info->timeout);
99 */
100 static void disconnect_window_hide()
101 {
102 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-on",
103 disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb));
104 109
105 gaim_signal_disconnect(gaim_connections_get_handle(), "signed-off", 110 g_free(info);
106 disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb));
107
108 gtk_widget_destroy(disconnect_window->window);
109 g_free(disconnect_window);
110 disconnect_window = NULL;
111 } 111 }
112 112
113 /* 113 static gboolean
114 * Make sure the Reconnect and Reconnect All buttons are correctly 114 do_signon(gpointer data)
115 * shown or hidden. Also make sure the label on the Reconnect
116 * button is correctly set to either Reconnect or Remove. If there
117 * is more than one account then make sure the GtkTreeView is shown.
118 * If there are no accounts disconnected then hide the dialog.
119 */
120 static void disconnect_window_update_buttons()
121 { 115 {
122 GtkTreeIter iter; 116 GaimAccount *account = data;
123 GtkTreeSelection *sel; 117 GaimAutoRecon *info;
124 GtkTreeModel *model;
125 char *label_text;
126 GaimAccount *account = NULL;
127 118
128 if (disconnect_window == NULL) 119 gaim_debug(GAIM_DEBUG_INFO, "autorecon", "do_signon called\n");
129 return; 120 g_return_val_if_fail(account != NULL, FALSE);
121 info = g_hash_table_lookup(hash, account);
130 122
131 model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview)); 123 if (g_list_index(gaim_accounts_get_all(), account) < 0)
124 return FALSE;
132 125
133 if (model == NULL) 126 if (info)
134 return; 127 info->timeout = 0;
135 128
136 if (!gtk_tree_model_get_iter_first(model, &iter)) { 129 gaim_debug(GAIM_DEBUG_INFO, "autorecon", "calling gaim_account_connect\n");
137 /* No more accounts being shown. Caloo calay! */ 130 gaim_account_connect(account);
138 disconnect_window_hide(); 131 gaim_debug(GAIM_DEBUG_INFO, "autorecon", "done calling gaim_account_connect\n");
139 return;
140 }
141 132
142 /* 133 return FALSE;
143 * If we have more than one disconnected account then show the
144 * GtkTreeView and the "Reconnect All" button
145 */
146 if (gtk_tree_model_iter_next(model, &iter)) {
147 gtk_widget_show_all(disconnect_window->sw);
148 gtk_widget_show(disconnect_window->reconnectall_btn);
149 } else {
150 gtk_widget_hide_all(disconnect_window->sw);
151 gtk_widget_hide(disconnect_window->reconnectall_btn);
152 }
153
154 /*
155 * Make sure one of the accounts is selected.
156 */
157 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
158 if (!gtk_tree_selection_get_selected(sel, &model, &iter)) {
159 gtk_tree_model_get_iter_first(model, &iter);
160 gtk_tree_selection_select_iter(sel, &iter);
161 }
162
163 /*
164 * Update the Reconnect/Remove button appropriately and set the
165 * label in the dialog to what it should be. If there is only
166 * one account in the tree model, and that account is connected,
167 * then we don't show the remove button.
168 */
169 gtk_tree_model_get(model, &iter, 3, &label_text, 4, &account, -1);
170 gtk_button_set_label(GTK_BUTTON(disconnect_window->reconnect_btn),
171 gaim_account_is_disconnected(account) ? _("Reconnect") : _("_Remove"));
172 gtk_label_set_markup(GTK_LABEL(disconnect_window->label), label_text);
173 gtk_dialog_set_response_sensitive(GTK_DIALOG(disconnect_window->window), GTK_RESPONSE_ACCEPT, TRUE);
174 gtk_tree_model_get_iter_first(model, &iter);
175 if (gaim_account_is_disconnected(account) || gtk_tree_model_iter_next(model, &iter))
176 gtk_widget_show(disconnect_window->reconnect_btn);
177 else
178 gtk_widget_hide(disconnect_window->reconnect_btn);
179 g_free(label_text);
180 } 134 }
181 135
182 static void disconnect_response_cb(GtkDialog *dialog, gint id, GtkWidget *widget) 136 static void gaim_gtk_connection_report_disconnect(GaimConnection *gc, const char *text)
183 { 137 {
184 GtkTreeIter iter; 138 GaimGtkBuddyList *list = gaim_gtk_blist_get_default_gtk_blist();
185 GtkTreeSelection *sel = NULL;
186 GtkTreeModel *model = NULL;
187 GaimAccount *account = NULL; 139 GaimAccount *account = NULL;
140 GaimAutoRecon *info;
141 GSList* listAccount;
188 142
189 switch (id) { 143 gtk_gaim_status_box_set_error(GTK_GAIM_STATUS_BOX(list->statusbox), text);
190 case GTK_RESPONSE_APPLY: /* Reconnect All */ 144 if (hash == NULL) {
191 model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview)); 145 hash = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
192 if (gtk_tree_model_get_iter_first(model, &iter)) { 146 free_auto_recon);
193 /* tree rows to be deleted */ 147 }
194 GList *l_del = NULL, *l_del_iter = NULL; 148 account = gaim_connection_get_account(gc);
195 /* accounts to be connected */ 149 info = g_hash_table_lookup(hash, account);
196 GList *l_accts = NULL, *l_accts_iter = NULL; 150 if (accountReconnecting)
197 do { 151 listAccount = g_slist_find(accountReconnecting, account);
198 GtkTreePath *path = gtk_tree_model_get_path(model, &iter); 152 else
199 GtkTreeRowReference* del_row = gtk_tree_row_reference_new(model, path); 153 listAccount = NULL;
200 l_del = g_list_append(l_del, del_row);
201 gtk_tree_path_free(path);
202 154
203 gtk_tree_model_get(model, &iter, 4, &account, -1); 155 if (!gc->wants_to_die) {
204 if (gaim_account_is_disconnected(account) && g_list_find(l_accts, account) == NULL) 156 if (info == NULL) {
205 l_accts = g_list_append(l_accts, account); 157 info = g_new0(GaimAutoRecon, 1);
206 } while (gtk_tree_model_iter_next(model, &iter)); 158 g_hash_table_insert(hash, account, info);
159 info->delay = INITIAL_RECON_DELAY;
160 } else {
161 info->delay = MIN(2 * info->delay, MAX_RECON_DELAY);
162 if (info->timeout != 0)
163 g_source_remove(info->timeout);
164 }
165 info->timeout = g_timeout_add(info->delay, do_signon, account);
207 166
208 /* remove all rows */ 167 if (!listAccount)
209 /* We could just do the following, but we only want to remove accounts 168 accountReconnecting = g_slist_prepend(accountReconnecting, account);
210 * that are going to be reconnected, not accounts that have already 169 } else if (info != NULL) {
211 * been reconnected. 170 g_hash_table_remove(hash, account);
212 */
213 /* gtk_list_store_clear(GTK_LIST_STORE(model)); */
214 l_del_iter = l_del;
215 while (l_del_iter != NULL) {
216 GtkTreeRowReference* del_row = l_del_iter->data;
217 GtkTreePath *path = gtk_tree_row_reference_get_path(del_row);
218 if (gtk_tree_model_get_iter(model, &iter, path))
219 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
220 gtk_tree_path_free(path);
221 gtk_tree_row_reference_free(del_row);
222 l_del_iter = l_del_iter->next;
223 }
224 g_list_free(l_del);
225 171
226 /* reconnect disconnected accounts */ 172 if (listAccount)
227 l_accts_iter = l_accts; 173 accountReconnecting = g_slist_delete_link(accountReconnecting, listAccount);
228 while (l_accts_iter != NULL) {
229 account = l_accts_iter->data;
230 gaim_account_connect(account);
231 l_accts_iter = l_accts_iter->next;
232 }
233 g_list_free(l_accts);
234
235 }
236
237 disconnect_window_update_buttons();
238
239 break;
240
241 case GTK_RESPONSE_ACCEPT: /* Reconnect Selected */
242 model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview));
243
244 /*
245 * If we have more than one account disconnection displayed, then
246 * the scroll window is visible and we should use the selected
247 * account to reconnect.
248 */
249 if (GTK_WIDGET_VISIBLE(disconnect_window->sw)) {
250 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
251 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
252 return;
253 } else {
254 /* There is only one account disconnection, so reconnect to it. */
255 if (!gtk_tree_model_get_iter_first(model, &iter))
256 return;
257 }
258
259 /* remove all disconnections of the account to be reconnected */
260 gtk_tree_model_get(model, &iter, 4, &account, -1);
261 if (gtk_tree_model_get_iter_first(model, &iter)) {
262 GList *l_del = NULL, *l_del_iter = NULL;
263 GaimAccount *account2 = NULL;
264 do {
265 gtk_tree_model_get(model, &iter, 4, &account2, -1);
266 if (account2 == account) {
267 GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
268 GtkTreeRowReference* del_row = gtk_tree_row_reference_new(model, path);
269 l_del = g_list_append(l_del, del_row);
270 gtk_tree_path_free(path);
271 }
272 } while (gtk_tree_model_iter_next(model, &iter));
273
274 l_del_iter = l_del;
275 while (l_del_iter != NULL) {
276 GtkTreeRowReference* del_row = l_del_iter->data;
277 GtkTreePath *path = gtk_tree_row_reference_get_path(del_row);
278 if (gtk_tree_model_get_iter(model, &iter, path))
279 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
280 gtk_tree_path_free(path);
281 gtk_tree_row_reference_free(del_row);
282 l_del_iter = l_del_iter->next;
283 }
284 g_list_free(l_del);
285 }
286
287 gaim_account_connect(account);
288 disconnect_window_update_buttons();
289
290 break;
291
292 case GTK_RESPONSE_DELETE_EVENT:
293 case GTK_RESPONSE_CLOSE:
294 disconnect_window_hide();
295 break;
296
297 } 174 }
298 } 175 }
299
300 /*
301 * Called whenever a different account is selected in the GtkListWhatever.
302 */
303 static void disconnect_tree_cb(GtkTreeSelection *sel, GtkTreeModel *model)
304 {
305 disconnect_window_update_buttons();
306 }
307
308 /*
309 * Update the icon next to the account in the disconnect dialog, and
310 * gray the Reconnect All button if there is only 1 disconnected account.
311 */
312 static void disconnect_connection_change_cb(GaimConnection *gc, void *data) {
313 GaimAccount *account = gaim_connection_get_account(gc);
314 GtkTreeIter iter;
315 GtkTreeModel *model;
316 GdkPixbuf *icon;
317 GdkPixbuf *scale;
318 GList *l_disc_accts = NULL;
319
320 if (disconnect_window == NULL)
321 return;
322
323 model = gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview));
324 icon = gaim_gtk_create_prpl_icon(account);
325 scale = gdk_pixbuf_scale_simple(icon, 16, 16, GDK_INTERP_BILINEAR);
326
327 /* Mark all disconnections w/ the account type disconnected /w grey icon */
328 if (gaim_account_is_disconnected(account))
329 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE);
330
331 gtk_tree_model_get_iter_first(model, &iter);
332 do {
333 GaimAccount *account2 = NULL;
334 /* Gray out the icon if this row is for this account */
335 gtk_tree_model_get(model, &iter, 4, &account2, -1);
336 if (account2 == account)
337 gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, scale, -1);
338
339 /* Add */
340 if (gaim_account_is_disconnected(account2)
341 && g_list_find(l_disc_accts, account2) == NULL)
342 l_disc_accts = g_list_append(l_disc_accts, account2);
343 } while (gtk_tree_model_iter_next(model, &iter));
344
345 gtk_dialog_set_response_sensitive(
346 GTK_DIALOG(disconnect_window->window),
347 GTK_RESPONSE_APPLY,
348 g_list_length(l_disc_accts) > 1);
349 g_list_free(l_disc_accts);
350
351 if (icon != NULL)
352 g_object_unref(G_OBJECT(icon));
353 if (scale != NULL)
354 g_object_unref(G_OBJECT(scale));
355
356 disconnect_window_update_buttons();
357 }
358
359 static void
360 gaim_gtk_connection_report_disconnect(GaimConnection *gc, const char *text)
361 {
362 char *label_text = NULL;
363 GtkTreeIter new_iter;
364 GtkListStore *list_store;
365 GtkTreeViewColumn *col;
366 GtkTreeSelection *sel = NULL;
367
368 label_text = g_strdup_printf(_("<span weight=\"bold\" size=\"larger\">%s has been disconnected.</span>\n\n%s\n%s"),
369 gaim_account_get_username(gaim_connection_get_account(gc)), gaim_date_full(),
370 text ? text : _("Reason Unknown."));
371
372 /* Build the window if it isn't there yet */
373 if (!disconnect_window) {
374 GtkWidget *hbox, *vbox, *img;
375 GtkCellRenderer *rend, *rend2;
376
377 disconnect_window = g_new0(struct disconnect_window, 1);
378 disconnect_window->window = gtk_dialog_new_with_buttons(_("Disconnected"), NULL, GTK_DIALOG_NO_SEPARATOR, NULL);
379 g_signal_connect(G_OBJECT(disconnect_window->window), "response", G_CALLBACK(disconnect_response_cb), disconnect_window);
380
381 gtk_container_set_border_width(GTK_CONTAINER(disconnect_window->window), GAIM_HIG_BOX_SPACE);
382 gtk_window_set_resizable(GTK_WINDOW(disconnect_window->window), FALSE);
383 gtk_dialog_set_has_separator(GTK_DIALOG(disconnect_window->window), FALSE);
384 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(disconnect_window->window)->vbox), GAIM_HIG_BORDER);
385 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(disconnect_window->window)->vbox), GAIM_HIG_BOX_SPACE);
386
387 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BORDER);
388 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(disconnect_window->window)->vbox), hbox);
389 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
390 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
391 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
392
393 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER);
394 gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
395
396 disconnect_window->label = gtk_label_new(label_text);
397
398 gtk_label_set_line_wrap(GTK_LABEL(disconnect_window->label), TRUE);
399 gtk_misc_set_alignment(GTK_MISC(disconnect_window->label), 0, 0);
400 gtk_box_pack_start(GTK_BOX(vbox), disconnect_window->label, FALSE, FALSE, 0);
401
402 disconnect_window->reconnect_btn = gtk_dialog_add_button(
403 GTK_DIALOG(disconnect_window->window),
404 _("_Reconnect"),
405 GTK_RESPONSE_ACCEPT);
406
407 disconnect_window->reconnectall_btn = gtk_dialog_add_button(
408 GTK_DIALOG(disconnect_window->window),
409 _("Reconnect _All"),
410 GTK_RESPONSE_APPLY);
411
412 gtk_dialog_add_button(
413 GTK_DIALOG(disconnect_window->window),
414 GTK_STOCK_CLOSE,
415 GTK_RESPONSE_CLOSE);
416
417 gtk_widget_show_all(disconnect_window->window);
418
419 /* Tree View */
420 disconnect_window->sw = gtk_scrolled_window_new(NULL,NULL);
421 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(disconnect_window->sw), GTK_SHADOW_IN);
422 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(disconnect_window->sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
423 gtk_box_pack_start(GTK_BOX(vbox), disconnect_window->sw, TRUE, TRUE, 0);
424
425 list_store = gtk_list_store_new(5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
426 disconnect_window->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
427
428 rend = gtk_cell_renderer_pixbuf_new();
429 rend2 = gtk_cell_renderer_text_new();
430 col = gtk_tree_view_column_new();
431 gtk_tree_view_column_set_title(col, _("Account"));
432 gtk_tree_view_column_pack_start(col, rend, FALSE);
433 gtk_tree_view_column_pack_start(col, rend2, FALSE);
434 gtk_tree_view_column_set_attributes(col, rend, "pixbuf", 0, NULL);
435 gtk_tree_view_column_set_attributes(col, rend2, "text", 1, NULL);
436 gtk_tree_view_append_column (GTK_TREE_VIEW(disconnect_window->treeview), col);
437
438 rend = gtk_cell_renderer_text_new();
439 col = gtk_tree_view_column_new_with_attributes (_("Time"),
440 rend, "text", 2, NULL);
441 gtk_tree_view_append_column (GTK_TREE_VIEW(disconnect_window->treeview), col);
442
443 g_object_unref(G_OBJECT(list_store));
444 gtk_container_add(GTK_CONTAINER(disconnect_window->sw), disconnect_window->treeview);
445
446 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (disconnect_window->treeview));
447 gtk_widget_set_size_request(disconnect_window->treeview, -1, 96);
448 g_signal_connect (G_OBJECT (sel), "changed",
449 G_CALLBACK (disconnect_tree_cb), list_store);
450
451 gaim_signal_connect(gaim_connections_get_handle(), "signed-on",
452 disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb), NULL);
453
454 gaim_signal_connect(gaim_connections_get_handle(), "signed-off",
455 disconnect_window, GAIM_CALLBACK(disconnect_connection_change_cb), NULL);
456 } else
457 list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(disconnect_window->treeview)));
458
459 /* Add this account to our list of disconnected accounts */
460 gtk_list_store_append(list_store, &new_iter);
461 gtk_list_store_set(list_store, &new_iter,
462 0, NULL,
463 1, gaim_account_get_username(gaim_connection_get_account(gc)),
464 2, gaim_date_full(),
465 3, label_text,
466 4, gaim_connection_get_account(gc), -1);
467
468 /* Make sure the newly disconnected account is selected */
469 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(disconnect_window->treeview));
470 gtk_tree_selection_select_iter(sel, &new_iter);
471
472 disconnect_window_update_buttons();
473
474 g_free(label_text);
475 }
476 /*
477 * End of disconnected dialog
478 */
479 176
480 static GaimConnectionUiOps conn_ui_ops = 177 static GaimConnectionUiOps conn_ui_ops =
481 { 178 {
482 gaim_gtk_connection_connect_progress, 179 gaim_gtk_connection_connect_progress,
483 gaim_gtk_connection_connected, 180 gaim_gtk_connection_connected,
484 gaim_gtk_connection_disconnected, 181 gaim_gtk_connection_disconnected,
485 gaim_gtk_connection_notice, 182 gaim_gtk_connection_notice,
486 gaim_gtk_connection_report_disconnect 183 gaim_gtk_connection_report_disconnect,
487 }; 184 };
488 185
489 GaimConnectionUiOps * 186 GaimConnectionUiOps *
490 gaim_gtk_connections_get_ui_ops(void) 187 gaim_gtk_connections_get_ui_ops(void)
491 { 188 {