Mercurial > pidgin.yaz
comparison src/oscar.c @ 1059:6e60c69d4432
[gaim-migrate @ 1069]
direct IM
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 03 Nov 2000 23:12:55 +0000 |
parents | 713b0e14e0a9 |
children | 2c4f958c596e |
comparison
equal
deleted
inserted
replaced
1058:4927ce25d8cc | 1059:6e60c69d4432 |
---|---|
48 #include "pixmaps/admin_icon.xpm" | 48 #include "pixmaps/admin_icon.xpm" |
49 #include "pixmaps/aol_icon.xpm" | 49 #include "pixmaps/aol_icon.xpm" |
50 #include "pixmaps/away_icon.xpm" | 50 #include "pixmaps/away_icon.xpm" |
51 #include "pixmaps/dt_icon.xpm" | 51 #include "pixmaps/dt_icon.xpm" |
52 #include "pixmaps/free_icon.xpm" | 52 #include "pixmaps/free_icon.xpm" |
53 #include "pixmaps/ok.xpm" | |
54 #include "pixmaps/cancel.xpm" | |
53 | 55 |
54 int gaim_caps = AIM_CAPS_CHAT | AIM_CAPS_SENDFILE | AIM_CAPS_GETFILE | | 56 int gaim_caps = AIM_CAPS_CHAT | AIM_CAPS_SENDFILE | AIM_CAPS_GETFILE | |
55 AIM_CAPS_VOICE | AIM_CAPS_IMIMAGE | AIM_CAPS_BUDDYICON; | 57 AIM_CAPS_VOICE | AIM_CAPS_IMIMAGE | AIM_CAPS_BUDDYICON; |
56 | 58 |
57 struct oscar_data { | 59 struct oscar_data { |
63 | 65 |
64 int create_exchange; | 66 int create_exchange; |
65 char *create_name; | 67 char *create_name; |
66 | 68 |
67 GSList *oscar_chats; | 69 GSList *oscar_chats; |
70 GSList *direct_ims; | |
68 }; | 71 }; |
72 | |
73 struct direct_im { | |
74 struct gaim_connection *gc; | |
75 char name[80]; | |
76 struct conversation *cnv; | |
77 int watcher; | |
78 struct aim_conn_t *conn; | |
79 }; | |
80 | |
81 static struct direct_im *find_direct_im(struct oscar_data *od, char *who) { | |
82 GSList *d = od->direct_ims; | |
83 char *n = g_strdup(normalize(who)); | |
84 struct direct_im *m = NULL; | |
85 | |
86 while (d) { | |
87 m = (struct direct_im *)d->data; | |
88 if (!strcmp(n, normalize(m->name))) | |
89 break; | |
90 m = NULL; | |
91 d = d->next; | |
92 } | |
93 | |
94 g_free(n); | |
95 return m; | |
96 } | |
69 | 97 |
70 struct chat_connection *find_oscar_chat(struct gaim_connection *gc, char *name) { | 98 struct chat_connection *find_oscar_chat(struct gaim_connection *gc, char *name) { |
71 GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats; | 99 GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats; |
72 struct chat_connection *c = NULL; | 100 struct chat_connection *c = NULL; |
73 if (gc->protocol != PROTO_OSCAR) return NULL; | 101 if (gc->protocol != PROTO_OSCAR) return NULL; |
161 static int gaim_rateresp (struct aim_session_t *, struct command_rx_struct *, ...); | 189 static int gaim_rateresp (struct aim_session_t *, struct command_rx_struct *, ...); |
162 static int gaim_reportinterval (struct aim_session_t *, struct command_rx_struct *, ...); | 190 static int gaim_reportinterval (struct aim_session_t *, struct command_rx_struct *, ...); |
163 static int gaim_parse_msgerr (struct aim_session_t *, struct command_rx_struct *, ...); | 191 static int gaim_parse_msgerr (struct aim_session_t *, struct command_rx_struct *, ...); |
164 static int gaim_parse_buddyrights(struct aim_session_t *, struct command_rx_struct *, ...); | 192 static int gaim_parse_buddyrights(struct aim_session_t *, struct command_rx_struct *, ...); |
165 static int gaim_parse_locerr (struct aim_session_t *, struct command_rx_struct *, ...); | 193 static int gaim_parse_locerr (struct aim_session_t *, struct command_rx_struct *, ...); |
194 | |
195 static int gaim_directim_initiate (struct aim_session_t *, struct command_rx_struct *, ...); | |
196 static int gaim_directim_incoming (struct aim_session_t *, struct command_rx_struct *, ...); | |
197 static int gaim_directim_disconnect(struct aim_session_t *, struct command_rx_struct *, ...); | |
198 static int gaim_directim_typing (struct aim_session_t *, struct command_rx_struct *, ...); | |
166 | 199 |
167 static char *msgerrreason[] = { | 200 static char *msgerrreason[] = { |
168 "Invalid error", | 201 "Invalid error", |
169 "Invalid SNAC", | 202 "Invalid SNAC", |
170 "Rate to host", | 203 "Rate to host", |
626 serv_got_update(gc, sn, 0, 0, 0, 0, 0, 0); | 659 serv_got_update(gc, sn, 0, 0, 0, 0, 0, 0); |
627 | 660 |
628 return 1; | 661 return 1; |
629 } | 662 } |
630 | 663 |
664 struct ask_direct { | |
665 GtkWidget *window; | |
666 struct gaim_connection *gc; | |
667 char *sn; | |
668 struct aim_directim_priv *priv; | |
669 }; | |
670 | |
671 static void cancel_direct_im(GtkWidget *w, struct ask_direct *d) { | |
672 gtk_widget_destroy(d->window); | |
673 g_free(d->sn); | |
674 g_free(d); | |
675 } | |
676 | |
677 static void delete_direct_im(GtkWidget *w, struct direct_im *d) { | |
678 struct oscar_data *od = (struct oscar_data *)d->gc->proto_data; | |
679 | |
680 od->direct_ims = g_slist_remove(od->direct_ims, d); | |
681 gdk_input_remove(d->watcher); | |
682 aim_conn_kill(od->sess, &d->conn); | |
683 g_free(d); | |
684 } | |
685 | |
686 static void accept_direct_im(GtkWidget *w, struct ask_direct *d) { | |
687 struct gaim_connection *gc = d->gc; | |
688 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
689 struct direct_im *dim; | |
690 | |
691 dim = find_direct_im(od, d->sn); | |
692 if (dim) { | |
693 gtk_widget_show(dim->cnv->window); | |
694 cancel_direct_im(w, d); /* 40 */ | |
695 return; | |
696 } | |
697 dim = g_new0(struct direct_im, 1); | |
698 dim->gc = d->gc; | |
699 g_snprintf(dim->name, sizeof dim->name, "%s", d->sn); | |
700 | |
701 if ((dim->conn = aim_directim_connect(od->sess, od->conn, d->priv)) == NULL) { | |
702 g_free(dim); | |
703 cancel_direct_im(w, d); | |
704 return; | |
705 } | |
706 | |
707 if (!(dim->cnv = find_conversation(d->sn))) dim->cnv = new_conversation(d->sn); | |
708 gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy", | |
709 GTK_SIGNAL_FUNC(delete_direct_im), dim); | |
710 | |
711 od->direct_ims = g_slist_append(od->direct_ims, dim); | |
712 dim->watcher = gdk_input_add(dim->conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, | |
713 oscar_callback, dim->conn); | |
714 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, | |
715 gaim_directim_incoming, 0); | |
716 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, | |
717 gaim_directim_disconnect, 0); | |
718 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, | |
719 gaim_directim_typing, 0); | |
720 | |
721 cancel_direct_im(w, d); | |
722 } | |
723 | |
724 static void ask_direct_im(struct gaim_connection *gc, struct aim_userinfo_s *info, | |
725 struct aim_directim_priv *priv) { | |
726 struct ask_direct *d = g_new0(struct ask_direct, 1); | |
727 GtkWidget *window; | |
728 GtkWidget *box; | |
729 GtkWidget *label; | |
730 GtkWidget *hbox; | |
731 GtkWidget *button; | |
732 char buf[256]; | |
733 | |
734 d->gc = gc; | |
735 d->sn = g_strdup(info->sn); | |
736 d->priv = priv; | |
737 | |
738 window = gtk_window_new(GTK_WINDOW_DIALOG); | |
739 gtk_window_set_wmclass(GTK_WINDOW(window), "directim", "Gaim"); | |
740 gtk_window_set_policy(GTK_WINDOW(window), 0, 0, 1); | |
741 gtk_window_set_title(GTK_WINDOW(window), _("Accept Direct IM?")); | |
742 gtk_widget_realize(window); | |
743 aol_icon(window->window); | |
744 d->window = window; | |
745 | |
746 box = gtk_vbox_new(FALSE, 0); | |
747 gtk_container_add(GTK_CONTAINER(window), box); | |
748 gtk_widget_show(box); | |
749 | |
750 g_snprintf(buf, sizeof buf, "%s has just asked to directly connect to %s.", info->sn, gc->username); | |
751 label = gtk_label_new(buf); | |
752 gtk_box_pack_start(GTK_BOX(box), label, 0, 0, 5); | |
753 gtk_widget_show(label); | |
754 | |
755 hbox = gtk_hbox_new(FALSE, 0); | |
756 gtk_box_pack_start(GTK_BOX(box), hbox, 0, 0, 1); | |
757 gtk_widget_show(hbox); | |
758 | |
759 button = picture_button(window, _("Accept"), ok_xpm); | |
760 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5); | |
761 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(accept_direct_im), d); | |
762 | |
763 button = picture_button(window, _("Cancel"), cancel_xpm); | |
764 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 5); | |
765 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(cancel_direct_im), d); | |
766 | |
767 gtk_widget_show(window); | |
768 } | |
769 | |
631 int gaim_parse_incoming_im(struct aim_session_t *sess, | 770 int gaim_parse_incoming_im(struct aim_session_t *sess, |
632 struct command_rx_struct *command, ...) { | 771 struct command_rx_struct *command, ...) { |
633 int channel; | 772 int channel; |
634 va_list ap; | 773 va_list ap; |
635 struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); | 774 struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); |
673 roominfo->name, | 812 roominfo->name, |
674 roominfo->exchange, | 813 roominfo->exchange, |
675 userinfo->sn, | 814 userinfo->sn, |
676 msg); | 815 msg); |
677 } else if (rendtype & AIM_CAPS_SENDFILE) { | 816 } else if (rendtype & AIM_CAPS_SENDFILE) { |
678 /* libfaim won't tell us that we got this just yet */ | |
679 } else if (rendtype & AIM_CAPS_GETFILE) { | 817 } else if (rendtype & AIM_CAPS_GETFILE) { |
680 /* nor will it tell us this. but it's still there */ | |
681 } else if (rendtype & AIM_CAPS_VOICE) { | 818 } else if (rendtype & AIM_CAPS_VOICE) { |
682 /* this one libfaim tells us unuseful info about */ | |
683 } else if (rendtype & AIM_CAPS_BUDDYICON) { | 819 } else if (rendtype & AIM_CAPS_BUDDYICON) { |
684 /* bah */ | |
685 } else if (rendtype & AIM_CAPS_IMIMAGE) { | 820 } else if (rendtype & AIM_CAPS_IMIMAGE) { |
686 /* DirectIM stuff */ | 821 struct aim_directim_priv *priv; |
822 | |
823 userinfo = va_arg(ap, struct aim_userinfo_s *); | |
824 priv = va_arg(ap, struct aim_directim_priv *); | |
825 va_end(ap); | |
826 | |
827 debug_printf("%s received direct im request from %s (%s)\n", | |
828 gc->username, userinfo->sn, priv->ip); | |
829 | |
830 ask_direct_im(gc, userinfo, priv); | |
687 } else { | 831 } else { |
688 sprintf(debug_buff, "Unknown rendtype %d\n", rendtype); | 832 sprintf(debug_buff, "Unknown rendtype %d\n", rendtype); |
689 debug_print(debug_buff); | 833 debug_print(debug_buff); |
690 } | 834 } |
691 } | 835 } |
1148 return "Oscar"; | 1292 return "Oscar"; |
1149 } | 1293 } |
1150 | 1294 |
1151 static void oscar_send_im(struct gaim_connection *gc, char *name, char *message, int away) { | 1295 static void oscar_send_im(struct gaim_connection *gc, char *name, char *message, int away) { |
1152 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; | 1296 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; |
1153 if (away) | 1297 struct direct_im *dim = find_direct_im(odata, name); |
1154 aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_AWAY, message); | 1298 if (dim) { |
1155 else | 1299 aim_send_im_direct(odata->sess, dim->conn, message); |
1156 aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_ACK, message); | 1300 } else { |
1301 if (away) | |
1302 aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_AWAY, message); | |
1303 else | |
1304 aim_send_im(odata->sess, odata->conn, name, AIM_IMFLAGS_ACK, message); | |
1305 } | |
1157 } | 1306 } |
1158 | 1307 |
1159 static void oscar_get_info(struct gaim_connection *g, char *name) { | 1308 static void oscar_get_info(struct gaim_connection *g, char *name) { |
1160 struct oscar_data *odata = (struct oscar_data *)g->proto_data; | 1309 struct oscar_data *odata = (struct oscar_data *)g->proto_data; |
1161 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_GENERALINFO); | 1310 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_GENERALINFO); |
1353 static void oscar_away_msg(GtkObject *obj, char *who) { | 1502 static void oscar_away_msg(GtkObject *obj, char *who) { |
1354 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); | 1503 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); |
1355 serv_get_away_msg(gc, who); | 1504 serv_get_away_msg(gc, who); |
1356 } | 1505 } |
1357 | 1506 |
1507 static int gaim_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1508 va_list ap; | |
1509 struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); | |
1510 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1511 struct aim_directim_priv *priv; | |
1512 struct aim_conn_t *newconn; | |
1513 struct direct_im *dim; | |
1514 | |
1515 va_start(ap, command); | |
1516 newconn = va_arg(ap, struct aim_conn_t *); | |
1517 va_end(ap); | |
1518 | |
1519 priv = (struct aim_directim_priv *)newconn->priv; | |
1520 | |
1521 debug_printf("DirectIM: initiate success to %s\n", priv->sn); | |
1522 dim = find_direct_im(od, priv->sn); | |
1523 | |
1524 dim->cnv = find_conversation(priv->sn); | |
1525 if (!dim->cnv) dim->cnv = new_conversation(priv->sn); | |
1526 gtk_signal_connect(GTK_OBJECT(dim->cnv->window), "destroy", | |
1527 GTK_SIGNAL_FUNC(delete_direct_im), dim); | |
1528 gdk_input_remove(dim->watcher); | |
1529 dim->conn = newconn; | |
1530 dim->watcher = gdk_input_add(dim->conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, | |
1531 oscar_callback, dim->conn); | |
1532 /* FIXME: print to screen that this is now direct */ | |
1533 | |
1534 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, | |
1535 gaim_directim_incoming, 0); | |
1536 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, | |
1537 gaim_directim_disconnect, 0); | |
1538 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, | |
1539 gaim_directim_typing, 0); | |
1540 | |
1541 return 1; | |
1542 } | |
1543 | |
1544 static int gaim_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1545 va_list ap; | |
1546 char *sn = NULL, *msg = NULL; | |
1547 struct aim_conn_t *conn; | |
1548 struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); | |
1549 | |
1550 va_start(ap, command); | |
1551 conn = va_arg(ap, struct aim_conn_t *); | |
1552 sn = va_arg(ap, char *); | |
1553 msg = va_arg(ap, char *); | |
1554 va_end(ap); | |
1555 | |
1556 debug_printf("Got DirectIM message from %s\n", sn); | |
1557 | |
1558 serv_got_im(gc, sn, msg, 0); | |
1559 | |
1560 return 1; | |
1561 } | |
1562 | |
1563 static int gaim_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1564 va_list ap; | |
1565 struct aim_conn_t *conn; | |
1566 char *sn; | |
1567 struct gaim_connection *gc = find_gaim_conn_by_aim_sess(sess); | |
1568 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1569 struct direct_im *dim; | |
1570 | |
1571 va_start(ap, command); | |
1572 conn = va_arg(ap, struct aim_conn_t *); | |
1573 sn = va_arg(ap, char *); | |
1574 va_end(ap); | |
1575 | |
1576 debug_printf("%s disconnected Direct IM.\n", sn); | |
1577 | |
1578 dim = find_direct_im(od, sn); | |
1579 od->direct_ims = g_slist_remove(od->direct_ims, dim); | |
1580 gdk_input_remove(dim->watcher); | |
1581 gtk_signal_disconnect_by_data(GTK_OBJECT(dim->cnv->window), dim); | |
1582 | |
1583 /* FIXME: need to indicate no longer direct */ | |
1584 | |
1585 aim_conn_kill(sess, &conn); | |
1586 | |
1587 return 1; | |
1588 } | |
1589 | |
1590 static int gaim_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...) { | |
1591 va_list ap; | |
1592 char *sn; | |
1593 | |
1594 va_start(ap, command); | |
1595 sn = va_arg(ap, char *); | |
1596 va_end(ap); | |
1597 | |
1598 /* I had to leave this. It's just too funny. It reminds me of my sister. */ | |
1599 debug_printf("ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn); | |
1600 | |
1601 return 1; | |
1602 } | |
1603 | |
1604 static void oscar_direct_im(GtkObject *obj, char *who) { | |
1605 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(obj); | |
1606 struct oscar_data *od = (struct oscar_data *)gc->proto_data; | |
1607 struct direct_im *dim; | |
1608 | |
1609 dim = find_direct_im(od, who); | |
1610 if (dim) { | |
1611 gtk_widget_show(dim->cnv->window); | |
1612 return; | |
1613 } | |
1614 dim = g_new0(struct direct_im, 1); | |
1615 dim->gc = gc; | |
1616 g_snprintf(dim->name, sizeof dim->name, "%s", who); | |
1617 od->direct_ims = g_slist_append(od->direct_ims, dim); | |
1618 | |
1619 dim->conn = aim_directim_initiate(od->sess, od->conn, NULL, who); | |
1620 dim->watcher = gdk_input_add(dim->conn->fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, | |
1621 oscar_callback, dim->conn); | |
1622 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, | |
1623 gaim_directim_initiate, 0); | |
1624 } | |
1625 | |
1358 static void oscar_action_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { | 1626 static void oscar_action_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { |
1359 GtkWidget *button; | 1627 GtkWidget *button; |
1360 | 1628 |
1361 button = gtk_menu_item_new_with_label(_("Get Info")); | 1629 button = gtk_menu_item_new_with_label(_("Get Info")); |
1362 gtk_signal_connect(GTK_OBJECT(button), "activate", | 1630 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1366 gtk_widget_show(button); | 1634 gtk_widget_show(button); |
1367 | 1635 |
1368 button = gtk_menu_item_new_with_label(_("Get Away Msg")); | 1636 button = gtk_menu_item_new_with_label(_("Get Away Msg")); |
1369 gtk_signal_connect(GTK_OBJECT(button), "activate", | 1637 gtk_signal_connect(GTK_OBJECT(button), "activate", |
1370 GTK_SIGNAL_FUNC(oscar_away_msg), who); | 1638 GTK_SIGNAL_FUNC(oscar_away_msg), who); |
1639 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
1640 gtk_menu_append(GTK_MENU(menu), button); | |
1641 gtk_widget_show(button); | |
1642 | |
1643 button = gtk_menu_item_new_with_label(_("Direct IM")); | |
1644 gtk_signal_connect(GTK_OBJECT(button), "activate", | |
1645 GTK_SIGNAL_FUNC(oscar_direct_im), who); | |
1371 gtk_object_set_user_data(GTK_OBJECT(button), gc); | 1646 gtk_object_set_user_data(GTK_OBJECT(button), gc); |
1372 gtk_menu_append(GTK_MENU(menu), button); | 1647 gtk_menu_append(GTK_MENU(menu), button); |
1373 gtk_widget_show(button); | 1648 gtk_widget_show(button); |
1374 } | 1649 } |
1375 | 1650 |