aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/oscar/oscar.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/oscar/oscar.c')
-rw-r--r--protocols/oscar/oscar.c168
1 files changed, 156 insertions, 12 deletions
diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c
index 76d61b13..15844479 100644
--- a/protocols/oscar/oscar.c
+++ b/protocols/oscar/oscar.c
@@ -61,7 +61,7 @@
/* Don't know if support for UTF8 is really working. For now it's UTF16 here.
static int gaim_caps = AIM_CAPS_UTF8; */
-static int gaim_caps = AIM_CAPS_INTEROP | AIM_CAPS_ICHAT | AIM_CAPS_ICQSERVERRELAY;
+static int gaim_caps = AIM_CAPS_INTEROP | AIM_CAPS_ICHAT | AIM_CAPS_ICQSERVERRELAY | AIM_CAPS_CHAT;
static guint8 gaim_features[] = {0x01, 0x01, 0x01, 0x02};
struct oscar_data {
@@ -155,7 +155,6 @@ static char *extract_name(const char *name) {
return tmp;
}
-#if 0
static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int id) {
GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats;
struct chat_connection *c = NULL;
@@ -170,7 +169,7 @@ static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int i
return c;
}
-#endif
+
static struct chat_connection *find_oscar_chat_by_conn(struct gaim_connection *gc,
aim_conn_t *conn) {
@@ -1075,14 +1074,15 @@ static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_
return 1;
}
+void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv);
+void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv);
+
static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
-#if 0
struct gaim_connection *gc = sess->aux_data;
-#endif
if (args->status != AIM_RENDEZVOUS_PROPOSE)
return 1;
-#if 0
+
if (args->reqclass & AIM_CAPS_CHAT) {
char *name = extract_name(args->info.chat.roominfo.name);
int *exch = g_new0(int, 1);
@@ -1090,15 +1090,23 @@ static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_
m = g_list_append(m, g_strdup(name ? name : args->info.chat.roominfo.name));
*exch = args->info.chat.roominfo.exchange;
m = g_list_append(m, exch);
- serv_got_chat_invite(gc,
- name ? name : args->info.chat.roominfo.name,
- userinfo->sn,
- (char *)args->msg,
- m);
+
+ char txt[1024];
+
+ g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", name, userinfo->sn, args->msg );
+
+ struct aim_chat_invitation * inv = g_new0(struct aim_chat_invitation, 1);
+
+ inv->gc = gc;
+ inv->exchange = *exch;
+ inv->name = g_strdup(name);
+
+ do_ask_dialog( gc, txt, inv, oscar_accept_chat, oscar_reject_chat);
+
if (name)
g_free(name);
}
-#endif
+
return 1;
}
@@ -2483,6 +2491,138 @@ int oscar_send_typing(struct gaim_connection *gc, char * who, int typing)
return( aim_im_sendmtn(od->sess, 1, who, typing ? 0x0002 : 0x0000) );
}
+int oscar_chat_send(struct gaim_connection * gc, int id, char *message)
+{
+ struct oscar_data * od = (struct oscar_data*)gc->proto_data;
+ struct chat_connection * ccon;
+
+ if(!(ccon = find_oscar_chat(gc, id)))
+ return -1;
+
+ int ret;
+ guint8 len = strlen(message);
+ char *s;
+
+ for (s = message; *s; s++)
+ if (*s & 128)
+ break;
+
+ /* Message contains high ASCII chars, time for some translation! */
+ if (*s) {
+ s = g_malloc(BUF_LONG);
+ /* Try if we can put it in an ISO8859-1 string first.
+ If we can't, fall back to UTF16. */
+ if ((ret = do_iconv("UTF-8", "ISO8859-1", message, s, len, BUF_LONG)) >= 0) {
+ len = ret;
+ } else if ((ret = do_iconv("UTF-8", "UNICODEBIG", message, s, len, BUF_LONG)) >= 0) {
+ len = ret;
+ } else {
+ /* OOF, translation failed... Oh well.. */
+ g_free( s );
+ s = message;
+ }
+ } else {
+ s = message;
+ }
+
+ ret = aim_chat_send_im(od->sess, ccon->conn, AIM_CHATFLAGS_NOREFLECT, s, len);
+
+ if (s != message) {
+ g_free(s);
+ }
+
+ return (ret >= 0);
+}
+
+void oscar_chat_invite(struct gaim_connection * gc, int id, char *message, char *who)
+{
+ struct oscar_data * od = (struct oscar_data *)gc->proto_data;
+ struct chat_connection *ccon = find_oscar_chat(gc, id);
+
+ if (ccon == NULL)
+ return;
+
+ aim_chat_invite(od->sess, od->conn, who, message ? message : "",
+ ccon->exchange, ccon->name, 0x0);
+}
+
+void oscar_chat_kill(struct gaim_connection *gc, struct chat_connection *cc)
+{
+ struct oscar_data *od = (struct oscar_data *)gc->proto_data;
+
+ /* Notify the conversation window that we've left the chat */
+ serv_got_chat_left(gc, cc->id);
+
+ /* Destroy the chat_connection */
+ od->oscar_chats = g_slist_remove(od->oscar_chats, cc);
+ if (cc->inpa > 0)
+ gaim_input_remove(cc->inpa);
+ aim_conn_kill(od->sess, &cc->conn);
+ g_free(cc->name);
+ g_free(cc->show);
+ g_free(cc);
+}
+
+void oscar_chat_leave(struct gaim_connection * gc, int id)
+{
+ struct chat_connection * ccon = find_oscar_chat(gc, id);
+
+ if(ccon == NULL)
+ return;
+
+ oscar_chat_kill(gc, ccon);
+}
+
+int oscar_chat_join(struct gaim_connection * gc, char * name)
+{
+ struct oscar_data * od = (struct oscar_data *)gc->proto_data;
+
+ aim_conn_t * cur;
+
+ if((cur = aim_getconn_type(od->sess, AIM_CONN_TYPE_CHATNAV))) {
+
+ return (aim_chatnav_createroom(od->sess, cur, name, 4) == 0);
+
+ } else {
+ struct create_room * cr = g_new0(struct create_room, 1);
+ cr->exchange = 4;
+ cr->name = g_strdup(name);
+ od->create_rooms = g_slist_append(od->create_rooms, cr);
+ aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_CHATNAV);
+ return 1;
+ }
+}
+
+int oscar_chat_open(struct gaim_connection * gc, char *who)
+{
+ struct oscar_data * od = (struct oscar_data *)gc->proto_data;
+
+ static int chat_id = 0;
+ char * chatname = g_new0(char, strlen(gc->username)+4);
+ g_snprintf(chatname, strlen(gc->username) + 4, "%s%d", gc->username, chat_id++);
+
+ int ret = oscar_chat_join(gc, chatname);
+
+ aim_chat_invite(od->sess, od->conn, who, "", 4, chatname, 0x0);
+
+ g_free(chatname);
+
+ return ret;
+}
+
+void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv)
+{
+ oscar_chat_join(inv->gc, inv->name);
+ g_free(inv->name);
+ g_free(inv);
+}
+
+void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv)
+{
+ g_free(inv->name);
+ g_free(inv);
+}
+
static struct prpl *my_protocol = NULL;
void oscar_init(struct prpl *ret) {
@@ -2496,6 +2636,10 @@ void oscar_init(struct prpl *ret) {
ret->get_away = oscar_get_away;
ret->add_buddy = oscar_add_buddy;
ret->remove_buddy = oscar_remove_buddy;
+ ret->chat_send = oscar_chat_send;
+ ret->chat_invite = oscar_chat_invite;
+ ret->chat_leave = oscar_chat_leave;
+ ret->chat_open = oscar_chat_open;
ret->add_permit = oscar_add_permit;
ret->add_deny = oscar_add_deny;
ret->rem_permit = oscar_rem_permit;