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