| 1 /* |
|
| 2 * gaim |
|
| 3 * |
|
| 4 * Gaim is the legal property of its developers, whose names are too numerous |
|
| 5 * to list here. Please refer to the COPYRIGHT file distributed with this |
|
| 6 * source distribution. |
|
| 7 * |
|
| 8 * This program is free software; you can redistribute it and/or modify |
|
| 9 * it under the terms of the GNU General Public License as published by |
|
| 10 * the Free Software Foundation; either version 2 of the License, or |
|
| 11 * (at your option) any later version. |
|
| 12 * |
|
| 13 * This program is distributed in the hope that it will be useful, |
|
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 16 * GNU General Public License for more details. |
|
| 17 * |
|
| 18 * You should have received a copy of the GNU General Public License |
|
| 19 * along with this program; if not, write to the Free Software |
|
| 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 21 */ |
|
| 22 #include "internal.h" |
|
| 23 #include "blist.h" |
|
| 24 #include "conversation.h" |
|
| 25 #include "dbus-maybe.h" |
|
| 26 #include "debug.h" |
|
| 27 #include "imgstore.h" |
|
| 28 #include "notify.h" |
|
| 29 #include "prefs.h" |
|
| 30 #include "prpl.h" |
|
| 31 #include "signals.h" |
|
| 32 #include "util.h" |
|
| 33 |
|
| 34 #define SEND_TYPED_TIMEOUT 5000 |
|
| 35 |
|
| 36 static GList *conversations = NULL; |
|
| 37 static GList *ims = NULL; |
|
| 38 static GList *chats = NULL; |
|
| 39 static GaimConversationUiOps *default_ops = NULL; |
|
| 40 |
|
| 41 void |
|
| 42 gaim_conversations_set_ui_ops(GaimConversationUiOps *ops) |
|
| 43 { |
|
| 44 default_ops = ops; |
|
| 45 } |
|
| 46 |
|
| 47 static gboolean |
|
| 48 reset_typing_cb(gpointer data) |
|
| 49 { |
|
| 50 GaimConversation *c = (GaimConversation *)data; |
|
| 51 GaimConvIm *im; |
|
| 52 |
|
| 53 im = GAIM_CONV_IM(c); |
|
| 54 |
|
| 55 gaim_conv_im_set_typing_state(im, GAIM_NOT_TYPING); |
|
| 56 gaim_conv_im_update_typing(im); |
|
| 57 gaim_conv_im_stop_typing_timeout(im); |
|
| 58 |
|
| 59 return FALSE; |
|
| 60 } |
|
| 61 |
|
| 62 static gboolean |
|
| 63 send_typed_cb(gpointer data) |
|
| 64 { |
|
| 65 GaimConversation *conv = (GaimConversation *)data; |
|
| 66 GaimConnection *gc; |
|
| 67 const char *name; |
|
| 68 |
|
| 69 g_return_val_if_fail(conv != NULL, FALSE); |
|
| 70 |
|
| 71 gc = gaim_conversation_get_gc(conv); |
|
| 72 name = gaim_conversation_get_name(conv); |
|
| 73 |
|
| 74 if (gc != NULL && name != NULL) { |
|
| 75 /* We set this to 1 so that GAIM_TYPING will be sent |
|
| 76 * if the Gaim user types anything else. |
|
| 77 */ |
|
| 78 gaim_conv_im_set_type_again(GAIM_CONV_IM(conv), 1); |
|
| 79 |
|
| 80 serv_send_typing(gc, name, GAIM_TYPED); |
|
| 81 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 82 "buddy-typed", conv->account, conv->name); |
|
| 83 |
|
| 84 gaim_debug(GAIM_DEBUG_MISC, "conversation", "typed...\n"); |
|
| 85 } |
|
| 86 |
|
| 87 return FALSE; |
|
| 88 } |
|
| 89 |
|
| 90 static void |
|
| 91 common_send(GaimConversation *conv, const char *message, GaimMessageFlags msgflags) |
|
| 92 { |
|
| 93 GaimConversationType type; |
|
| 94 GaimAccount *account; |
|
| 95 GaimConnection *gc; |
|
| 96 char *displayed = NULL, *sent = NULL; |
|
| 97 int err = 0; |
|
| 98 |
|
| 99 if (strlen(message) == 0) |
|
| 100 return; |
|
| 101 |
|
| 102 account = gaim_conversation_get_account(conv); |
|
| 103 gc = gaim_conversation_get_gc(conv); |
|
| 104 |
|
| 105 g_return_if_fail(account != NULL); |
|
| 106 g_return_if_fail(gc != NULL); |
|
| 107 |
|
| 108 type = gaim_conversation_get_type(conv); |
|
| 109 |
|
| 110 /* Always linkfy the text for display */ |
|
| 111 displayed = gaim_markup_linkify(message); |
|
| 112 |
|
| 113 if ((conv->features & GAIM_CONNECTION_HTML) && |
|
| 114 !(msgflags & GAIM_MESSAGE_RAW)) |
|
| 115 { |
|
| 116 sent = g_strdup(displayed); |
|
| 117 } |
|
| 118 else |
|
| 119 sent = g_strdup(message); |
|
| 120 |
|
| 121 msgflags |= GAIM_MESSAGE_SEND; |
|
| 122 |
|
| 123 if (type == GAIM_CONV_TYPE_IM) { |
|
| 124 GaimConvIm *im = GAIM_CONV_IM(conv); |
|
| 125 |
|
| 126 gaim_signal_emit(gaim_conversations_get_handle(), "sending-im-msg", |
|
| 127 account, |
|
| 128 gaim_conversation_get_name(conv), &sent); |
|
| 129 |
|
| 130 if (sent != NULL && sent[0] != '\0') { |
|
| 131 |
|
| 132 err = serv_send_im(gc, gaim_conversation_get_name(conv), |
|
| 133 sent, msgflags); |
|
| 134 |
|
| 135 if ((err > 0) && (displayed != NULL)) |
|
| 136 gaim_conv_im_write(im, NULL, displayed, msgflags, time(NULL)); |
|
| 137 |
|
| 138 gaim_signal_emit(gaim_conversations_get_handle(), "sent-im-msg", |
|
| 139 account, |
|
| 140 gaim_conversation_get_name(conv), sent); |
|
| 141 } |
|
| 142 } |
|
| 143 else { |
|
| 144 gaim_signal_emit(gaim_conversations_get_handle(), "sending-chat-msg", |
|
| 145 account, &sent, |
|
| 146 gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv))); |
|
| 147 |
|
| 148 if (sent != NULL && sent[0] != '\0') { |
|
| 149 err = serv_chat_send(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)), sent, msgflags); |
|
| 150 |
|
| 151 gaim_signal_emit(gaim_conversations_get_handle(), "sent-chat-msg", |
|
| 152 account, sent, |
|
| 153 gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv))); |
|
| 154 } |
|
| 155 } |
|
| 156 |
|
| 157 if (err < 0) { |
|
| 158 const char *who; |
|
| 159 const char *msg; |
|
| 160 |
|
| 161 who = gaim_conversation_get_name(conv); |
|
| 162 |
|
| 163 if (err == -E2BIG) { |
|
| 164 msg = _("Unable to send message: The message is too large."); |
|
| 165 |
|
| 166 if (!gaim_conv_present_error(who, account, msg)) { |
|
| 167 char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who); |
|
| 168 gaim_notify_error(gc, NULL, msg2, _("The message is too large.")); |
|
| 169 g_free(msg2); |
|
| 170 } |
|
| 171 } |
|
| 172 else if (err == -ENOTCONN) { |
|
| 173 gaim_debug(GAIM_DEBUG_ERROR, "conversation", |
|
| 174 "Not yet connected.\n"); |
|
| 175 } |
|
| 176 else { |
|
| 177 msg = _("Unable to send message."); |
|
| 178 |
|
| 179 if (!gaim_conv_present_error(who, account, msg)) { |
|
| 180 char *msg2 = g_strdup_printf(_("Unable to send message to %s."), who); |
|
| 181 gaim_notify_error(gc, NULL, msg2, NULL); |
|
| 182 g_free(msg2); |
|
| 183 } |
|
| 184 } |
|
| 185 } |
|
| 186 |
|
| 187 g_free(displayed); |
|
| 188 g_free(sent); |
|
| 189 } |
|
| 190 |
|
| 191 static void |
|
| 192 open_log(GaimConversation *conv) |
|
| 193 { |
|
| 194 conv->logs = g_list_append(NULL, gaim_log_new(conv->type == GAIM_CONV_TYPE_CHAT ? GAIM_LOG_CHAT : |
|
| 195 GAIM_LOG_IM, conv->name, conv->account, |
|
| 196 conv, time(NULL), NULL)); |
|
| 197 } |
|
| 198 |
|
| 199 |
|
| 200 /************************************************************************** |
|
| 201 * Conversation API |
|
| 202 **************************************************************************/ |
|
| 203 static void |
|
| 204 gaim_conversation_chat_cleanup_for_rejoin(GaimConversation *conv) |
|
| 205 { |
|
| 206 const char *disp; |
|
| 207 GaimAccount *account; |
|
| 208 GaimConnection *gc; |
|
| 209 |
|
| 210 account = gaim_conversation_get_account(conv); |
|
| 211 |
|
| 212 gaim_conversation_close_logs(conv); |
|
| 213 open_log(conv); |
|
| 214 |
|
| 215 gc = gaim_account_get_connection(account); |
|
| 216 |
|
| 217 if ((disp = gaim_connection_get_display_name(gc)) != NULL) |
|
| 218 gaim_conv_chat_set_nick(GAIM_CONV_CHAT(conv), disp); |
|
| 219 else |
|
| 220 { |
|
| 221 gaim_conv_chat_set_nick(GAIM_CONV_CHAT(conv), |
|
| 222 gaim_account_get_username(account)); |
|
| 223 } |
|
| 224 |
|
| 225 gaim_conv_chat_clear_users(GAIM_CONV_CHAT(conv)); |
|
| 226 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(conv), NULL, NULL); |
|
| 227 GAIM_CONV_CHAT(conv)->left = FALSE; |
|
| 228 |
|
| 229 gaim_conversation_update(conv, GAIM_CONV_UPDATE_CHATLEFT); |
|
| 230 } |
|
| 231 |
|
| 232 GaimConversation * |
|
| 233 gaim_conversation_new(GaimConversationType type, GaimAccount *account, |
|
| 234 const char *name) |
|
| 235 { |
|
| 236 GaimConversation *conv; |
|
| 237 GaimConnection *gc; |
|
| 238 GaimConversationUiOps *ops; |
|
| 239 |
|
| 240 g_return_val_if_fail(type != GAIM_CONV_TYPE_UNKNOWN, NULL); |
|
| 241 g_return_val_if_fail(account != NULL, NULL); |
|
| 242 g_return_val_if_fail(name != NULL, NULL); |
|
| 243 |
|
| 244 /* Check if this conversation already exists. */ |
|
| 245 if ((conv = gaim_find_conversation_with_account(type, name, account)) != NULL) |
|
| 246 { |
|
| 247 if (gaim_conversation_get_type(conv) != GAIM_CONV_TYPE_CHAT || |
|
| 248 gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv))) |
|
| 249 { |
|
| 250 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) |
|
| 251 gaim_conversation_chat_cleanup_for_rejoin(conv); |
|
| 252 |
|
| 253 return conv; |
|
| 254 } |
|
| 255 } |
|
| 256 |
|
| 257 gc = gaim_account_get_connection(account); |
|
| 258 g_return_val_if_fail(gc != NULL, NULL); |
|
| 259 |
|
| 260 conv = g_new0(GaimConversation, 1); |
|
| 261 GAIM_DBUS_REGISTER_POINTER(conv, GaimConversation); |
|
| 262 |
|
| 263 conv->type = type; |
|
| 264 conv->account = account; |
|
| 265 conv->name = g_strdup(name); |
|
| 266 conv->title = g_strdup(name); |
|
| 267 conv->data = g_hash_table_new_full(g_str_hash, g_str_equal, |
|
| 268 g_free, NULL); |
|
| 269 /* copy features from the connection. */ |
|
| 270 conv->features = gc->flags; |
|
| 271 |
|
| 272 if (type == GAIM_CONV_TYPE_IM) |
|
| 273 { |
|
| 274 GaimBuddyIcon *icon; |
|
| 275 conv->u.im = g_new0(GaimConvIm, 1); |
|
| 276 conv->u.im->conv = conv; |
|
| 277 GAIM_DBUS_REGISTER_POINTER(conv->u.im, GaimConvIm); |
|
| 278 |
|
| 279 ims = g_list_append(ims, conv); |
|
| 280 if ((icon = gaim_buddy_icons_find(account, name))) |
|
| 281 gaim_conv_im_set_icon(conv->u.im, icon); |
|
| 282 |
|
| 283 if (gaim_prefs_get_bool("/core/logging/log_ims")) |
|
| 284 { |
|
| 285 gaim_conversation_set_logging(conv, TRUE); |
|
| 286 open_log(conv); |
|
| 287 } |
|
| 288 } |
|
| 289 else if (type == GAIM_CONV_TYPE_CHAT) |
|
| 290 { |
|
| 291 const char *disp; |
|
| 292 |
|
| 293 conv->u.chat = g_new0(GaimConvChat, 1); |
|
| 294 conv->u.chat->conv = conv; |
|
| 295 GAIM_DBUS_REGISTER_POINTER(conv->u.chat, GaimConvChat); |
|
| 296 |
|
| 297 chats = g_list_append(chats, conv); |
|
| 298 |
|
| 299 if ((disp = gaim_connection_get_display_name(account->gc))) |
|
| 300 gaim_conv_chat_set_nick(conv->u.chat, disp); |
|
| 301 else |
|
| 302 gaim_conv_chat_set_nick(conv->u.chat, |
|
| 303 gaim_account_get_username(account)); |
|
| 304 |
|
| 305 if (gaim_prefs_get_bool("/core/logging/log_chats")) |
|
| 306 { |
|
| 307 gaim_conversation_set_logging(conv, TRUE); |
|
| 308 open_log(conv); |
|
| 309 } |
|
| 310 } |
|
| 311 |
|
| 312 conversations = g_list_append(conversations, conv); |
|
| 313 |
|
| 314 /* Auto-set the title. */ |
|
| 315 gaim_conversation_autoset_title(conv); |
|
| 316 |
|
| 317 /* Don't move this.. it needs to be one of the last things done otherwise |
|
| 318 * it causes mysterious crashes on my system. |
|
| 319 * -- Gary |
|
| 320 */ |
|
| 321 ops = conv->ui_ops = default_ops; |
|
| 322 if (ops != NULL && ops->create_conversation != NULL) |
|
| 323 ops->create_conversation(conv); |
|
| 324 |
|
| 325 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 326 "conversation-created", conv); |
|
| 327 |
|
| 328 return conv; |
|
| 329 } |
|
| 330 |
|
| 331 void |
|
| 332 gaim_conversation_destroy(GaimConversation *conv) |
|
| 333 { |
|
| 334 GaimPluginProtocolInfo *prpl_info = NULL; |
|
| 335 GaimConversationUiOps *ops; |
|
| 336 GaimConnection *gc; |
|
| 337 const char *name; |
|
| 338 |
|
| 339 g_return_if_fail(conv != NULL); |
|
| 340 |
|
| 341 ops = gaim_conversation_get_ui_ops(conv); |
|
| 342 gc = gaim_conversation_get_gc(conv); |
|
| 343 name = gaim_conversation_get_name(conv); |
|
| 344 |
|
| 345 if (gc != NULL) |
|
| 346 { |
|
| 347 /* Still connected */ |
|
| 348 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 349 |
|
| 350 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) |
|
| 351 { |
|
| 352 if (gaim_prefs_get_bool("/core/conversations/im/send_typing")) |
|
| 353 serv_send_typing(gc, name, GAIM_NOT_TYPING); |
|
| 354 |
|
| 355 if (gc && prpl_info->convo_closed != NULL) |
|
| 356 prpl_info->convo_closed(gc, name); |
|
| 357 } |
|
| 358 else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) |
|
| 359 { |
|
| 360 int chat_id = gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)); |
|
| 361 #if 0 |
|
| 362 /* |
|
| 363 * This is unfortunately necessary, because calling |
|
| 364 * serv_chat_leave() calls this gaim_conversation_destroy(), |
|
| 365 * which leads to two calls here.. We can't just return after |
|
| 366 * this, because then it'll return on the next pass. So, since |
|
| 367 * serv_got_chat_left(), which is eventually called from the |
|
| 368 * prpl that serv_chat_leave() calls, removes this conversation |
|
| 369 * from the gc's buddy_chats list, we're going to check to see |
|
| 370 * if this exists in the list. If so, we want to return after |
|
| 371 * calling this, because it'll be called again. If not, fall |
|
| 372 * through, because it'll have already been removed, and we'd |
|
| 373 * be on the 2nd pass. |
|
| 374 * |
|
| 375 * Long paragraph. <-- Short sentence. |
|
| 376 * |
|
| 377 * -- ChipX86 |
|
| 378 */ |
|
| 379 |
|
| 380 if (gc && g_slist_find(gc->buddy_chats, conv) != NULL) { |
|
| 381 serv_chat_leave(gc, chat_id); |
|
| 382 |
|
| 383 return; |
|
| 384 } |
|
| 385 #endif |
|
| 386 /* |
|
| 387 * Instead of all of that, lets just close the window when |
|
| 388 * the user tells us to, and let the prpl deal with the |
|
| 389 * internals on it's own time. Don't do this if the prpl already |
|
| 390 * knows it left the chat. |
|
| 391 */ |
|
| 392 if (!gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv))) |
|
| 393 serv_chat_leave(gc, chat_id); |
|
| 394 |
|
| 395 /* |
|
| 396 * If they didn't call serv_got_chat_left by now, it's too late. |
|
| 397 * So we better do it for them before we destroy the thing. |
|
| 398 */ |
|
| 399 if (!gaim_conv_chat_has_left(GAIM_CONV_CHAT(conv))) |
|
| 400 serv_got_chat_left(gc, chat_id); |
|
| 401 } |
|
| 402 } |
|
| 403 |
|
| 404 /* remove from conversations and im/chats lists prior to emit */ |
|
| 405 conversations = g_list_remove(conversations, conv); |
|
| 406 |
|
| 407 if(conv->type==GAIM_CONV_TYPE_IM) |
|
| 408 ims = g_list_remove(ims, conv); |
|
| 409 else if(conv->type==GAIM_CONV_TYPE_CHAT) |
|
| 410 chats = g_list_remove(chats, conv); |
|
| 411 |
|
| 412 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 413 "deleting-conversation", conv); |
|
| 414 |
|
| 415 g_free(conv->name); |
|
| 416 g_free(conv->title); |
|
| 417 |
|
| 418 conv->name = NULL; |
|
| 419 conv->title = NULL; |
|
| 420 |
|
| 421 if (conv->type == GAIM_CONV_TYPE_IM) { |
|
| 422 gaim_conv_im_stop_typing_timeout(conv->u.im); |
|
| 423 gaim_conv_im_stop_send_typed_timeout(conv->u.im); |
|
| 424 |
|
| 425 if (conv->u.im->icon != NULL) |
|
| 426 gaim_buddy_icon_unref(conv->u.im->icon); |
|
| 427 conv->u.im->icon = NULL; |
|
| 428 |
|
| 429 GAIM_DBUS_UNREGISTER_POINTER(conv->u.im); |
|
| 430 g_free(conv->u.im); |
|
| 431 conv->u.im = NULL; |
|
| 432 } |
|
| 433 else if (conv->type == GAIM_CONV_TYPE_CHAT) { |
|
| 434 |
|
| 435 g_list_foreach(conv->u.chat->in_room, (GFunc)gaim_conv_chat_cb_destroy, NULL); |
|
| 436 g_list_free(conv->u.chat->in_room); |
|
| 437 |
|
| 438 g_list_foreach(conv->u.chat->ignored, (GFunc)g_free, NULL); |
|
| 439 g_list_free(conv->u.chat->ignored); |
|
| 440 |
|
| 441 conv->u.chat->in_room = NULL; |
|
| 442 conv->u.chat->ignored = NULL; |
|
| 443 |
|
| 444 g_free(conv->u.chat->who); |
|
| 445 conv->u.chat->who = NULL; |
|
| 446 |
|
| 447 g_free(conv->u.chat->topic); |
|
| 448 conv->u.chat->topic = NULL; |
|
| 449 |
|
| 450 g_free(conv->u.chat->nick); |
|
| 451 |
|
| 452 GAIM_DBUS_UNREGISTER_POINTER(conv->u.chat); |
|
| 453 g_free(conv->u.chat); |
|
| 454 conv->u.chat = NULL; |
|
| 455 } |
|
| 456 |
|
| 457 g_hash_table_destroy(conv->data); |
|
| 458 conv->data = NULL; |
|
| 459 |
|
| 460 if (ops != NULL && ops->destroy_conversation != NULL) |
|
| 461 ops->destroy_conversation(conv); |
|
| 462 |
|
| 463 gaim_conversation_close_logs(conv); |
|
| 464 |
|
| 465 GAIM_DBUS_UNREGISTER_POINTER(conv); |
|
| 466 g_free(conv); |
|
| 467 conv = NULL; |
|
| 468 } |
|
| 469 |
|
| 470 |
|
| 471 void |
|
| 472 gaim_conversation_present(GaimConversation *conv) { |
|
| 473 GaimConversationUiOps *ops; |
|
| 474 |
|
| 475 g_return_if_fail(conv != NULL); |
|
| 476 |
|
| 477 ops = gaim_conversation_get_ui_ops(conv); |
|
| 478 if(ops && ops->present) |
|
| 479 ops->present(conv); |
|
| 480 } |
|
| 481 |
|
| 482 |
|
| 483 void |
|
| 484 gaim_conversation_set_features(GaimConversation *conv, GaimConnectionFlags features) |
|
| 485 { |
|
| 486 g_return_if_fail(conv != NULL); |
|
| 487 |
|
| 488 conv->features = features; |
|
| 489 |
|
| 490 gaim_conversation_update(conv, GAIM_CONV_UPDATE_FEATURES); |
|
| 491 } |
|
| 492 |
|
| 493 |
|
| 494 GaimConnectionFlags |
|
| 495 gaim_conversation_get_features(GaimConversation *conv) |
|
| 496 { |
|
| 497 g_return_val_if_fail(conv != NULL, 0); |
|
| 498 return conv->features; |
|
| 499 } |
|
| 500 |
|
| 501 |
|
| 502 GaimConversationType |
|
| 503 gaim_conversation_get_type(const GaimConversation *conv) |
|
| 504 { |
|
| 505 g_return_val_if_fail(conv != NULL, GAIM_CONV_TYPE_UNKNOWN); |
|
| 506 |
|
| 507 return conv->type; |
|
| 508 } |
|
| 509 |
|
| 510 void |
|
| 511 gaim_conversation_set_ui_ops(GaimConversation *conv, |
|
| 512 GaimConversationUiOps *ops) |
|
| 513 { |
|
| 514 g_return_if_fail(conv != NULL); |
|
| 515 |
|
| 516 if (conv->ui_ops == ops) |
|
| 517 return; |
|
| 518 |
|
| 519 if (conv->ui_ops != NULL && conv->ui_ops->destroy_conversation != NULL) |
|
| 520 conv->ui_ops->destroy_conversation(conv); |
|
| 521 |
|
| 522 conv->ui_data = NULL; |
|
| 523 |
|
| 524 conv->ui_ops = ops; |
|
| 525 } |
|
| 526 |
|
| 527 GaimConversationUiOps * |
|
| 528 gaim_conversation_get_ui_ops(const GaimConversation *conv) |
|
| 529 { |
|
| 530 g_return_val_if_fail(conv != NULL, NULL); |
|
| 531 |
|
| 532 return conv->ui_ops; |
|
| 533 } |
|
| 534 |
|
| 535 void |
|
| 536 gaim_conversation_set_account(GaimConversation *conv, GaimAccount *account) |
|
| 537 { |
|
| 538 g_return_if_fail(conv != NULL); |
|
| 539 |
|
| 540 if (account == gaim_conversation_get_account(conv)) |
|
| 541 return; |
|
| 542 |
|
| 543 conv->account = account; |
|
| 544 |
|
| 545 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ACCOUNT); |
|
| 546 } |
|
| 547 |
|
| 548 GaimAccount * |
|
| 549 gaim_conversation_get_account(const GaimConversation *conv) |
|
| 550 { |
|
| 551 g_return_val_if_fail(conv != NULL, NULL); |
|
| 552 |
|
| 553 return conv->account; |
|
| 554 } |
|
| 555 |
|
| 556 GaimConnection * |
|
| 557 gaim_conversation_get_gc(const GaimConversation *conv) |
|
| 558 { |
|
| 559 GaimAccount *account; |
|
| 560 |
|
| 561 g_return_val_if_fail(conv != NULL, NULL); |
|
| 562 |
|
| 563 account = gaim_conversation_get_account(conv); |
|
| 564 |
|
| 565 if (account == NULL) |
|
| 566 return NULL; |
|
| 567 |
|
| 568 return account->gc; |
|
| 569 } |
|
| 570 |
|
| 571 void |
|
| 572 gaim_conversation_set_title(GaimConversation *conv, const char *title) |
|
| 573 { |
|
| 574 g_return_if_fail(conv != NULL); |
|
| 575 g_return_if_fail(title != NULL); |
|
| 576 |
|
| 577 g_free(conv->title); |
|
| 578 conv->title = g_strdup(title); |
|
| 579 |
|
| 580 gaim_conversation_update(conv, GAIM_CONV_UPDATE_TITLE); |
|
| 581 } |
|
| 582 |
|
| 583 const char * |
|
| 584 gaim_conversation_get_title(const GaimConversation *conv) |
|
| 585 { |
|
| 586 g_return_val_if_fail(conv != NULL, NULL); |
|
| 587 |
|
| 588 return conv->title; |
|
| 589 } |
|
| 590 |
|
| 591 void |
|
| 592 gaim_conversation_autoset_title(GaimConversation *conv) |
|
| 593 { |
|
| 594 GaimAccount *account; |
|
| 595 GaimBuddy *b; |
|
| 596 GaimChat *chat; |
|
| 597 const char *text = NULL, *name; |
|
| 598 |
|
| 599 g_return_if_fail(conv != NULL); |
|
| 600 |
|
| 601 account = gaim_conversation_get_account(conv); |
|
| 602 name = gaim_conversation_get_name(conv); |
|
| 603 |
|
| 604 if(gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) { |
|
| 605 if(account && ((b = gaim_find_buddy(account, name)) != NULL)) |
|
| 606 text = gaim_buddy_get_contact_alias(b); |
|
| 607 } else if(gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) { |
|
| 608 if(account && ((chat = gaim_blist_find_chat(account, name)) != NULL)) |
|
| 609 text = chat->alias; |
|
| 610 } |
|
| 611 |
|
| 612 |
|
| 613 if(text == NULL) |
|
| 614 text = name; |
|
| 615 |
|
| 616 gaim_conversation_set_title(conv, text); |
|
| 617 } |
|
| 618 |
|
| 619 void |
|
| 620 gaim_conversation_foreach(void (*func)(GaimConversation *conv)) |
|
| 621 { |
|
| 622 GaimConversation *conv; |
|
| 623 GList *l; |
|
| 624 |
|
| 625 g_return_if_fail(func != NULL); |
|
| 626 |
|
| 627 for (l = gaim_get_conversations(); l != NULL; l = l->next) { |
|
| 628 conv = (GaimConversation *)l->data; |
|
| 629 |
|
| 630 func(conv); |
|
| 631 } |
|
| 632 } |
|
| 633 |
|
| 634 void |
|
| 635 gaim_conversation_set_name(GaimConversation *conv, const char *name) |
|
| 636 { |
|
| 637 g_return_if_fail(conv != NULL); |
|
| 638 |
|
| 639 g_free(conv->name); |
|
| 640 conv->name = g_strdup(name); |
|
| 641 |
|
| 642 gaim_conversation_autoset_title(conv); |
|
| 643 } |
|
| 644 |
|
| 645 const char * |
|
| 646 gaim_conversation_get_name(const GaimConversation *conv) |
|
| 647 { |
|
| 648 g_return_val_if_fail(conv != NULL, NULL); |
|
| 649 |
|
| 650 return conv->name; |
|
| 651 } |
|
| 652 |
|
| 653 void |
|
| 654 gaim_conversation_set_logging(GaimConversation *conv, gboolean log) |
|
| 655 { |
|
| 656 g_return_if_fail(conv != NULL); |
|
| 657 |
|
| 658 if (conv->logging != log) |
|
| 659 { |
|
| 660 conv->logging = log; |
|
| 661 gaim_conversation_update(conv, GAIM_CONV_UPDATE_LOGGING); |
|
| 662 } |
|
| 663 } |
|
| 664 |
|
| 665 gboolean |
|
| 666 gaim_conversation_is_logging(const GaimConversation *conv) |
|
| 667 { |
|
| 668 g_return_val_if_fail(conv != NULL, FALSE); |
|
| 669 |
|
| 670 return conv->logging; |
|
| 671 } |
|
| 672 |
|
| 673 void |
|
| 674 gaim_conversation_close_logs(GaimConversation *conv) |
|
| 675 { |
|
| 676 g_return_if_fail(conv != NULL); |
|
| 677 |
|
| 678 g_list_foreach(conv->logs, (GFunc)gaim_log_free, NULL); |
|
| 679 g_list_free(conv->logs); |
|
| 680 conv->logs = NULL; |
|
| 681 } |
|
| 682 |
|
| 683 GaimConvIm * |
|
| 684 gaim_conversation_get_im_data(const GaimConversation *conv) |
|
| 685 { |
|
| 686 g_return_val_if_fail(conv != NULL, NULL); |
|
| 687 |
|
| 688 if (gaim_conversation_get_type(conv) != GAIM_CONV_TYPE_IM) |
|
| 689 return NULL; |
|
| 690 |
|
| 691 return conv->u.im; |
|
| 692 } |
|
| 693 |
|
| 694 GaimConvChat * |
|
| 695 gaim_conversation_get_chat_data(const GaimConversation *conv) |
|
| 696 { |
|
| 697 g_return_val_if_fail(conv != NULL, NULL); |
|
| 698 |
|
| 699 if (gaim_conversation_get_type(conv) != GAIM_CONV_TYPE_CHAT) |
|
| 700 return NULL; |
|
| 701 |
|
| 702 return conv->u.chat; |
|
| 703 } |
|
| 704 |
|
| 705 void |
|
| 706 gaim_conversation_set_data(GaimConversation *conv, const char *key, |
|
| 707 gpointer data) |
|
| 708 { |
|
| 709 g_return_if_fail(conv != NULL); |
|
| 710 g_return_if_fail(key != NULL); |
|
| 711 |
|
| 712 g_hash_table_replace(conv->data, g_strdup(key), data); |
|
| 713 } |
|
| 714 |
|
| 715 gpointer |
|
| 716 gaim_conversation_get_data(GaimConversation *conv, const char *key) |
|
| 717 { |
|
| 718 g_return_val_if_fail(conv != NULL, NULL); |
|
| 719 g_return_val_if_fail(key != NULL, NULL); |
|
| 720 |
|
| 721 return g_hash_table_lookup(conv->data, key); |
|
| 722 } |
|
| 723 |
|
| 724 GList * |
|
| 725 gaim_get_conversations(void) |
|
| 726 { |
|
| 727 return conversations; |
|
| 728 } |
|
| 729 |
|
| 730 GList * |
|
| 731 gaim_get_ims(void) |
|
| 732 { |
|
| 733 return ims; |
|
| 734 } |
|
| 735 |
|
| 736 GList * |
|
| 737 gaim_get_chats(void) |
|
| 738 { |
|
| 739 return chats; |
|
| 740 } |
|
| 741 |
|
| 742 |
|
| 743 GaimConversation * |
|
| 744 gaim_find_conversation_with_account(GaimConversationType type, |
|
| 745 const char *name, |
|
| 746 const GaimAccount *account) |
|
| 747 { |
|
| 748 GaimConversation *c = NULL; |
|
| 749 gchar *name1; |
|
| 750 const gchar *name2; |
|
| 751 GList *cnv; |
|
| 752 |
|
| 753 g_return_val_if_fail(name != NULL, NULL); |
|
| 754 |
|
| 755 name1 = g_strdup(gaim_normalize(account, name)); |
|
| 756 |
|
| 757 for (cnv = gaim_get_conversations(); cnv != NULL; cnv = cnv->next) { |
|
| 758 c = (GaimConversation *)cnv->data; |
|
| 759 name2 = gaim_normalize(account, gaim_conversation_get_name(c)); |
|
| 760 |
|
| 761 if (((type == GAIM_CONV_TYPE_ANY) || (type == gaim_conversation_get_type(c))) && |
|
| 762 (account == gaim_conversation_get_account(c)) && |
|
| 763 !gaim_utf8_strcasecmp(name1, name2)) { |
|
| 764 |
|
| 765 break; |
|
| 766 } |
|
| 767 |
|
| 768 c = NULL; |
|
| 769 } |
|
| 770 |
|
| 771 g_free(name1); |
|
| 772 |
|
| 773 return c; |
|
| 774 } |
|
| 775 |
|
| 776 void |
|
| 777 gaim_conversation_write(GaimConversation *conv, const char *who, |
|
| 778 const char *message, GaimMessageFlags flags, |
|
| 779 time_t mtime) |
|
| 780 { |
|
| 781 GaimPluginProtocolInfo *prpl_info = NULL; |
|
| 782 GaimConnection *gc = NULL; |
|
| 783 GaimAccount *account; |
|
| 784 GaimConversationUiOps *ops; |
|
| 785 const char *alias; |
|
| 786 char *displayed = NULL; |
|
| 787 GaimBuddy *b; |
|
| 788 int plugin_return; |
|
| 789 GaimConversationType type; |
|
| 790 /* int logging_font_options = 0; */ |
|
| 791 |
|
| 792 g_return_if_fail(conv != NULL); |
|
| 793 g_return_if_fail(message != NULL); |
|
| 794 |
|
| 795 ops = gaim_conversation_get_ui_ops(conv); |
|
| 796 |
|
| 797 if (ops == NULL || ops->write_conv == NULL) |
|
| 798 return; |
|
| 799 |
|
| 800 account = gaim_conversation_get_account(conv); |
|
| 801 type = gaim_conversation_get_type(conv); |
|
| 802 |
|
| 803 if (account != NULL) |
|
| 804 gc = gaim_account_get_connection(account); |
|
| 805 |
|
| 806 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT && |
|
| 807 (gc == NULL || !g_slist_find(gc->buddy_chats, conv))) |
|
| 808 return; |
|
| 809 |
|
| 810 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM && |
|
| 811 !g_list_find(gaim_get_conversations(), conv)) |
|
| 812 return; |
|
| 813 |
|
| 814 displayed = g_strdup(message); |
|
| 815 |
|
| 816 plugin_return = |
|
| 817 GPOINTER_TO_INT(gaim_signal_emit_return_1( |
|
| 818 gaim_conversations_get_handle(), |
|
| 819 (type == GAIM_CONV_TYPE_IM ? "writing-im-msg" : "writing-chat-msg"), |
|
| 820 account, who, &displayed, conv, flags)); |
|
| 821 |
|
| 822 if (displayed == NULL) |
|
| 823 return; |
|
| 824 |
|
| 825 if (plugin_return) { |
|
| 826 g_free(displayed); |
|
| 827 return; |
|
| 828 } |
|
| 829 |
|
| 830 if (who == NULL || *who == '\0') |
|
| 831 who = gaim_conversation_get_name(conv); |
|
| 832 |
|
| 833 alias = who; |
|
| 834 |
|
| 835 if (account != NULL) { |
|
| 836 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gaim_find_prpl(gaim_account_get_protocol_id(account))); |
|
| 837 |
|
| 838 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM || |
|
| 839 !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
|
| 840 |
|
| 841 if (flags & GAIM_MESSAGE_SEND) { |
|
| 842 b = gaim_find_buddy(account, |
|
| 843 gaim_account_get_username(account)); |
|
| 844 |
|
| 845 if (gaim_account_get_alias(account) != NULL) |
|
| 846 alias = account->alias; |
|
| 847 else if (b != NULL && strcmp(b->name, gaim_buddy_get_contact_alias(b))) |
|
| 848 alias = gaim_buddy_get_contact_alias(b); |
|
| 849 else if (gaim_connection_get_display_name(gc) != NULL) |
|
| 850 alias = gaim_connection_get_display_name(gc); |
|
| 851 else |
|
| 852 alias = gaim_account_get_username(account); |
|
| 853 } |
|
| 854 else |
|
| 855 { |
|
| 856 b = gaim_find_buddy(account, who); |
|
| 857 |
|
| 858 if (b != NULL) |
|
| 859 alias = gaim_buddy_get_contact_alias(b); |
|
| 860 } |
|
| 861 } |
|
| 862 } |
|
| 863 |
|
| 864 if (!(flags & GAIM_MESSAGE_NO_LOG) && gaim_conversation_is_logging(conv)) { |
|
| 865 GList *log; |
|
| 866 |
|
| 867 if (conv->logs == NULL) |
|
| 868 open_log(conv); |
|
| 869 |
|
| 870 log = conv->logs; |
|
| 871 while (log != NULL) { |
|
| 872 gaim_log_write((GaimLog *)log->data, flags, alias, mtime, displayed); |
|
| 873 log = log->next; |
|
| 874 } |
|
| 875 } |
|
| 876 |
|
| 877 if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) { |
|
| 878 if ((flags & GAIM_MESSAGE_RECV) == GAIM_MESSAGE_RECV) { |
|
| 879 gaim_conv_im_set_typing_state(GAIM_CONV_IM(conv), GAIM_NOT_TYPING); |
|
| 880 } |
|
| 881 } |
|
| 882 |
|
| 883 ops->write_conv(conv, who, alias, displayed, flags, mtime); |
|
| 884 |
|
| 885 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 886 (type == GAIM_CONV_TYPE_IM ? "wrote-im-msg" : "wrote-chat-msg"), |
|
| 887 account, who, displayed, conv, flags); |
|
| 888 |
|
| 889 g_free(displayed); |
|
| 890 } |
|
| 891 |
|
| 892 gboolean |
|
| 893 gaim_conversation_has_focus(GaimConversation *conv) |
|
| 894 { |
|
| 895 gboolean ret = FALSE; |
|
| 896 GaimConversationUiOps *ops; |
|
| 897 |
|
| 898 g_return_val_if_fail(conv != NULL, FALSE); |
|
| 899 |
|
| 900 ops = gaim_conversation_get_ui_ops(conv); |
|
| 901 |
|
| 902 if (ops != NULL && ops->has_focus != NULL) |
|
| 903 ret = ops->has_focus(conv); |
|
| 904 |
|
| 905 return ret; |
|
| 906 } |
|
| 907 |
|
| 908 /* |
|
| 909 * TODO: Need to make sure calls to this function happen in the core |
|
| 910 * instead of the UI. That way UIs have less work to do, and the |
|
| 911 * core/UI split is cleaner. Also need to make sure this is called |
|
| 912 * when chats are added/removed from the blist. |
|
| 913 */ |
|
| 914 void |
|
| 915 gaim_conversation_update(GaimConversation *conv, GaimConvUpdateType type) |
|
| 916 { |
|
| 917 g_return_if_fail(conv != NULL); |
|
| 918 |
|
| 919 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 920 "conversation-updated", conv, type); |
|
| 921 } |
|
| 922 |
|
| 923 /************************************************************************** |
|
| 924 * IM Conversation API |
|
| 925 **************************************************************************/ |
|
| 926 GaimConversation * |
|
| 927 gaim_conv_im_get_conversation(const GaimConvIm *im) |
|
| 928 { |
|
| 929 g_return_val_if_fail(im != NULL, NULL); |
|
| 930 |
|
| 931 return im->conv; |
|
| 932 } |
|
| 933 |
|
| 934 void |
|
| 935 gaim_conv_im_set_icon(GaimConvIm *im, GaimBuddyIcon *icon) |
|
| 936 { |
|
| 937 g_return_if_fail(im != NULL); |
|
| 938 |
|
| 939 if (im->icon != icon) |
|
| 940 { |
|
| 941 if (im->icon != NULL) |
|
| 942 gaim_buddy_icon_unref(im->icon); |
|
| 943 |
|
| 944 im->icon = (icon == NULL ? NULL : gaim_buddy_icon_ref(icon)); |
|
| 945 } |
|
| 946 |
|
| 947 gaim_conversation_update(gaim_conv_im_get_conversation(im), |
|
| 948 GAIM_CONV_UPDATE_ICON); |
|
| 949 } |
|
| 950 |
|
| 951 GaimBuddyIcon * |
|
| 952 gaim_conv_im_get_icon(const GaimConvIm *im) |
|
| 953 { |
|
| 954 g_return_val_if_fail(im != NULL, NULL); |
|
| 955 |
|
| 956 return im->icon; |
|
| 957 } |
|
| 958 |
|
| 959 void |
|
| 960 gaim_conv_im_set_typing_state(GaimConvIm *im, GaimTypingState state) |
|
| 961 { |
|
| 962 g_return_if_fail(im != NULL); |
|
| 963 |
|
| 964 if (im->typing_state != state) |
|
| 965 { |
|
| 966 im->typing_state = state; |
|
| 967 |
|
| 968 if (state == GAIM_TYPING) |
|
| 969 { |
|
| 970 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 971 "buddy-typing", im->conv->account, im->conv->name); |
|
| 972 } |
|
| 973 else if (state == GAIM_TYPED) |
|
| 974 { |
|
| 975 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 976 "buddy-typed", im->conv->account, im->conv->name); |
|
| 977 } |
|
| 978 else if (state == GAIM_NOT_TYPING) |
|
| 979 { |
|
| 980 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 981 "buddy-typing-stopped", im->conv->account, im->conv->name); |
|
| 982 } |
|
| 983 } |
|
| 984 } |
|
| 985 |
|
| 986 GaimTypingState |
|
| 987 gaim_conv_im_get_typing_state(const GaimConvIm *im) |
|
| 988 { |
|
| 989 g_return_val_if_fail(im != NULL, 0); |
|
| 990 |
|
| 991 return im->typing_state; |
|
| 992 } |
|
| 993 |
|
| 994 void |
|
| 995 gaim_conv_im_start_typing_timeout(GaimConvIm *im, int timeout) |
|
| 996 { |
|
| 997 GaimConversation *conv; |
|
| 998 const char *name; |
|
| 999 |
|
| 1000 g_return_if_fail(im != NULL); |
|
| 1001 |
|
| 1002 if (im->typing_timeout > 0) |
|
| 1003 gaim_conv_im_stop_typing_timeout(im); |
|
| 1004 |
|
| 1005 conv = gaim_conv_im_get_conversation(im); |
|
| 1006 name = gaim_conversation_get_name(conv); |
|
| 1007 |
|
| 1008 im->typing_timeout = gaim_timeout_add(timeout * 1000, reset_typing_cb, conv); |
|
| 1009 } |
|
| 1010 |
|
| 1011 void |
|
| 1012 gaim_conv_im_stop_typing_timeout(GaimConvIm *im) |
|
| 1013 { |
|
| 1014 g_return_if_fail(im != NULL); |
|
| 1015 |
|
| 1016 if (im->typing_timeout == 0) |
|
| 1017 return; |
|
| 1018 |
|
| 1019 gaim_timeout_remove(im->typing_timeout); |
|
| 1020 im->typing_timeout = 0; |
|
| 1021 } |
|
| 1022 |
|
| 1023 guint |
|
| 1024 gaim_conv_im_get_typing_timeout(const GaimConvIm *im) |
|
| 1025 { |
|
| 1026 g_return_val_if_fail(im != NULL, 0); |
|
| 1027 |
|
| 1028 return im->typing_timeout; |
|
| 1029 } |
|
| 1030 |
|
| 1031 void |
|
| 1032 gaim_conv_im_set_type_again(GaimConvIm *im, unsigned int val) |
|
| 1033 { |
|
| 1034 g_return_if_fail(im != NULL); |
|
| 1035 |
|
| 1036 if (val == 0) |
|
| 1037 im->type_again = 0; |
|
| 1038 else |
|
| 1039 im->type_again = time(NULL) + val; |
|
| 1040 } |
|
| 1041 |
|
| 1042 time_t |
|
| 1043 gaim_conv_im_get_type_again(const GaimConvIm *im) |
|
| 1044 { |
|
| 1045 g_return_val_if_fail(im != NULL, 0); |
|
| 1046 |
|
| 1047 return im->type_again; |
|
| 1048 } |
|
| 1049 |
|
| 1050 void |
|
| 1051 gaim_conv_im_start_send_typed_timeout(GaimConvIm *im) |
|
| 1052 { |
|
| 1053 g_return_if_fail(im != NULL); |
|
| 1054 |
|
| 1055 im->send_typed_timeout = gaim_timeout_add(SEND_TYPED_TIMEOUT, send_typed_cb, |
|
| 1056 gaim_conv_im_get_conversation(im)); |
|
| 1057 } |
|
| 1058 |
|
| 1059 void |
|
| 1060 gaim_conv_im_stop_send_typed_timeout(GaimConvIm *im) |
|
| 1061 { |
|
| 1062 g_return_if_fail(im != NULL); |
|
| 1063 |
|
| 1064 if (im->send_typed_timeout == 0) |
|
| 1065 return; |
|
| 1066 |
|
| 1067 gaim_timeout_remove(im->send_typed_timeout); |
|
| 1068 im->send_typed_timeout = 0; |
|
| 1069 } |
|
| 1070 |
|
| 1071 guint |
|
| 1072 gaim_conv_im_get_send_typed_timeout(const GaimConvIm *im) |
|
| 1073 { |
|
| 1074 g_return_val_if_fail(im != NULL, 0); |
|
| 1075 |
|
| 1076 return im->send_typed_timeout; |
|
| 1077 } |
|
| 1078 |
|
| 1079 void |
|
| 1080 gaim_conv_im_update_typing(GaimConvIm *im) |
|
| 1081 { |
|
| 1082 g_return_if_fail(im != NULL); |
|
| 1083 |
|
| 1084 gaim_conversation_update(gaim_conv_im_get_conversation(im), |
|
| 1085 GAIM_CONV_UPDATE_TYPING); |
|
| 1086 } |
|
| 1087 |
|
| 1088 void |
|
| 1089 gaim_conv_im_write(GaimConvIm *im, const char *who, const char *message, |
|
| 1090 GaimMessageFlags flags, time_t mtime) |
|
| 1091 { |
|
| 1092 GaimConversation *c; |
|
| 1093 |
|
| 1094 g_return_if_fail(im != NULL); |
|
| 1095 g_return_if_fail(message != NULL); |
|
| 1096 |
|
| 1097 c = gaim_conv_im_get_conversation(im); |
|
| 1098 |
|
| 1099 /* Raise the window, if specified in prefs. */ |
|
| 1100 if (c->ui_ops != NULL && c->ui_ops->write_im != NULL) |
|
| 1101 c->ui_ops->write_im(c, who, message, flags, mtime); |
|
| 1102 else |
|
| 1103 gaim_conversation_write(c, who, message, flags, mtime); |
|
| 1104 } |
|
| 1105 |
|
| 1106 gboolean gaim_conv_present_error(const char *who, GaimAccount *account, const char *what) |
|
| 1107 { |
|
| 1108 GaimConversation *conv; |
|
| 1109 |
|
| 1110 g_return_val_if_fail(who != NULL, FALSE); |
|
| 1111 g_return_val_if_fail(account !=NULL, FALSE); |
|
| 1112 g_return_val_if_fail(what != NULL, FALSE); |
|
| 1113 |
|
| 1114 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, who, account); |
|
| 1115 if (conv != NULL) |
|
| 1116 gaim_conversation_write(conv, NULL, what, GAIM_MESSAGE_ERROR, time(NULL)); |
|
| 1117 else |
|
| 1118 return FALSE; |
|
| 1119 |
|
| 1120 return TRUE; |
|
| 1121 } |
|
| 1122 |
|
| 1123 void |
|
| 1124 gaim_conv_im_send(GaimConvIm *im, const char *message) |
|
| 1125 { |
|
| 1126 gaim_conv_im_send_with_flags(im, message, 0); |
|
| 1127 } |
|
| 1128 |
|
| 1129 void |
|
| 1130 gaim_conv_im_send_with_flags(GaimConvIm *im, const char *message, GaimMessageFlags flags) |
|
| 1131 { |
|
| 1132 g_return_if_fail(im != NULL); |
|
| 1133 g_return_if_fail(message != NULL); |
|
| 1134 |
|
| 1135 common_send(gaim_conv_im_get_conversation(im), message, flags); |
|
| 1136 } |
|
| 1137 |
|
| 1138 gboolean |
|
| 1139 gaim_conv_custom_smiley_add(GaimConversation *conv, const char *smile, |
|
| 1140 const char *cksum_type, const char *chksum, |
|
| 1141 gboolean remote) |
|
| 1142 { |
|
| 1143 if (conv == NULL || smile == NULL || !*smile) { |
|
| 1144 return FALSE; |
|
| 1145 } |
|
| 1146 |
|
| 1147 /* TODO: check if the icon is in the cache and return false if so */ |
|
| 1148 /* TODO: add an icon cache (that doesn't suck) */ |
|
| 1149 if (conv->ui_ops != NULL && conv->ui_ops->custom_smiley_add !=NULL) { |
|
| 1150 return conv->ui_ops->custom_smiley_add(conv, smile, remote); |
|
| 1151 } else { |
|
| 1152 gaim_debug_info("conversation", "Could not find add custom smiley function"); |
|
| 1153 return FALSE; |
|
| 1154 } |
|
| 1155 |
|
| 1156 } |
|
| 1157 |
|
| 1158 void |
|
| 1159 gaim_conv_custom_smiley_write(GaimConversation *conv, const char *smile, |
|
| 1160 const guchar *data, gsize size) |
|
| 1161 { |
|
| 1162 g_return_if_fail(conv != NULL); |
|
| 1163 g_return_if_fail(smile != NULL && *smile); |
|
| 1164 |
|
| 1165 if (conv->ui_ops != NULL && conv->ui_ops->custom_smiley_write != NULL) |
|
| 1166 conv->ui_ops->custom_smiley_write(conv, smile, data, size); |
|
| 1167 else |
|
| 1168 gaim_debug_info("conversation", "Could not find the smiley write function"); |
|
| 1169 } |
|
| 1170 |
|
| 1171 void |
|
| 1172 gaim_conv_custom_smiley_close(GaimConversation *conv, const char *smile) |
|
| 1173 { |
|
| 1174 g_return_if_fail(conv != NULL); |
|
| 1175 g_return_if_fail(smile != NULL && *smile); |
|
| 1176 |
|
| 1177 if (conv->ui_ops != NULL && conv->ui_ops->custom_smiley_close != NULL) |
|
| 1178 conv->ui_ops->custom_smiley_close(conv, smile); |
|
| 1179 else |
|
| 1180 gaim_debug_info("conversation", "Could not find custom smiley close function"); |
|
| 1181 } |
|
| 1182 |
|
| 1183 |
|
| 1184 /************************************************************************** |
|
| 1185 * Chat Conversation API |
|
| 1186 **************************************************************************/ |
|
| 1187 |
|
| 1188 GaimConversation * |
|
| 1189 gaim_conv_chat_get_conversation(const GaimConvChat *chat) |
|
| 1190 { |
|
| 1191 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1192 |
|
| 1193 return chat->conv; |
|
| 1194 } |
|
| 1195 |
|
| 1196 GList * |
|
| 1197 gaim_conv_chat_set_users(GaimConvChat *chat, GList *users) |
|
| 1198 { |
|
| 1199 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1200 |
|
| 1201 chat->in_room = users; |
|
| 1202 |
|
| 1203 return users; |
|
| 1204 } |
|
| 1205 |
|
| 1206 GList * |
|
| 1207 gaim_conv_chat_get_users(const GaimConvChat *chat) |
|
| 1208 { |
|
| 1209 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1210 |
|
| 1211 return chat->in_room; |
|
| 1212 } |
|
| 1213 |
|
| 1214 void |
|
| 1215 gaim_conv_chat_ignore(GaimConvChat *chat, const char *name) |
|
| 1216 { |
|
| 1217 g_return_if_fail(chat != NULL); |
|
| 1218 g_return_if_fail(name != NULL); |
|
| 1219 |
|
| 1220 /* Make sure the user isn't already ignored. */ |
|
| 1221 if (gaim_conv_chat_is_user_ignored(chat, name)) |
|
| 1222 return; |
|
| 1223 |
|
| 1224 gaim_conv_chat_set_ignored(chat, |
|
| 1225 g_list_append(gaim_conv_chat_get_ignored(chat), g_strdup(name))); |
|
| 1226 } |
|
| 1227 |
|
| 1228 void |
|
| 1229 gaim_conv_chat_unignore(GaimConvChat *chat, const char *name) |
|
| 1230 { |
|
| 1231 GList *item; |
|
| 1232 |
|
| 1233 g_return_if_fail(chat != NULL); |
|
| 1234 g_return_if_fail(name != NULL); |
|
| 1235 |
|
| 1236 /* Make sure the user is actually ignored. */ |
|
| 1237 if (!gaim_conv_chat_is_user_ignored(chat, name)) |
|
| 1238 return; |
|
| 1239 |
|
| 1240 item = g_list_find(gaim_conv_chat_get_ignored(chat), |
|
| 1241 gaim_conv_chat_get_ignored_user(chat, name)); |
|
| 1242 |
|
| 1243 gaim_conv_chat_set_ignored(chat, |
|
| 1244 g_list_remove_link(gaim_conv_chat_get_ignored(chat), item)); |
|
| 1245 |
|
| 1246 g_free(item->data); |
|
| 1247 g_list_free_1(item); |
|
| 1248 } |
|
| 1249 |
|
| 1250 GList * |
|
| 1251 gaim_conv_chat_set_ignored(GaimConvChat *chat, GList *ignored) |
|
| 1252 { |
|
| 1253 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1254 |
|
| 1255 chat->ignored = ignored; |
|
| 1256 |
|
| 1257 return ignored; |
|
| 1258 } |
|
| 1259 |
|
| 1260 GList * |
|
| 1261 gaim_conv_chat_get_ignored(const GaimConvChat *chat) |
|
| 1262 { |
|
| 1263 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1264 |
|
| 1265 return chat->ignored; |
|
| 1266 } |
|
| 1267 |
|
| 1268 const char * |
|
| 1269 gaim_conv_chat_get_ignored_user(const GaimConvChat *chat, const char *user) |
|
| 1270 { |
|
| 1271 GList *ignored; |
|
| 1272 |
|
| 1273 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1274 g_return_val_if_fail(user != NULL, NULL); |
|
| 1275 |
|
| 1276 for (ignored = gaim_conv_chat_get_ignored(chat); |
|
| 1277 ignored != NULL; |
|
| 1278 ignored = ignored->next) { |
|
| 1279 |
|
| 1280 const char *ign = (const char *)ignored->data; |
|
| 1281 |
|
| 1282 if (!gaim_utf8_strcasecmp(user, ign) || |
|
| 1283 ((*ign == '+' || *ign == '%') && !gaim_utf8_strcasecmp(user, ign + 1))) |
|
| 1284 return ign; |
|
| 1285 |
|
| 1286 if (*ign == '@') { |
|
| 1287 ign++; |
|
| 1288 |
|
| 1289 if ((*ign == '+' && !gaim_utf8_strcasecmp(user, ign + 1)) || |
|
| 1290 (*ign != '+' && !gaim_utf8_strcasecmp(user, ign))) |
|
| 1291 return ign; |
|
| 1292 } |
|
| 1293 } |
|
| 1294 |
|
| 1295 return NULL; |
|
| 1296 } |
|
| 1297 |
|
| 1298 gboolean |
|
| 1299 gaim_conv_chat_is_user_ignored(const GaimConvChat *chat, const char *user) |
|
| 1300 { |
|
| 1301 g_return_val_if_fail(chat != NULL, FALSE); |
|
| 1302 g_return_val_if_fail(user != NULL, FALSE); |
|
| 1303 |
|
| 1304 return (gaim_conv_chat_get_ignored_user(chat, user) != NULL); |
|
| 1305 } |
|
| 1306 |
|
| 1307 void |
|
| 1308 gaim_conv_chat_set_topic(GaimConvChat *chat, const char *who, const char *topic) |
|
| 1309 { |
|
| 1310 g_return_if_fail(chat != NULL); |
|
| 1311 |
|
| 1312 g_free(chat->who); |
|
| 1313 g_free(chat->topic); |
|
| 1314 |
|
| 1315 chat->who = g_strdup(who); |
|
| 1316 chat->topic = g_strdup(topic); |
|
| 1317 |
|
| 1318 gaim_conversation_update(gaim_conv_chat_get_conversation(chat), |
|
| 1319 GAIM_CONV_UPDATE_TOPIC); |
|
| 1320 |
|
| 1321 gaim_signal_emit(gaim_conversations_get_handle(), "chat-topic-changed", |
|
| 1322 chat->conv, chat->who, chat->topic); |
|
| 1323 } |
|
| 1324 |
|
| 1325 const char * |
|
| 1326 gaim_conv_chat_get_topic(const GaimConvChat *chat) |
|
| 1327 { |
|
| 1328 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1329 |
|
| 1330 return chat->topic; |
|
| 1331 } |
|
| 1332 |
|
| 1333 void |
|
| 1334 gaim_conv_chat_set_id(GaimConvChat *chat, int id) |
|
| 1335 { |
|
| 1336 g_return_if_fail(chat != NULL); |
|
| 1337 |
|
| 1338 chat->id = id; |
|
| 1339 } |
|
| 1340 |
|
| 1341 int |
|
| 1342 gaim_conv_chat_get_id(const GaimConvChat *chat) |
|
| 1343 { |
|
| 1344 g_return_val_if_fail(chat != NULL, -1); |
|
| 1345 |
|
| 1346 return chat->id; |
|
| 1347 } |
|
| 1348 |
|
| 1349 void |
|
| 1350 gaim_conv_chat_write(GaimConvChat *chat, const char *who, const char *message, |
|
| 1351 GaimMessageFlags flags, time_t mtime) |
|
| 1352 { |
|
| 1353 GaimAccount *account; |
|
| 1354 GaimConversation *conv; |
|
| 1355 GaimConnection *gc; |
|
| 1356 GaimPluginProtocolInfo *prpl_info; |
|
| 1357 |
|
| 1358 g_return_if_fail(chat != NULL); |
|
| 1359 g_return_if_fail(who != NULL); |
|
| 1360 g_return_if_fail(message != NULL); |
|
| 1361 |
|
| 1362 conv = gaim_conv_chat_get_conversation(chat); |
|
| 1363 gc = gaim_conversation_get_gc(conv); |
|
| 1364 account = gaim_connection_get_account(gc); |
|
| 1365 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 1366 |
|
| 1367 /* Don't display this if the person who wrote it is ignored. */ |
|
| 1368 if (gaim_conv_chat_is_user_ignored(chat, who)) |
|
| 1369 return; |
|
| 1370 |
|
| 1371 if (!(flags & GAIM_MESSAGE_WHISPER)) { |
|
| 1372 char *str; |
|
| 1373 |
|
| 1374 str = g_strdup(gaim_normalize(account, who)); |
|
| 1375 |
|
| 1376 if (!strcmp(str, gaim_normalize(account, chat->nick))) { |
|
| 1377 flags |= GAIM_MESSAGE_SEND; |
|
| 1378 } else { |
|
| 1379 flags |= GAIM_MESSAGE_RECV; |
|
| 1380 |
|
| 1381 if (gaim_utf8_has_word(message, chat->nick)) |
|
| 1382 flags |= GAIM_MESSAGE_NICK; |
|
| 1383 } |
|
| 1384 |
|
| 1385 g_free(str); |
|
| 1386 } |
|
| 1387 |
|
| 1388 /* Pass this on to either the ops structure or the default write func. */ |
|
| 1389 if (conv->ui_ops != NULL && conv->ui_ops->write_chat != NULL) |
|
| 1390 conv->ui_ops->write_chat(conv, who, message, flags, mtime); |
|
| 1391 else |
|
| 1392 gaim_conversation_write(conv, who, message, flags, mtime); |
|
| 1393 } |
|
| 1394 |
|
| 1395 void |
|
| 1396 gaim_conv_chat_send(GaimConvChat *chat, const char *message) |
|
| 1397 { |
|
| 1398 gaim_conv_chat_send_with_flags(chat, message, 0); |
|
| 1399 } |
|
| 1400 |
|
| 1401 void |
|
| 1402 gaim_conv_chat_send_with_flags(GaimConvChat *chat, const char *message, GaimMessageFlags flags) |
|
| 1403 { |
|
| 1404 g_return_if_fail(chat != NULL); |
|
| 1405 g_return_if_fail(message != NULL); |
|
| 1406 |
|
| 1407 common_send(gaim_conv_chat_get_conversation(chat), message, flags); |
|
| 1408 } |
|
| 1409 |
|
| 1410 void |
|
| 1411 gaim_conv_chat_add_user(GaimConvChat *chat, const char *user, |
|
| 1412 const char *extra_msg, GaimConvChatBuddyFlags flags, |
|
| 1413 gboolean new_arrival) |
|
| 1414 { |
|
| 1415 GList *users = g_list_append(NULL, (char *)user); |
|
| 1416 GList *extra_msgs = g_list_append(NULL, (char *)extra_msg); |
|
| 1417 GList *flags2 = g_list_append(NULL, GINT_TO_POINTER(flags)); |
|
| 1418 |
|
| 1419 gaim_conv_chat_add_users(chat, users, extra_msgs, flags2, new_arrival); |
|
| 1420 |
|
| 1421 g_list_free(users); |
|
| 1422 g_list_free(extra_msgs); |
|
| 1423 g_list_free(flags2); |
|
| 1424 } |
|
| 1425 |
|
| 1426 static int |
|
| 1427 gaim_conv_chat_cb_compare(GaimConvChatBuddy *a, GaimConvChatBuddy *b) |
|
| 1428 { |
|
| 1429 GaimConvChatBuddyFlags f1 = 0, f2 = 0; |
|
| 1430 char *user1 = NULL, *user2 = NULL; |
|
| 1431 gint ret = 0; |
|
| 1432 |
|
| 1433 if (a) { |
|
| 1434 f1 = a->flags; |
|
| 1435 if (a->alias_key) |
|
| 1436 user1 = a->alias_key; |
|
| 1437 else if (a->name) |
|
| 1438 user1 = a->name; |
|
| 1439 } |
|
| 1440 |
|
| 1441 if (b) { |
|
| 1442 f2 = b->flags; |
|
| 1443 if (b->alias_key) |
|
| 1444 user2 = b->alias_key; |
|
| 1445 else if (b->name) |
|
| 1446 user2 = b->name; |
|
| 1447 } |
|
| 1448 |
|
| 1449 if (user1 == NULL || user2 == NULL) { |
|
| 1450 if (!(user1 == NULL && user2 == NULL)) |
|
| 1451 ret = (user1 == NULL) ? -1: 1; |
|
| 1452 } else if (f1 != f2) { |
|
| 1453 /* sort more important users first */ |
|
| 1454 ret = (f1 > f2) ? -1 : 1; |
|
| 1455 } else if (a->buddy != b->buddy) { |
|
| 1456 ret = a->buddy ? -1 : 1; |
|
| 1457 } else { |
|
| 1458 ret = strcasecmp(user1, user2); |
|
| 1459 } |
|
| 1460 |
|
| 1461 return ret; |
|
| 1462 } |
|
| 1463 |
|
| 1464 void |
|
| 1465 gaim_conv_chat_add_users(GaimConvChat *chat, GList *users, GList *extra_msgs, |
|
| 1466 GList *flags, gboolean new_arrivals) |
|
| 1467 { |
|
| 1468 GaimConversation *conv; |
|
| 1469 GaimConversationUiOps *ops; |
|
| 1470 GaimConvChatBuddy *cbuddy; |
|
| 1471 GaimConnection *gc; |
|
| 1472 GaimPluginProtocolInfo *prpl_info; |
|
| 1473 GList *ul, *fl; |
|
| 1474 GList *cbuddies = NULL; |
|
| 1475 |
|
| 1476 g_return_if_fail(chat != NULL); |
|
| 1477 g_return_if_fail(users != NULL); |
|
| 1478 |
|
| 1479 conv = gaim_conv_chat_get_conversation(chat); |
|
| 1480 ops = gaim_conversation_get_ui_ops(conv); |
|
| 1481 |
|
| 1482 gc = gaim_conversation_get_gc(conv); |
|
| 1483 g_return_if_fail(gc != NULL); |
|
| 1484 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 1485 g_return_if_fail(prpl_info != NULL); |
|
| 1486 |
|
| 1487 ul = users; |
|
| 1488 fl = flags; |
|
| 1489 while ((ul != NULL) && (fl != NULL)) { |
|
| 1490 const char *user = (const char *)ul->data; |
|
| 1491 const char *alias = user; |
|
| 1492 gboolean quiet; |
|
| 1493 GaimConvChatBuddyFlags flag = GPOINTER_TO_INT(fl->data); |
|
| 1494 const char *extra_msg = (extra_msgs ? extra_msgs->data : NULL); |
|
| 1495 |
|
| 1496 if (!strcmp(chat->nick, gaim_normalize(conv->account, user))) { |
|
| 1497 const char *alias2 = gaim_account_get_alias(conv->account); |
|
| 1498 if (alias2 != NULL) |
|
| 1499 alias = alias2; |
|
| 1500 else |
|
| 1501 { |
|
| 1502 const char *display_name = gaim_connection_get_display_name(gc); |
|
| 1503 if (display_name != NULL) |
|
| 1504 alias = display_name; |
|
| 1505 } |
|
| 1506 } else if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
|
| 1507 GaimBuddy *buddy; |
|
| 1508 if ((buddy = gaim_find_buddy(gc->account, user)) != NULL) |
|
| 1509 alias = gaim_buddy_get_contact_alias(buddy); |
|
| 1510 } |
|
| 1511 |
|
| 1512 quiet = GPOINTER_TO_INT(gaim_signal_emit_return_1(gaim_conversations_get_handle(), |
|
| 1513 "chat-buddy-joining", conv, user, flag)) | |
|
| 1514 gaim_conv_chat_is_user_ignored(chat, user); |
|
| 1515 |
|
| 1516 cbuddy = gaim_conv_chat_cb_new(user, alias, flag); |
|
| 1517 /* This seems dumb. Why should we set users thousands of times? */ |
|
| 1518 gaim_conv_chat_set_users(chat, |
|
| 1519 g_list_prepend(gaim_conv_chat_get_users(chat), cbuddy)); |
|
| 1520 |
|
| 1521 cbuddies = g_list_prepend(cbuddies, cbuddy); |
|
| 1522 |
|
| 1523 if (!quiet && new_arrivals) { |
|
| 1524 char *escaped = g_markup_escape_text(alias, -1); |
|
| 1525 char *tmp; |
|
| 1526 |
|
| 1527 if (extra_msg == NULL) |
|
| 1528 tmp = g_strdup_printf(_("%s entered the room."), escaped); |
|
| 1529 else { |
|
| 1530 char *escaped2 = g_markup_escape_text(extra_msg, -1); |
|
| 1531 tmp = g_strdup_printf(_("%s [<I>%s</I>] entered the room."), |
|
| 1532 escaped, escaped2); |
|
| 1533 g_free(escaped2); |
|
| 1534 } |
|
| 1535 g_free(escaped); |
|
| 1536 |
|
| 1537 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); |
|
| 1538 g_free(tmp); |
|
| 1539 } |
|
| 1540 |
|
| 1541 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 1542 "chat-buddy-joined", conv, user, flag, new_arrivals); |
|
| 1543 ul = ul->next; |
|
| 1544 fl = fl->next; |
|
| 1545 if (extra_msgs != NULL) |
|
| 1546 extra_msgs = extra_msgs->next; |
|
| 1547 } |
|
| 1548 |
|
| 1549 cbuddies = g_list_sort(cbuddies, (GCompareFunc)gaim_conv_chat_cb_compare); |
|
| 1550 |
|
| 1551 if (ops != NULL && ops->chat_add_users != NULL) |
|
| 1552 ops->chat_add_users(conv, cbuddies, new_arrivals); |
|
| 1553 |
|
| 1554 g_list_free(cbuddies); |
|
| 1555 } |
|
| 1556 |
|
| 1557 void |
|
| 1558 gaim_conv_chat_rename_user(GaimConvChat *chat, const char *old_user, |
|
| 1559 const char *new_user) |
|
| 1560 { |
|
| 1561 GaimConversation *conv; |
|
| 1562 GaimConversationUiOps *ops; |
|
| 1563 GaimConnection *gc; |
|
| 1564 GaimPluginProtocolInfo *prpl_info; |
|
| 1565 GaimConvChatBuddy *cb; |
|
| 1566 GaimConvChatBuddyFlags flags; |
|
| 1567 const char *new_alias = new_user; |
|
| 1568 char tmp[BUF_LONG]; |
|
| 1569 gboolean is_me = FALSE; |
|
| 1570 |
|
| 1571 g_return_if_fail(chat != NULL); |
|
| 1572 g_return_if_fail(old_user != NULL); |
|
| 1573 g_return_if_fail(new_user != NULL); |
|
| 1574 |
|
| 1575 conv = gaim_conv_chat_get_conversation(chat); |
|
| 1576 ops = gaim_conversation_get_ui_ops(conv); |
|
| 1577 |
|
| 1578 gc = gaim_conversation_get_gc(conv); |
|
| 1579 g_return_if_fail(gc != NULL); |
|
| 1580 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 1581 g_return_if_fail(prpl_info != NULL); |
|
| 1582 |
|
| 1583 flags = gaim_conv_chat_user_get_flags(chat, old_user); |
|
| 1584 cb = gaim_conv_chat_cb_new(new_user, NULL, flags); |
|
| 1585 gaim_conv_chat_set_users(chat, |
|
| 1586 g_list_prepend(gaim_conv_chat_get_users(chat), cb)); |
|
| 1587 |
|
| 1588 if (!strcmp(chat->nick, gaim_normalize(conv->account, old_user))) { |
|
| 1589 const char *alias; |
|
| 1590 |
|
| 1591 /* Note this for later. */ |
|
| 1592 is_me = TRUE; |
|
| 1593 |
|
| 1594 alias = gaim_account_get_alias(conv->account); |
|
| 1595 if (alias != NULL) |
|
| 1596 new_alias = alias; |
|
| 1597 else |
|
| 1598 { |
|
| 1599 const char *display_name = gaim_connection_get_display_name(gc); |
|
| 1600 if (display_name != NULL) |
|
| 1601 alias = display_name; |
|
| 1602 } |
|
| 1603 } else if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
|
| 1604 GaimBuddy *buddy; |
|
| 1605 if ((buddy = gaim_find_buddy(gc->account, new_user)) != NULL) |
|
| 1606 new_alias = gaim_buddy_get_contact_alias(buddy); |
|
| 1607 } |
|
| 1608 |
|
| 1609 if (ops != NULL && ops->chat_rename_user != NULL) |
|
| 1610 ops->chat_rename_user(conv, old_user, new_user, new_alias); |
|
| 1611 |
|
| 1612 cb = gaim_conv_chat_cb_find(chat, old_user); |
|
| 1613 |
|
| 1614 if (cb) { |
|
| 1615 gaim_conv_chat_set_users(chat, |
|
| 1616 g_list_remove(gaim_conv_chat_get_users(chat), cb)); |
|
| 1617 gaim_conv_chat_cb_destroy(cb); |
|
| 1618 } |
|
| 1619 |
|
| 1620 if (gaim_conv_chat_is_user_ignored(chat, old_user)) { |
|
| 1621 gaim_conv_chat_unignore(chat, old_user); |
|
| 1622 gaim_conv_chat_ignore(chat, new_user); |
|
| 1623 } |
|
| 1624 else if (gaim_conv_chat_is_user_ignored(chat, new_user)) |
|
| 1625 gaim_conv_chat_unignore(chat, new_user); |
|
| 1626 |
|
| 1627 if (is_me) |
|
| 1628 gaim_conv_chat_set_nick(chat, new_user); |
|
| 1629 |
|
| 1630 if (gaim_prefs_get_bool("/core/conversations/chat/show_nick_change") && |
|
| 1631 !gaim_conv_chat_is_user_ignored(chat, new_user)) { |
|
| 1632 |
|
| 1633 if (is_me) { |
|
| 1634 char *escaped = g_markup_escape_text(new_user, -1); |
|
| 1635 g_snprintf(tmp, sizeof(tmp), |
|
| 1636 _("You are now known as %s"), escaped); |
|
| 1637 g_free(escaped); |
|
| 1638 } else { |
|
| 1639 const char *old_alias = old_user; |
|
| 1640 const char *new_alias = new_user; |
|
| 1641 char *escaped; |
|
| 1642 char *escaped2; |
|
| 1643 |
|
| 1644 if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
|
| 1645 GaimBuddy *buddy; |
|
| 1646 |
|
| 1647 if ((buddy = gaim_find_buddy(gc->account, old_user)) != NULL) |
|
| 1648 old_alias = gaim_buddy_get_contact_alias(buddy); |
|
| 1649 if ((buddy = gaim_find_buddy(gc->account, new_user)) != NULL) |
|
| 1650 new_alias = gaim_buddy_get_contact_alias(buddy); |
|
| 1651 } |
|
| 1652 |
|
| 1653 escaped = g_markup_escape_text(old_alias, -1); |
|
| 1654 escaped2 = g_markup_escape_text(new_alias, -1); |
|
| 1655 g_snprintf(tmp, sizeof(tmp), |
|
| 1656 _("%s is now known as %s"), escaped, escaped2); |
|
| 1657 g_free(escaped); |
|
| 1658 g_free(escaped2); |
|
| 1659 } |
|
| 1660 |
|
| 1661 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); |
|
| 1662 } |
|
| 1663 } |
|
| 1664 |
|
| 1665 void |
|
| 1666 gaim_conv_chat_remove_user(GaimConvChat *chat, const char *user, const char *reason) |
|
| 1667 { |
|
| 1668 GList *users = g_list_append(NULL, (char *)user); |
|
| 1669 |
|
| 1670 gaim_conv_chat_remove_users(chat, users, reason); |
|
| 1671 |
|
| 1672 g_list_free(users); |
|
| 1673 } |
|
| 1674 |
|
| 1675 void |
|
| 1676 gaim_conv_chat_remove_users(GaimConvChat *chat, GList *users, const char *reason) |
|
| 1677 { |
|
| 1678 GaimConversation *conv; |
|
| 1679 GaimConnection *gc; |
|
| 1680 GaimPluginProtocolInfo *prpl_info; |
|
| 1681 GaimConversationUiOps *ops; |
|
| 1682 GaimConvChatBuddy *cb; |
|
| 1683 GList *l; |
|
| 1684 gboolean quiet; |
|
| 1685 |
|
| 1686 g_return_if_fail(chat != NULL); |
|
| 1687 g_return_if_fail(users != NULL); |
|
| 1688 |
|
| 1689 conv = gaim_conv_chat_get_conversation(chat); |
|
| 1690 |
|
| 1691 gc = gaim_conversation_get_gc(conv); |
|
| 1692 g_return_if_fail(gc != NULL); |
|
| 1693 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 1694 g_return_if_fail(prpl_info != NULL); |
|
| 1695 |
|
| 1696 ops = gaim_conversation_get_ui_ops(conv); |
|
| 1697 |
|
| 1698 for (l = users; l != NULL; l = l->next) { |
|
| 1699 const char *user = (const char *)l->data; |
|
| 1700 quiet = GPOINTER_TO_INT(gaim_signal_emit_return_1(gaim_conversations_get_handle(), |
|
| 1701 "chat-buddy-leaving", conv, user, reason)) | |
|
| 1702 gaim_conv_chat_is_user_ignored(chat, user); |
|
| 1703 |
|
| 1704 cb = gaim_conv_chat_cb_find(chat, user); |
|
| 1705 |
|
| 1706 if (cb) { |
|
| 1707 gaim_conv_chat_set_users(chat, |
|
| 1708 g_list_remove(gaim_conv_chat_get_users(chat), cb)); |
|
| 1709 gaim_conv_chat_cb_destroy(cb); |
|
| 1710 } |
|
| 1711 |
|
| 1712 /* NOTE: Don't remove them from ignored in case they re-enter. */ |
|
| 1713 |
|
| 1714 if (!quiet) { |
|
| 1715 const char *alias = user; |
|
| 1716 char *escaped; |
|
| 1717 char *tmp; |
|
| 1718 |
|
| 1719 if (!(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
|
| 1720 GaimBuddy *buddy; |
|
| 1721 |
|
| 1722 if ((buddy = gaim_find_buddy(gc->account, user)) != NULL) |
|
| 1723 alias = gaim_buddy_get_contact_alias(buddy); |
|
| 1724 } |
|
| 1725 |
|
| 1726 escaped = g_markup_escape_text(alias, -1); |
|
| 1727 |
|
| 1728 if (reason == NULL || !*reason) |
|
| 1729 tmp = g_strdup_printf(_("%s left the room."), escaped); |
|
| 1730 else { |
|
| 1731 char *escaped2 = g_markup_escape_text(reason, -1); |
|
| 1732 tmp = g_strdup_printf(_("%s left the room (%s)."), |
|
| 1733 escaped, escaped2); |
|
| 1734 g_free(escaped2); |
|
| 1735 } |
|
| 1736 g_free(escaped); |
|
| 1737 |
|
| 1738 gaim_conversation_write(conv, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); |
|
| 1739 g_free(tmp); |
|
| 1740 } |
|
| 1741 |
|
| 1742 gaim_signal_emit(gaim_conversations_get_handle(), "chat-buddy-left", |
|
| 1743 conv, user, reason); |
|
| 1744 } |
|
| 1745 |
|
| 1746 if (ops != NULL && ops->chat_remove_users != NULL) |
|
| 1747 ops->chat_remove_users(conv, users); |
|
| 1748 } |
|
| 1749 |
|
| 1750 void |
|
| 1751 gaim_conv_chat_clear_users(GaimConvChat *chat) |
|
| 1752 { |
|
| 1753 GaimConversation *conv; |
|
| 1754 GaimConversationUiOps *ops; |
|
| 1755 GList *users, *names = NULL; |
|
| 1756 GList *l; |
|
| 1757 |
|
| 1758 g_return_if_fail(chat != NULL); |
|
| 1759 |
|
| 1760 conv = gaim_conv_chat_get_conversation(chat); |
|
| 1761 ops = gaim_conversation_get_ui_ops(conv); |
|
| 1762 users = gaim_conv_chat_get_users(chat); |
|
| 1763 |
|
| 1764 if (ops != NULL && ops->chat_remove_users != NULL) { |
|
| 1765 for (l = users; l; l = l->next) { |
|
| 1766 GaimConvChatBuddy *cb = l->data; |
|
| 1767 names = g_list_append(names, cb->name); |
|
| 1768 } |
|
| 1769 ops->chat_remove_users(conv, names); |
|
| 1770 g_list_free(names); |
|
| 1771 } |
|
| 1772 |
|
| 1773 for (l = users; l; l = l->next) |
|
| 1774 { |
|
| 1775 GaimConvChatBuddy *cb = l->data; |
|
| 1776 |
|
| 1777 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 1778 "chat-buddy-leaving", conv, cb->name, NULL); |
|
| 1779 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 1780 "chat-buddy-left", conv, cb->name, NULL); |
|
| 1781 |
|
| 1782 gaim_conv_chat_cb_destroy(cb); |
|
| 1783 } |
|
| 1784 |
|
| 1785 g_list_free(users); |
|
| 1786 gaim_conv_chat_set_users(chat, NULL); |
|
| 1787 } |
|
| 1788 |
|
| 1789 |
|
| 1790 gboolean |
|
| 1791 gaim_conv_chat_find_user(GaimConvChat *chat, const char *user) |
|
| 1792 { |
|
| 1793 g_return_val_if_fail(chat != NULL, FALSE); |
|
| 1794 g_return_val_if_fail(user != NULL, FALSE); |
|
| 1795 |
|
| 1796 return (gaim_conv_chat_cb_find(chat, user) != NULL); |
|
| 1797 } |
|
| 1798 |
|
| 1799 void |
|
| 1800 gaim_conv_chat_user_set_flags(GaimConvChat *chat, const char *user, |
|
| 1801 GaimConvChatBuddyFlags flags) |
|
| 1802 { |
|
| 1803 GaimConversation *conv; |
|
| 1804 GaimConversationUiOps *ops; |
|
| 1805 GaimConvChatBuddy *cb; |
|
| 1806 GaimConvChatBuddyFlags oldflags; |
|
| 1807 |
|
| 1808 g_return_if_fail(chat != NULL); |
|
| 1809 g_return_if_fail(user != NULL); |
|
| 1810 |
|
| 1811 cb = gaim_conv_chat_cb_find(chat, user); |
|
| 1812 |
|
| 1813 if (!cb) |
|
| 1814 return; |
|
| 1815 |
|
| 1816 if (flags == cb->flags) |
|
| 1817 return; |
|
| 1818 |
|
| 1819 oldflags = cb->flags; |
|
| 1820 cb->flags = flags; |
|
| 1821 |
|
| 1822 conv = gaim_conv_chat_get_conversation(chat); |
|
| 1823 ops = gaim_conversation_get_ui_ops(conv); |
|
| 1824 |
|
| 1825 if (ops != NULL && ops->chat_update_user != NULL) |
|
| 1826 ops->chat_update_user(conv, user); |
|
| 1827 |
|
| 1828 gaim_signal_emit(gaim_conversations_get_handle(), |
|
| 1829 "chat-buddy-flags", conv, user, oldflags, flags); |
|
| 1830 } |
|
| 1831 |
|
| 1832 GaimConvChatBuddyFlags |
|
| 1833 gaim_conv_chat_user_get_flags(GaimConvChat *chat, const char *user) |
|
| 1834 { |
|
| 1835 GaimConvChatBuddy *cb; |
|
| 1836 |
|
| 1837 g_return_val_if_fail(chat != NULL, 0); |
|
| 1838 g_return_val_if_fail(user != NULL, 0); |
|
| 1839 |
|
| 1840 cb = gaim_conv_chat_cb_find(chat, user); |
|
| 1841 |
|
| 1842 if (!cb) |
|
| 1843 return GAIM_CBFLAGS_NONE; |
|
| 1844 |
|
| 1845 return cb->flags; |
|
| 1846 } |
|
| 1847 |
|
| 1848 void gaim_conv_chat_set_nick(GaimConvChat *chat, const char *nick) { |
|
| 1849 g_return_if_fail(chat != NULL); |
|
| 1850 |
|
| 1851 g_free(chat->nick); |
|
| 1852 chat->nick = g_strdup(gaim_normalize(chat->conv->account, nick)); |
|
| 1853 } |
|
| 1854 |
|
| 1855 const char *gaim_conv_chat_get_nick(GaimConvChat *chat) { |
|
| 1856 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1857 |
|
| 1858 return chat->nick; |
|
| 1859 } |
|
| 1860 |
|
| 1861 GaimConversation * |
|
| 1862 gaim_find_chat(const GaimConnection *gc, int id) |
|
| 1863 { |
|
| 1864 GList *l; |
|
| 1865 GaimConversation *conv; |
|
| 1866 |
|
| 1867 for (l = gaim_get_chats(); l != NULL; l = l->next) { |
|
| 1868 conv = (GaimConversation *)l->data; |
|
| 1869 |
|
| 1870 if (gaim_conv_chat_get_id(GAIM_CONV_CHAT(conv)) == id && |
|
| 1871 gaim_conversation_get_gc(conv) == gc) |
|
| 1872 return conv; |
|
| 1873 } |
|
| 1874 |
|
| 1875 return NULL; |
|
| 1876 } |
|
| 1877 |
|
| 1878 void |
|
| 1879 gaim_conv_chat_left(GaimConvChat *chat) |
|
| 1880 { |
|
| 1881 g_return_if_fail(chat != NULL); |
|
| 1882 |
|
| 1883 chat->left = TRUE; |
|
| 1884 gaim_conversation_update(chat->conv, GAIM_CONV_UPDATE_CHATLEFT); |
|
| 1885 } |
|
| 1886 |
|
| 1887 gboolean |
|
| 1888 gaim_conv_chat_has_left(GaimConvChat *chat) |
|
| 1889 { |
|
| 1890 g_return_val_if_fail(chat != NULL, TRUE); |
|
| 1891 |
|
| 1892 return chat->left; |
|
| 1893 } |
|
| 1894 GaimConvChatBuddy * |
|
| 1895 gaim_conv_chat_cb_new(const char *name, const char *alias, GaimConvChatBuddyFlags flags) |
|
| 1896 { |
|
| 1897 GaimConvChatBuddy *cb; |
|
| 1898 |
|
| 1899 g_return_val_if_fail(name != NULL, NULL); |
|
| 1900 |
|
| 1901 cb = g_new0(GaimConvChatBuddy, 1); |
|
| 1902 cb->name = g_strdup(name); |
|
| 1903 cb->flags = flags; |
|
| 1904 cb->alias = g_strdup(alias); |
|
| 1905 |
|
| 1906 GAIM_DBUS_REGISTER_POINTER(cb, GaimConvChatBuddy); |
|
| 1907 return cb; |
|
| 1908 } |
|
| 1909 |
|
| 1910 GaimConvChatBuddy * |
|
| 1911 gaim_conv_chat_cb_find(GaimConvChat *chat, const char *name) |
|
| 1912 { |
|
| 1913 GList *l; |
|
| 1914 GaimConvChatBuddy *cb = NULL; |
|
| 1915 |
|
| 1916 g_return_val_if_fail(chat != NULL, NULL); |
|
| 1917 g_return_val_if_fail(name != NULL, NULL); |
|
| 1918 |
|
| 1919 for (l = gaim_conv_chat_get_users(chat); l; l = l->next) { |
|
| 1920 cb = l->data; |
|
| 1921 if (!gaim_utf8_strcasecmp(cb->name, name)) |
|
| 1922 return cb; |
|
| 1923 } |
|
| 1924 |
|
| 1925 return NULL; |
|
| 1926 } |
|
| 1927 |
|
| 1928 void |
|
| 1929 gaim_conv_chat_cb_destroy(GaimConvChatBuddy *cb) |
|
| 1930 { |
|
| 1931 if (cb == NULL) |
|
| 1932 return; |
|
| 1933 |
|
| 1934 g_free(cb->alias); |
|
| 1935 g_free(cb->alias_key); |
|
| 1936 g_free(cb->name); |
|
| 1937 |
|
| 1938 GAIM_DBUS_UNREGISTER_POINTER(cb); |
|
| 1939 g_free(cb); |
|
| 1940 } |
|
| 1941 |
|
| 1942 const char * |
|
| 1943 gaim_conv_chat_cb_get_name(GaimConvChatBuddy *cb) |
|
| 1944 { |
|
| 1945 g_return_val_if_fail(cb != NULL, NULL); |
|
| 1946 |
|
| 1947 return cb->name; |
|
| 1948 } |
|
| 1949 |
|
| 1950 void * |
|
| 1951 gaim_conversations_get_handle(void) |
|
| 1952 { |
|
| 1953 static int handle; |
|
| 1954 |
|
| 1955 return &handle; |
|
| 1956 } |
|
| 1957 |
|
| 1958 void |
|
| 1959 gaim_conversations_init(void) |
|
| 1960 { |
|
| 1961 void *handle = gaim_conversations_get_handle(); |
|
| 1962 |
|
| 1963 /********************************************************************** |
|
| 1964 * Register preferences |
|
| 1965 **********************************************************************/ |
|
| 1966 |
|
| 1967 /* Conversations */ |
|
| 1968 gaim_prefs_add_none("/core/conversations"); |
|
| 1969 |
|
| 1970 /* Conversations -> Chat */ |
|
| 1971 gaim_prefs_add_none("/core/conversations/chat"); |
|
| 1972 gaim_prefs_add_bool("/core/conversations/chat/show_nick_change", TRUE); |
|
| 1973 |
|
| 1974 /* Conversations -> IM */ |
|
| 1975 gaim_prefs_add_none("/core/conversations/im"); |
|
| 1976 gaim_prefs_add_bool("/core/conversations/im/send_typing", TRUE); |
|
| 1977 |
|
| 1978 |
|
| 1979 /********************************************************************** |
|
| 1980 * Register signals |
|
| 1981 **********************************************************************/ |
|
| 1982 gaim_signal_register(handle, "writing-im-msg", |
|
| 1983 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER, |
|
| 1984 gaim_value_new(GAIM_TYPE_BOOLEAN), 5, |
|
| 1985 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 1986 GAIM_SUBTYPE_ACCOUNT), |
|
| 1987 gaim_value_new(GAIM_TYPE_STRING), |
|
| 1988 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 1989 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 1990 GAIM_SUBTYPE_CONVERSATION), |
|
| 1991 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 1992 |
|
| 1993 gaim_signal_register(handle, "wrote-im-msg", |
|
| 1994 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT, |
|
| 1995 NULL, 5, |
|
| 1996 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 1997 GAIM_SUBTYPE_ACCOUNT), |
|
| 1998 gaim_value_new(GAIM_TYPE_STRING), |
|
| 1999 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2000 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2001 GAIM_SUBTYPE_CONVERSATION), |
|
| 2002 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2003 |
|
| 2004 gaim_signal_register(handle, "sending-im-msg", |
|
| 2005 gaim_marshal_VOID__POINTER_POINTER_POINTER, |
|
| 2006 NULL, 3, |
|
| 2007 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2008 GAIM_SUBTYPE_ACCOUNT), |
|
| 2009 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2010 gaim_value_new_outgoing(GAIM_TYPE_STRING)); |
|
| 2011 |
|
| 2012 gaim_signal_register(handle, "sent-im-msg", |
|
| 2013 gaim_marshal_VOID__POINTER_POINTER_POINTER, |
|
| 2014 NULL, 3, |
|
| 2015 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2016 GAIM_SUBTYPE_ACCOUNT), |
|
| 2017 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2018 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2019 |
|
| 2020 gaim_signal_register(handle, "receiving-im-msg", |
|
| 2021 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER, |
|
| 2022 gaim_value_new(GAIM_TYPE_BOOLEAN), 5, |
|
| 2023 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2024 GAIM_SUBTYPE_ACCOUNT), |
|
| 2025 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 2026 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 2027 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2028 GAIM_SUBTYPE_CONVERSATION), |
|
| 2029 gaim_value_new_outgoing(GAIM_TYPE_UINT)); |
|
| 2030 |
|
| 2031 gaim_signal_register(handle, "received-im-msg", |
|
| 2032 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT, |
|
| 2033 NULL, 5, |
|
| 2034 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2035 GAIM_SUBTYPE_ACCOUNT), |
|
| 2036 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2037 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2038 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2039 GAIM_SUBTYPE_CONVERSATION), |
|
| 2040 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2041 |
|
| 2042 gaim_signal_register(handle, "writing-chat-msg", |
|
| 2043 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER, |
|
| 2044 gaim_value_new(GAIM_TYPE_BOOLEAN), 5, |
|
| 2045 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2046 GAIM_SUBTYPE_ACCOUNT), |
|
| 2047 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2048 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 2049 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2050 GAIM_SUBTYPE_CONVERSATION), |
|
| 2051 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2052 |
|
| 2053 gaim_signal_register(handle, "wrote-chat-msg", |
|
| 2054 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT, |
|
| 2055 NULL, 5, |
|
| 2056 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2057 GAIM_SUBTYPE_ACCOUNT), |
|
| 2058 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2059 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2060 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2061 GAIM_SUBTYPE_CONVERSATION), |
|
| 2062 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2063 |
|
| 2064 gaim_signal_register(handle, "sending-chat-msg", |
|
| 2065 gaim_marshal_VOID__POINTER_POINTER_UINT, NULL, 3, |
|
| 2066 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2067 GAIM_SUBTYPE_ACCOUNT), |
|
| 2068 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 2069 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2070 |
|
| 2071 gaim_signal_register(handle, "sent-chat-msg", |
|
| 2072 gaim_marshal_VOID__POINTER_POINTER_UINT, NULL, 3, |
|
| 2073 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2074 GAIM_SUBTYPE_ACCOUNT), |
|
| 2075 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2076 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2077 |
|
| 2078 gaim_signal_register(handle, "receiving-chat-msg", |
|
| 2079 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER_POINTER_POINTER, |
|
| 2080 gaim_value_new(GAIM_TYPE_BOOLEAN), 5, |
|
| 2081 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2082 GAIM_SUBTYPE_ACCOUNT), |
|
| 2083 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 2084 gaim_value_new_outgoing(GAIM_TYPE_STRING), |
|
| 2085 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2086 GAIM_SUBTYPE_CONVERSATION), |
|
| 2087 gaim_value_new_outgoing(GAIM_TYPE_UINT)); |
|
| 2088 |
|
| 2089 gaim_signal_register(handle, "received-chat-msg", |
|
| 2090 gaim_marshal_VOID__POINTER_POINTER_POINTER_POINTER_UINT, |
|
| 2091 NULL, 5, |
|
| 2092 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2093 GAIM_SUBTYPE_ACCOUNT), |
|
| 2094 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2095 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2096 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2097 GAIM_SUBTYPE_CONVERSATION), |
|
| 2098 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2099 |
|
| 2100 gaim_signal_register(handle, "conversation-created", |
|
| 2101 gaim_marshal_VOID__POINTER, NULL, 1, |
|
| 2102 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2103 GAIM_SUBTYPE_CONVERSATION)); |
|
| 2104 |
|
| 2105 gaim_signal_register(handle, "conversation-updated", |
|
| 2106 gaim_marshal_VOID__POINTER_UINT, NULL, 2, |
|
| 2107 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2108 GAIM_SUBTYPE_CONVERSATION), |
|
| 2109 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2110 |
|
| 2111 gaim_signal_register(handle, "deleting-conversation", |
|
| 2112 gaim_marshal_VOID__POINTER, NULL, 1, |
|
| 2113 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2114 GAIM_SUBTYPE_CONVERSATION)); |
|
| 2115 |
|
| 2116 gaim_signal_register(handle, "buddy-typing", |
|
| 2117 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, |
|
| 2118 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2119 GAIM_SUBTYPE_ACCOUNT), |
|
| 2120 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2121 |
|
| 2122 gaim_signal_register(handle, "buddy-typed", |
|
| 2123 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, |
|
| 2124 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2125 GAIM_SUBTYPE_ACCOUNT), |
|
| 2126 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2127 |
|
| 2128 gaim_signal_register(handle, "buddy-typing-stopped", |
|
| 2129 gaim_marshal_VOID__POINTER_POINTER, NULL, 2, |
|
| 2130 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2131 GAIM_SUBTYPE_ACCOUNT), |
|
| 2132 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2133 |
|
| 2134 gaim_signal_register(handle, "chat-buddy-joining", |
|
| 2135 gaim_marshal_BOOLEAN__POINTER_POINTER_UINT, |
|
| 2136 gaim_value_new(GAIM_TYPE_BOOLEAN), 3, |
|
| 2137 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2138 GAIM_SUBTYPE_CONVERSATION), |
|
| 2139 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2140 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2141 |
|
| 2142 gaim_signal_register(handle, "chat-buddy-joined", |
|
| 2143 gaim_marshal_VOID__POINTER_POINTER_UINT_UINT, NULL, 4, |
|
| 2144 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2145 GAIM_SUBTYPE_CONVERSATION), |
|
| 2146 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2147 gaim_value_new(GAIM_TYPE_UINT), |
|
| 2148 gaim_value_new(GAIM_TYPE_BOOLEAN)); |
|
| 2149 |
|
| 2150 gaim_signal_register(handle, "chat-buddy-flags", |
|
| 2151 gaim_marshal_VOID__POINTER_POINTER_UINT_UINT, NULL, 4, |
|
| 2152 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2153 GAIM_SUBTYPE_CONVERSATION), |
|
| 2154 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2155 gaim_value_new(GAIM_TYPE_UINT), |
|
| 2156 gaim_value_new(GAIM_TYPE_UINT)); |
|
| 2157 |
|
| 2158 gaim_signal_register(handle, "chat-buddy-leaving", |
|
| 2159 gaim_marshal_BOOLEAN__POINTER_POINTER_POINTER, |
|
| 2160 gaim_value_new(GAIM_TYPE_BOOLEAN), 3, |
|
| 2161 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2162 GAIM_SUBTYPE_CONVERSATION), |
|
| 2163 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2164 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2165 |
|
| 2166 gaim_signal_register(handle, "chat-buddy-left", |
|
| 2167 gaim_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3, |
|
| 2168 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2169 GAIM_SUBTYPE_CONVERSATION), |
|
| 2170 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2171 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2172 |
|
| 2173 gaim_signal_register(handle, "chat-inviting-user", |
|
| 2174 gaim_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3, |
|
| 2175 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2176 GAIM_SUBTYPE_CONVERSATION), |
|
| 2177 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2178 gaim_value_new_outgoing(GAIM_TYPE_STRING)); |
|
| 2179 |
|
| 2180 gaim_signal_register(handle, "chat-invited-user", |
|
| 2181 gaim_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3, |
|
| 2182 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2183 GAIM_SUBTYPE_CONVERSATION), |
|
| 2184 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2185 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2186 |
|
| 2187 gaim_signal_register(handle, "chat-invited", |
|
| 2188 gaim_marshal_INT__POINTER_POINTER_POINTER_POINTER_POINTER, |
|
| 2189 NULL, 5, |
|
| 2190 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2191 GAIM_SUBTYPE_ACCOUNT), |
|
| 2192 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2193 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2194 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2195 gaim_value_new(GAIM_TYPE_POINTER)); |
|
| 2196 |
|
| 2197 gaim_signal_register(handle, "chat-joined", |
|
| 2198 gaim_marshal_VOID__POINTER, NULL, 1, |
|
| 2199 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2200 GAIM_SUBTYPE_CONVERSATION)); |
|
| 2201 |
|
| 2202 gaim_signal_register(handle, "chat-left", |
|
| 2203 gaim_marshal_VOID__POINTER, NULL, 1, |
|
| 2204 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2205 GAIM_SUBTYPE_CONVERSATION)); |
|
| 2206 |
|
| 2207 gaim_signal_register(handle, "chat-topic-changed", |
|
| 2208 gaim_marshal_VOID__POINTER_POINTER_POINTER, NULL, 3, |
|
| 2209 gaim_value_new(GAIM_TYPE_SUBTYPE, |
|
| 2210 GAIM_SUBTYPE_CONVERSATION), |
|
| 2211 gaim_value_new(GAIM_TYPE_STRING), |
|
| 2212 gaim_value_new(GAIM_TYPE_STRING)); |
|
| 2213 } |
|
| 2214 |
|
| 2215 void |
|
| 2216 gaim_conversations_uninit(void) |
|
| 2217 { |
|
| 2218 while (conversations) |
|
| 2219 gaim_conversation_destroy((GaimConversation*)conversations->data); |
|
| 2220 gaim_signals_unregister_by_instance(gaim_conversations_get_handle()); |
|
| 2221 } |
|