comparison src/protocols/oscar/oscar.c @ 4359:5fb47ec9bfe4

[gaim-migrate @ 4625] Wow, okay, where to begin with this one ;) I rewrote the whole conversation backend. It is now core/UI split. Here's how it works.. Every conversation is represented by a gaim_conversation structure. This branches out into gaim_im and gaim_chat structures. Every conversation lives in (well, normally, but it doesn't have to) a gaim_window structure. This is a _CORE_ representation of a window. There can be multiple gaim_window structures around. The gaim_window and gaim_conversation structures have UI-specific operation structures associated with them. At the moment, the only UI is GTK+, and this will be for some time. Don't start thinking you can write a QT UI now. It's just not going to happen. Everything that is done on a conversation is done through the core API. This API does core processing and then calls the UI operations for the rendering and anything else. Now, what does this give the user? - Multiple windows. - Multiple tabs per window. - Draggable tabs. - Send As menu is moved to the menubar. - Menubar for chats. - Some very cool stuff in the future, like replacing, say, IRC chat windows with an X-Chat interface, or whatever. - Later on, customizable window/conversation positioning. For developers: - Fully documented API - Core/UI split - Variable checking and mostly sane handling of incorrect variables. - Logical structure to conversations, both core and UI. - Some very cool stuff in the future, like replacing, say, IRC chat windows with an X-Chat interface, or whatever. - Later on, customizable window/conversation positioning. - Oh yeah, and the beginning of a stock icon system. Now, there are things that aren't there yet. You will see tabs even if you have them turned off. This will be fixed in time. Also, the preferences will change to work with the new structure. I'm starting school in 2 days, so it may not be done immediately, but hopefully in the next week. Enjoy! committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Mon, 20 Jan 2003 09:10:23 +0000
parents 2b8abf7f9cc1
children 7ba9b56a8796
comparison
equal deleted inserted replaced
4358:2b8abf7f9cc1 4359:5fb47ec9bfe4
154 int fd; /* this is redundant since we have the conn below */ 154 int fd; /* this is redundant since we have the conn below */
155 aim_conn_t *conn; 155 aim_conn_t *conn;
156 int inpa; 156 int inpa;
157 int id; 157 int id;
158 struct gaim_connection *gc; /* i hate this. */ 158 struct gaim_connection *gc; /* i hate this. */
159 struct conversation *cnv; /* bah. */ 159 struct gaim_conversation *cnv; /* bah. */
160 int maxlen; 160 int maxlen;
161 int maxvis; 161 int maxvis;
162 }; 162 };
163 163
164 struct direct_im { 164 struct direct_im {
456 } 456 }
457 457
458 static void gaim_directim_disconnect(aim_session_t *sess, aim_conn_t *conn) { 458 static void gaim_directim_disconnect(aim_session_t *sess, aim_conn_t *conn) {
459 struct gaim_connection *gc = sess->aux_data; 459 struct gaim_connection *gc = sess->aux_data;
460 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 460 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
461 struct conversation *cnv; 461 struct gaim_conversation *cnv;
462 struct direct_im *dim; 462 struct direct_im *dim;
463 char *sn; 463 char *sn;
464 char buf[256]; 464 char buf[256];
465 465
466 sn = g_strdup(aim_directim_getsn(conn)); 466 sn = g_strdup(aim_directim_getsn(conn));
474 if (dim->connected) 474 if (dim->connected)
475 g_snprintf(buf, sizeof buf, _("Direct IM with %s closed"), sn); 475 g_snprintf(buf, sizeof buf, _("Direct IM with %s closed"), sn);
476 else 476 else
477 g_snprintf(buf, sizeof buf, _("Direct IM with %s failed"), sn); 477 g_snprintf(buf, sizeof buf, _("Direct IM with %s failed"), sn);
478 478
479 if ((cnv = find_conversation(sn))) 479 if ((cnv = gaim_find_conversation(sn)))
480 write_to_conv(cnv, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); 480 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL));
481 update_progress(cnv, 100); 481
482 gaim_conversation_update_progress(cnv, 100);
482 483
483 g_free(dim); /* I guess? I don't see it anywhere else... -- mid */ 484 g_free(dim); /* I guess? I don't see it anywhere else... -- mid */
484 g_free(sn); 485 g_free(sn);
485 486
486 return; 487 return;
1485 1486
1486 static void oscar_directim_callback(gpointer data, gint source, GaimInputCondition condition) { 1487 static void oscar_directim_callback(gpointer data, gint source, GaimInputCondition condition) {
1487 struct direct_im *dim = data; 1488 struct direct_im *dim = data;
1488 struct gaim_connection *gc = dim->gc; 1489 struct gaim_connection *gc = dim->gc;
1489 struct oscar_data *od = gc->proto_data; 1490 struct oscar_data *od = gc->proto_data;
1490 struct conversation *cnv; 1491 struct gaim_conversation *cnv;
1491 char buf[256]; 1492 char buf[256];
1492 struct sockaddr name; 1493 struct sockaddr name;
1493 socklen_t name_len = 1; 1494 socklen_t name_len = 1;
1494 1495
1495 if (!g_slist_find(connections, gc)) { 1496 if (!g_slist_find(connections, gc)) {
1503 } 1504 }
1504 1505
1505 if (dim->conn->fd != source) 1506 if (dim->conn->fd != source)
1506 dim->conn->fd = source; 1507 dim->conn->fd = source;
1507 aim_conn_completeconnect(od->sess, dim->conn); 1508 aim_conn_completeconnect(od->sess, dim->conn);
1508 if (!(cnv = find_conversation(dim->name))) 1509 if (!(cnv = gaim_find_conversation(dim->name)))
1509 cnv = new_conversation(dim->name); 1510 cnv = gaim_conversation_new(GAIM_CONV_IM, dim->name);
1510 1511
1511 /* This is the best way to see if we're connected or not */ 1512 /* This is the best way to see if we're connected or not */
1512 if (getpeername(source, &name, &name_len) == 0) { 1513 if (getpeername(source, &name, &name_len) == 0) {
1513 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name); 1514 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name);
1514 dim->connected = TRUE; 1515 dim->connected = TRUE;
1515 write_to_conv(cnv, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); 1516 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL));
1516 } 1517 }
1517 od->direct_ims = g_slist_append(od->direct_ims, dim); 1518 od->direct_ims = g_slist_append(od->direct_ims, dim);
1518 1519
1519 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, 1520 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
1520 oscar_callback, dim->conn); 1521 oscar_callback, dim->conn);
2954 c = find_oscar_chat_by_conn(g, fr->conn); 2955 c = find_oscar_chat_by_conn(g, fr->conn);
2955 if (!c) 2956 if (!c)
2956 return 1; 2957 return 1;
2957 2958
2958 for (i = 0; i < count; i++) 2959 for (i = 0; i < count; i++)
2959 add_chat_buddy(c->cnv, info[i].sn, NULL); 2960 gaim_chat_add_user(GAIM_CHAT(c->cnv), info[i].sn, NULL);
2960 2961
2961 return 1; 2962 return 1;
2962 } 2963 }
2963 2964
2964 static int gaim_chat_leave(aim_session_t *sess, aim_frame_t *fr, ...) { 2965 static int gaim_chat_leave(aim_session_t *sess, aim_frame_t *fr, ...) {
2977 c = find_oscar_chat_by_conn(g, fr->conn); 2978 c = find_oscar_chat_by_conn(g, fr->conn);
2978 if (!c) 2979 if (!c)
2979 return 1; 2980 return 1;
2980 2981
2981 for (i = 0; i < count; i++) 2982 for (i = 0; i < count; i++)
2982 remove_chat_buddy(c->cnv, info[i].sn, NULL); 2983 gaim_chat_remove_user(GAIM_CHAT(c->cnv), info[i].sn, NULL);
2983 2984
2984 return 1; 2985 return 1;
2985 } 2986 }
2986 2987
2987 static int gaim_chat_info_update(aim_session_t *sess, aim_frame_t *fr, ...) { 2988 static int gaim_chat_info_update(aim_session_t *sess, aim_frame_t *fr, ...) {
4505 } 4506 }
4506 4507
4507 static void oscar_chat_leave(struct gaim_connection *g, int id) { 4508 static void oscar_chat_leave(struct gaim_connection *g, int id) {
4508 struct oscar_data *odata = g ? (struct oscar_data *)g->proto_data : NULL; 4509 struct oscar_data *odata = g ? (struct oscar_data *)g->proto_data : NULL;
4509 GSList *bcs = g->buddy_chats; 4510 GSList *bcs = g->buddy_chats;
4510 struct conversation *b = NULL; 4511 struct gaim_conversation *b = NULL;
4511 struct chat_connection *c = NULL; 4512 struct chat_connection *c = NULL;
4512 int count = 0; 4513 int count = 0;
4513 4514
4514 while (bcs) { 4515 while (bcs) {
4515 count++; 4516 count++;
4516 b = (struct conversation *)bcs->data; 4517 b = (struct gaim_conversation *)bcs->data;
4517 if (id == b->id) 4518 if (id == gaim_chat_get_id(GAIM_CHAT(b)))
4518 break; 4519 break;
4519 bcs = bcs->next; 4520 bcs = bcs->next;
4520 b = NULL; 4521 b = NULL;
4521 } 4522 }
4522 4523
4523 if (!b) 4524 if (!b)
4524 return; 4525 return;
4525 4526
4526 debug_printf("Attempting to leave room %s (currently in %d rooms)\n", b->name, count); 4527 debug_printf("Attempting to leave room %s (currently in %d rooms)\n", b->name, count);
4527 4528
4528 c = find_oscar_chat(g, b->id); 4529 c = find_oscar_chat(g, gaim_chat_get_id(GAIM_CHAT(b)));
4529 if (c != NULL) { 4530 if (c != NULL) {
4530 if (odata) 4531 if (odata)
4531 odata->oscar_chats = g_slist_remove(odata->oscar_chats, c); 4532 odata->oscar_chats = g_slist_remove(odata->oscar_chats, c);
4532 if (c->inpa > 0) 4533 if (c->inpa > 0)
4533 gaim_input_remove(c->inpa); 4534 gaim_input_remove(c->inpa);
4536 g_free(c->name); 4537 g_free(c->name);
4537 g_free(c->show); 4538 g_free(c->show);
4538 g_free(c); 4539 g_free(c);
4539 } 4540 }
4540 /* we do this because with Oscar it doesn't tell us we left */ 4541 /* we do this because with Oscar it doesn't tell us we left */
4541 serv_got_chat_left(g, b->id); 4542 serv_got_chat_left(g, gaim_chat_get_id(GAIM_CHAT(b)));
4542 } 4543 }
4543 4544
4544 static int oscar_chat_send(struct gaim_connection *g, int id, char *message) { 4545 static int oscar_chat_send(struct gaim_connection *g, int id, char *message) {
4545 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 4546 struct oscar_data *odata = (struct oscar_data *)g->proto_data;
4546 GSList *bcs = g->buddy_chats; 4547 GSList *bcs = g->buddy_chats;
4547 struct conversation *b = NULL; 4548 struct gaim_conversation *b = NULL;
4548 struct chat_connection *c = NULL; 4549 struct chat_connection *c = NULL;
4549 char *buf, *buf2; 4550 char *buf, *buf2;
4550 int i, j; 4551 int i, j;
4551 4552
4552 while (bcs) { 4553 while (bcs) {
4553 b = (struct conversation *)bcs->data; 4554 b = (struct gaim_conversation *)bcs->data;
4554 if (id == b->id) 4555 if (id == gaim_chat_get_id(GAIM_CHAT(b)))
4555 break; 4556 break;
4556 bcs = bcs->next; 4557 bcs = bcs->next;
4557 b = NULL; 4558 b = NULL;
4558 } 4559 }
4559 if (!b) 4560 if (!b)
4728 static int gaim_directim_initiate(aim_session_t *sess, aim_frame_t *fr, ...) { 4729 static int gaim_directim_initiate(aim_session_t *sess, aim_frame_t *fr, ...) {
4729 va_list ap; 4730 va_list ap;
4730 struct gaim_connection *gc = sess->aux_data; 4731 struct gaim_connection *gc = sess->aux_data;
4731 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4732 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4732 aim_conn_t *newconn, *listenerconn; 4733 aim_conn_t *newconn, *listenerconn;
4733 struct conversation *cnv; 4734 struct gaim_conversation *cnv;
4734 struct direct_im *dim; 4735 struct direct_im *dim;
4735 char buf[256]; 4736 char buf[256];
4736 char *sn; 4737 char *sn;
4737 4738
4738 va_start(ap, fr); 4739 va_start(ap, fr);
4746 sn = g_strdup(aim_directim_getsn(newconn)); 4747 sn = g_strdup(aim_directim_getsn(newconn));
4747 4748
4748 debug_printf("DirectIM: initiate success to %s\n", sn); 4749 debug_printf("DirectIM: initiate success to %s\n", sn);
4749 dim = find_direct_im(od, sn); 4750 dim = find_direct_im(od, sn);
4750 4751
4751 if (!(cnv = find_conversation(sn))) 4752 if (!(cnv = gaim_find_conversation(sn)))
4752 cnv = new_conversation(sn); 4753 cnv = gaim_conversation_new(GAIM_CONV_IM, sn);
4753 gaim_input_remove(dim->watcher); 4754 gaim_input_remove(dim->watcher);
4754 dim->conn = newconn; 4755 dim->conn = newconn;
4755 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, 4756 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
4756 oscar_callback, dim->conn); 4757 oscar_callback, dim->conn);
4757 dim->connected = TRUE; 4758 dim->connected = TRUE;
4758 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), sn); 4759 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), sn);
4759 g_free(sn); 4760 g_free(sn);
4760 write_to_conv(cnv, buf, WFLAG_SYSTEM, NULL, time(NULL), -1); 4761 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL));
4761 4762
4762 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, 4763 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING,
4763 gaim_directim_incoming, 0); 4764 gaim_directim_incoming, 0);
4764 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, 4765 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING,
4765 gaim_directim_typing, 0); 4766 gaim_directim_typing, 0);
4772 va_list ap; 4773 va_list ap;
4773 char *sn; 4774 char *sn;
4774 double percent; 4775 double percent;
4775 struct gaim_connection *gc = sess->aux_data; 4776 struct gaim_connection *gc = sess->aux_data;
4776 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4777 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4777 struct conversation *c; 4778 struct gaim_conversation *c;
4778 struct direct_im *dim; 4779 struct direct_im *dim;
4779 4780
4780 va_start(ap, fr); 4781 va_start(ap, fr);
4781 sn = va_arg(ap, char *); 4782 sn = va_arg(ap, char *);
4782 percent = va_arg(ap, double); 4783 percent = va_arg(ap, double);
4789 dim->watcher = 0; 4790 dim->watcher = 0;
4790 } 4791 }
4791 while (gtk_events_pending()) 4792 while (gtk_events_pending())
4792 gtk_main_iteration(); 4793 gtk_main_iteration();
4793 4794
4794 if ((c = find_conversation(sn))) 4795 if ((c = gaim_find_conversation(sn)))
4795 update_progress(c, percent); 4796 gaim_conversation_update_progress(c, percent);
4796 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, 4797 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
4797 oscar_callback, dim->conn); 4798 oscar_callback, dim->conn);
4798 4799
4799 return 1; 4800 return 1;
4800 } 4801 }