4 * Purple 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
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 #include "conversation.h"
32 /**************************************************************************/
33 /** @name Attention Type API */
34 /**************************************************************************/
36 purple_attention_type_new(const char *ulname
, const char *name
,
37 const char *inc_desc
, const char *out_desc
)
39 PurpleAttentionType
*attn
= g_new0(PurpleAttentionType
, 1);
41 purple_attention_type_set_name(attn
, name
);
42 purple_attention_type_set_incoming_desc(attn
, inc_desc
);
43 purple_attention_type_set_outgoing_desc(attn
, out_desc
);
44 purple_attention_type_set_unlocalized_name(attn
, ulname
);
51 purple_attention_type_set_name(PurpleAttentionType
*type
, const char *name
)
53 g_return_if_fail(type
!= NULL
);
59 purple_attention_type_set_incoming_desc(PurpleAttentionType
*type
, const char *desc
)
61 g_return_if_fail(type
!= NULL
);
63 type
->incoming_description
= desc
;
67 purple_attention_type_set_outgoing_desc(PurpleAttentionType
*type
, const char *desc
)
69 g_return_if_fail(type
!= NULL
);
71 type
->outgoing_description
= desc
;
75 purple_attention_type_set_icon_name(PurpleAttentionType
*type
, const char *name
)
77 g_return_if_fail(type
!= NULL
);
79 type
->icon_name
= name
;
83 purple_attention_type_set_unlocalized_name(PurpleAttentionType
*type
, const char *ulname
)
85 g_return_if_fail(type
!= NULL
);
87 type
->unlocalized_name
= ulname
;
91 purple_attention_type_get_name(const PurpleAttentionType
*type
)
93 g_return_val_if_fail(type
!= NULL
, NULL
);
99 purple_attention_type_get_incoming_desc(const PurpleAttentionType
*type
)
101 g_return_val_if_fail(type
!= NULL
, NULL
);
103 return type
->incoming_description
;
107 purple_attention_type_get_outgoing_desc(const PurpleAttentionType
*type
)
109 g_return_val_if_fail(type
!= NULL
, NULL
);
111 return type
->outgoing_description
;
115 purple_attention_type_get_icon_name(const PurpleAttentionType
*type
)
117 g_return_val_if_fail(type
!= NULL
, NULL
);
119 if(type
->icon_name
== NULL
|| *(type
->icon_name
) == '\0')
122 return type
->icon_name
;
126 purple_attention_type_get_unlocalized_name(const PurpleAttentionType
*type
)
128 g_return_val_if_fail(type
!= NULL
, NULL
);
130 return type
->unlocalized_name
;
133 /**************************************************************************/
134 /** @name Protocol Plugin API */
135 /**************************************************************************/
137 purple_prpl_got_account_idle(PurpleAccount
*account
, gboolean idle
,
140 g_return_if_fail(account
!= NULL
);
141 g_return_if_fail(purple_account_is_connected(account
));
143 purple_presence_set_idle(purple_account_get_presence(account
),
148 purple_prpl_got_account_login_time(PurpleAccount
*account
, time_t login_time
)
150 PurplePresence
*presence
;
152 g_return_if_fail(account
!= NULL
);
153 g_return_if_fail(purple_account_is_connected(account
));
156 login_time
= time(NULL
);
158 presence
= purple_account_get_presence(account
);
160 purple_presence_set_login_time(presence
, login_time
);
164 purple_prpl_got_account_status(PurpleAccount
*account
, const char *status_id
, ...)
166 PurplePresence
*presence
;
167 PurpleStatus
*status
;
170 g_return_if_fail(account
!= NULL
);
171 g_return_if_fail(status_id
!= NULL
);
172 g_return_if_fail(purple_account_is_connected(account
));
174 presence
= purple_account_get_presence(account
);
175 status
= purple_presence_get_status(presence
, status_id
);
177 g_return_if_fail(status
!= NULL
);
179 va_start(args
, status_id
);
180 purple_status_set_active_with_attrs(status
, TRUE
, args
);
185 purple_prpl_got_user_idle(PurpleAccount
*account
, const char *name
,
186 gboolean idle
, time_t idle_time
)
188 PurplePresence
*presence
;
191 g_return_if_fail(account
!= NULL
);
192 g_return_if_fail(name
!= NULL
);
193 g_return_if_fail(purple_account_is_connected(account
) || purple_account_is_connecting(account
));
195 if ((list
= purple_find_buddies(account
, name
)) == NULL
)
199 presence
= purple_buddy_get_presence(list
->data
);
200 list
= g_slist_delete_link(list
, list
);
201 purple_presence_set_idle(presence
, idle
, idle_time
);
206 purple_prpl_got_user_login_time(PurpleAccount
*account
, const char *name
,
210 PurplePresence
*presence
;
212 g_return_if_fail(account
!= NULL
);
213 g_return_if_fail(name
!= NULL
);
215 if ((list
= purple_find_buddies(account
, name
)) == NULL
)
219 login_time
= time(NULL
);
222 PurpleBuddy
*buddy
= list
->data
;
223 presence
= purple_buddy_get_presence(buddy
);
224 list
= g_slist_delete_link(list
, list
);
226 if (purple_presence_get_login_time(presence
) != login_time
)
228 purple_presence_set_login_time(presence
, login_time
);
230 purple_signal_emit(purple_blist_get_handle(), "buddy-got-login-time", buddy
);
236 purple_prpl_got_user_status(PurpleAccount
*account
, const char *name
,
237 const char *status_id
, ...)
241 PurplePresence
*presence
;
242 PurpleStatus
*status
;
243 PurpleStatus
*old_status
;
246 g_return_if_fail(account
!= NULL
);
247 g_return_if_fail(name
!= NULL
);
248 g_return_if_fail(status_id
!= NULL
);
249 g_return_if_fail(purple_account_is_connected(account
) || purple_account_is_connecting(account
));
251 if((list
= purple_find_buddies(account
, name
)) == NULL
)
254 for(l
= list
; l
!= NULL
; l
= l
->next
) {
257 presence
= purple_buddy_get_presence(buddy
);
258 status
= purple_presence_get_status(presence
, status_id
);
263 old_status
= purple_presence_get_active_status(presence
);
265 va_start(args
, status_id
);
266 purple_status_set_active_with_attrs(status
, TRUE
, args
);
269 purple_blist_update_buddy_status(buddy
, old_status
);
274 /* we get to re-use the last status we found */
275 if (!purple_status_is_online(status
))
276 serv_got_typing_stopped(purple_account_get_connection(account
), name
);
279 void purple_prpl_got_user_status_deactive(PurpleAccount
*account
, const char *name
,
280 const char *status_id
)
284 PurplePresence
*presence
;
285 PurpleStatus
*status
;
287 g_return_if_fail(account
!= NULL
);
288 g_return_if_fail(name
!= NULL
);
289 g_return_if_fail(status_id
!= NULL
);
290 g_return_if_fail(purple_account_is_connected(account
) || purple_account_is_connecting(account
));
292 if((list
= purple_find_buddies(account
, name
)) == NULL
)
295 for(l
= list
; l
!= NULL
; l
= l
->next
) {
298 presence
= purple_buddy_get_presence(buddy
);
299 status
= purple_presence_get_status(presence
, status_id
);
304 if (purple_status_is_active(status
)) {
305 purple_status_set_active(status
, FALSE
);
306 purple_blist_update_buddy_status(buddy
, status
);
314 do_prpl_change_account_status(PurpleAccount
*account
,
315 PurpleStatus
*old_status
, PurpleStatus
*new_status
)
318 PurplePluginProtocolInfo
*prpl_info
;
320 if (purple_status_is_online(new_status
) &&
321 purple_account_is_disconnected(account
) &&
322 purple_network_is_available())
324 purple_account_connect(account
);
328 if (!purple_status_is_online(new_status
))
330 if (!purple_account_is_disconnected(account
))
331 purple_account_disconnect(account
);
332 /* Clear out the unsaved password if we're already disconnected and we switch to offline status */
333 else if (!purple_account_get_remember_password(account
))
334 purple_account_set_password(account
, NULL
);
338 if (purple_account_is_connecting(account
))
340 * We don't need to call the set_status PRPL function because
341 * the PRPL will take care of setting its status during the
342 * connection process.
346 prpl
= purple_find_prpl(purple_account_get_protocol_id(account
));
351 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
353 if (!purple_account_is_disconnected(account
) && prpl_info
->set_status
!= NULL
)
355 prpl_info
->set_status(account
, new_status
);
360 purple_prpl_change_account_status(PurpleAccount
*account
,
361 PurpleStatus
*old_status
, PurpleStatus
*new_status
)
363 g_return_if_fail(account
!= NULL
);
364 g_return_if_fail(new_status
!= NULL
);
365 g_return_if_fail(!purple_status_is_exclusive(new_status
) || old_status
!= NULL
);
367 do_prpl_change_account_status(account
, old_status
, new_status
);
369 purple_signal_emit(purple_accounts_get_handle(), "account-status-changed",
370 account
, old_status
, new_status
);
374 purple_prpl_get_statuses(PurpleAccount
*account
, PurplePresence
*presence
)
376 GList
*statuses
= NULL
;
378 PurpleStatus
*status
;
380 g_return_val_if_fail(account
!= NULL
, NULL
);
381 g_return_val_if_fail(presence
!= NULL
, NULL
);
383 for (l
= purple_account_get_status_types(account
); l
!= NULL
; l
= l
->next
)
385 status
= purple_status_new((PurpleStatusType
*)l
->data
, presence
);
386 statuses
= g_list_prepend(statuses
, status
);
389 statuses
= g_list_reverse(statuses
);
395 purple_prpl_send_attention(PurpleConnection
*gc
, const char *who
, guint type_code
)
397 PurpleAttentionType
*attn
;
398 PurpleMessageFlags flags
;
400 PurpleConversation
*conv
;
401 gboolean (*send_attention
)(PurpleConnection
*, const char *, guint
);
407 g_return_if_fail(gc
!= NULL
);
408 g_return_if_fail(who
!= NULL
);
410 prpl
= purple_find_prpl(purple_account_get_protocol_id(gc
->account
));
411 send_attention
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
)->send_attention
;
412 g_return_if_fail(send_attention
!= NULL
);
416 attn
= purple_get_attention_type_from_code(gc
->account
, type_code
);
418 if ((buddy
= purple_find_buddy(purple_connection_get_account(gc
), who
)) != NULL
)
419 alias
= purple_buddy_get_contact_alias(buddy
);
423 if (attn
&& purple_attention_type_get_outgoing_desc(attn
)) {
424 description
= g_strdup_printf(purple_attention_type_get_outgoing_desc(attn
), alias
);
426 description
= g_strdup_printf(_("Requesting %s's attention..."), alias
);
429 flags
= PURPLE_MESSAGE_SEND
| PURPLE_MESSAGE_NOTIFY
| PURPLE_MESSAGE_SYSTEM
;
431 purple_debug_info("server", "serv_send_attention: sending '%s' to %s\n",
434 if (!send_attention(gc
, who
, type_code
))
437 conv
= purple_conversation_new(PURPLE_CONV_TYPE_IM
, gc
->account
, who
);
438 purple_conv_im_write(PURPLE_CONV_IM(conv
), NULL
, description
, flags
, mtime
);
444 got_attention(PurpleConnection
*gc
, int id
, const char *who
, guint type_code
)
446 PurpleMessageFlags flags
;
447 PurpleAttentionType
*attn
;
455 attn
= purple_get_attention_type_from_code(gc
->account
, type_code
);
457 /* PURPLE_MESSAGE_NOTIFY is for attention messages. */
458 flags
= PURPLE_MESSAGE_SYSTEM
| PURPLE_MESSAGE_NOTIFY
| PURPLE_MESSAGE_RECV
;
460 /* TODO: if (attn->icon_name) is non-null, use it to lookup an emoticon and display
461 * it next to the attention command. And if it is null, display a generic icon. */
463 if ((buddy
= purple_find_buddy(purple_connection_get_account(gc
), who
)) != NULL
)
464 alias
= purple_buddy_get_contact_alias(buddy
);
468 if (attn
&& purple_attention_type_get_incoming_desc(attn
)) {
469 description
= g_strdup_printf(purple_attention_type_get_incoming_desc(attn
), alias
);
471 description
= g_strdup_printf(_("%s has requested your attention!"), alias
);
474 purple_debug_info("server", "got_attention: got '%s' from %s\n",
478 serv_got_im(gc
, who
, description
, flags
, mtime
);
480 serv_got_chat_in(gc
, id
, who
, flags
, description
, mtime
);
482 /* TODO: sounds (depending on PurpleAttentionType), shaking, etc. */
488 purple_prpl_got_attention(PurpleConnection
*gc
, const char *who
, guint type_code
)
490 got_attention(gc
, -1, who
, type_code
);
494 purple_prpl_got_attention_in_chat(PurpleConnection
*gc
, int id
, const char *who
, guint type_code
)
496 got_attention(gc
, id
, who
, type_code
);
499 /**************************************************************************
500 * Protocol Plugin Subsystem API
501 **************************************************************************/
504 purple_find_prpl(const char *id
)
507 PurplePlugin
*plugin
;
509 g_return_val_if_fail(id
!= NULL
, NULL
);
511 for (l
= purple_plugins_get_protocols(); l
!= NULL
; l
= l
->next
) {
512 plugin
= (PurplePlugin
*)l
->data
;
514 if (!strcmp(plugin
->info
->id
, id
))