comparison libpurple/protocols/sametime/sametime.c @ 31086:a8cc50c2279f

Remove trailing whitespace
author Richard Laager <rlaager@wiktel.com>
date Tue, 04 Jan 2011 06:55:30 +0000
parents 1cdae196aac8
children 3ef5e744589c
comparison
equal deleted inserted replaced
31085:44f53d3fc54f 31086:a8cc50c2279f
315 315
316 316
317 /** resolves a mwSession from a PurpleConnection */ 317 /** resolves a mwSession from a PurpleConnection */
318 static struct mwSession *gc_to_session(PurpleConnection *gc) { 318 static struct mwSession *gc_to_session(PurpleConnection *gc) {
319 struct mwPurplePluginData *pd; 319 struct mwPurplePluginData *pd;
320 320
321 g_return_val_if_fail(gc != NULL, NULL); 321 g_return_val_if_fail(gc != NULL, NULL);
322 322
323 pd = gc->proto_data; 323 pd = gc->proto_data;
324 g_return_val_if_fail(pd != NULL, NULL); 324 g_return_val_if_fail(pd != NULL, NULL);
325 325
326 return pd->session; 326 return pd->session;
327 } 327 }
328 328
329 329
330 /** resolves a PurpleConnection from a mwSession */ 330 /** resolves a PurpleConnection from a mwSession */
353 avail = purple_circ_buffer_get_max_read(circ); 353 avail = purple_circ_buffer_get_max_read(circ);
354 if(BUF_LONG < avail) avail = BUF_LONG; 354 if(BUF_LONG < avail) avail = BUF_LONG;
355 355
356 while(avail) { 356 while(avail) {
357 ret = write(pd->socket, circ->outptr, avail); 357 ret = write(pd->socket, circ->outptr, avail);
358 358
359 if(ret <= 0) 359 if(ret <= 0)
360 break; 360 break;
361 361
362 purple_circ_buffer_mark_read(circ, ret); 362 purple_circ_buffer_mark_read(circ, ret);
363 avail = purple_circ_buffer_get_max_read(circ); 363 avail = purple_circ_buffer_get_max_read(circ);
436 436
437 pd = mwSession_getClientData(session); 437 pd = mwSession_getClientData(session);
438 g_return_if_fail(pd != NULL); 438 g_return_if_fail(pd != NULL);
439 439
440 gc = pd->gc; 440 gc = pd->gc;
441 441
442 if(pd->outpa) { 442 if(pd->outpa) {
443 purple_input_remove(pd->outpa); 443 purple_input_remove(pd->outpa);
444 pd->outpa = 0; 444 pd->outpa = 0;
445 } 445 }
446 446
447 if(pd->socket) { 447 if(pd->socket) {
448 close(pd->socket); 448 close(pd->socket);
449 pd->socket = 0; 449 pd->socket = 0;
450 } 450 }
451 451
452 if(gc->inpa) { 452 if(gc->inpa) {
453 purple_input_remove(gc->inpa); 453 purple_input_remove(gc->inpa);
454 gc->inpa = 0; 454 gc->inpa = 0;
455 } 455 }
456 } 456 }
487 static void mw_aware_list_on_aware(struct mwAwareList *list, 487 static void mw_aware_list_on_aware(struct mwAwareList *list,
488 struct mwAwareSnapshot *aware) { 488 struct mwAwareSnapshot *aware) {
489 489
490 PurpleConnection *gc; 490 PurpleConnection *gc;
491 PurpleAccount *acct; 491 PurpleAccount *acct;
492 492
493 struct mwPurplePluginData *pd; 493 struct mwPurplePluginData *pd;
494 guint32 idle; 494 guint32 idle;
495 guint stat; 495 guint stat;
496 const char *id; 496 const char *id;
497 const char *status = MW_STATE_ACTIVE; 497 const char *status = MW_STATE_ACTIVE;
505 id = aware->id.user; 505 id = aware->id.user;
506 506
507 if(idle) { 507 if(idle) {
508 guint32 idle_len; /*< how long a client has been idle */ 508 guint32 idle_len; /*< how long a client has been idle */
509 guint32 ugly_idle_len; /*< how long a broken client has been idle */ 509 guint32 ugly_idle_len; /*< how long a broken client has been idle */
510 510
511 DEBUG_INFO("%s has idle value 0x%x\n", NSTR(id), idle); 511 DEBUG_INFO("%s has idle value 0x%x\n", NSTR(id), idle);
512 512
513 idle_len = time(NULL) - idle; 513 idle_len = time(NULL) - idle;
514 ugly_idle_len = ((time(NULL) * 1000) - idle) / 1000; 514 ugly_idle_len = ((time(NULL) * 1000) - idle) / 1000;
515 515
516 if(idle > ugly_idle_len) 516 if(idle > ugly_idle_len)
517 ugly_idle_len = 0; 517 ugly_idle_len = 0;
518 else 518 else
519 ugly_idle_len = (ugly_idle_len - idle) / 1000; 519 ugly_idle_len = (ugly_idle_len - idle) / 1000;
520 520
521 /* 521 /*
522 what's the deal here? Well, good clients are smart enough to 522 what's the deal here? Well, good clients are smart enough to
523 publish their idle time by using an attribute to indicate that 523 publish their idle time by using an attribute to indicate that
524 they went idle at some time UTC, in seconds since epoch. Bad 524 they went idle at some time UTC, in seconds since epoch. Bad
525 clients use milliseconds since epoch. So we're going to compute 525 clients use milliseconds since epoch. So we're going to compute
526 the idle time for either method, then figure out the lower of 526 the idle time for either method, then figure out the lower of
552 break; 552 break;
553 553
554 case mwStatus_IDLE: 554 case mwStatus_IDLE:
555 if(! idle) idle = -1; 555 if(! idle) idle = -1;
556 break; 556 break;
557 557
558 case mwStatus_AWAY: 558 case mwStatus_AWAY:
559 status = MW_STATE_AWAY; 559 status = MW_STATE_AWAY;
560 break; 560 break;
561 561
562 case mwStatus_BUSY: 562 case mwStatus_BUSY:
563 status = MW_STATE_BUSY; 563 status = MW_STATE_BUSY;
564 break; 564 break;
565 } 565 }
566 566
567 /* NAB group members */ 567 /* NAB group members */
568 if(aware->group) { 568 if(aware->group) {
569 PurpleGroup *group; 569 PurpleGroup *group;
570 PurpleBuddy *buddy; 570 PurpleBuddy *buddy;
571 PurpleBlistNode *bnode; 571 PurpleBlistNode *bnode;
591 g_list_free(query); 591 g_list_free(query);
592 } 592 }
593 593
594 purple_blist_node_set_int(bnode, BUDDY_KEY_TYPE, mwSametimeUser_NORMAL); 594 purple_blist_node_set_int(bnode, BUDDY_KEY_TYPE, mwSametimeUser_NORMAL);
595 } 595 }
596 596
597 if(aware->online) { 597 if(aware->online) {
598 purple_prpl_got_user_status(acct, id, status, NULL); 598 purple_prpl_got_user_status(acct, id, status, NULL);
599 purple_prpl_got_user_idle(acct, id, !!idle, (time_t) idle); 599 purple_prpl_got_user_idle(acct, id, !!idle, (time_t) idle);
600 600
601 } else { 601 } else {
626 626
627 /** Ensures that an Aware List is associated with the given group, and 627 /** Ensures that an Aware List is associated with the given group, and
628 returns that list. */ 628 returns that list. */
629 static struct mwAwareList * 629 static struct mwAwareList *
630 list_ensure(struct mwPurplePluginData *pd, PurpleGroup *group) { 630 list_ensure(struct mwPurplePluginData *pd, PurpleGroup *group) {
631 631
632 struct mwAwareList *list; 632 struct mwAwareList *list;
633 633
634 g_return_val_if_fail(pd != NULL, NULL); 634 g_return_val_if_fail(pd != NULL, NULL);
635 g_return_val_if_fail(group != NULL, NULL); 635 g_return_val_if_fail(group != NULL, NULL);
636 636
637 list = g_hash_table_lookup(pd->group_list_map, group); 637 list = g_hash_table_lookup(pd->group_list_map, group);
638 if(! list) { 638 if(! list) {
639 list = mwAwareList_new(pd->srvc_aware, &mw_aware_list_handler); 639 list = mwAwareList_new(pd->srvc_aware, &mw_aware_list_handler);
640 mwAwareList_setClientData(list, pd->gc, NULL); 640 mwAwareList_setClientData(list, pd->gc, NULL);
641 641
642 mwAwareList_watchAttributes(list, 642 mwAwareList_watchAttributes(list,
643 mwAttribute_AV_PREFS_SET, 643 mwAttribute_AV_PREFS_SET,
644 mwAttribute_MICROPHONE, 644 mwAttribute_MICROPHONE,
645 mwAttribute_SPEAKERS, 645 mwAttribute_SPEAKERS,
646 mwAttribute_VIDEO_CAMERA, 646 mwAttribute_VIDEO_CAMERA,
648 NULL); 648 NULL);
649 649
650 g_hash_table_replace(pd->group_list_map, group, list); 650 g_hash_table_replace(pd->group_list_map, group, list);
651 g_hash_table_insert(pd->group_list_map, list, group); 651 g_hash_table_insert(pd->group_list_map, list, group);
652 } 652 }
653 653
654 return list; 654 return list;
655 } 655 }
656 656
657 657
658 static void blist_export(PurpleConnection *gc, struct mwSametimeList *stlist) { 658 static void blist_export(PurpleConnection *gc, struct mwSametimeList *stlist) {
687 if(! gtype) gtype = mwSametimeGroup_NORMAL; 687 if(! gtype) gtype = mwSametimeGroup_NORMAL;
688 688
689 /* if it's a normal group with none of our people in it, skip it */ 689 /* if it's a normal group with none of our people in it, skip it */
690 if(gtype == mwSametimeGroup_NORMAL && !purple_group_on_account(grp, acct)) 690 if(gtype == mwSametimeGroup_NORMAL && !purple_group_on_account(grp, acct))
691 continue; 691 continue;
692 692
693 /* if the group has an owner and we're not it, skip it */ 693 /* if the group has an owner and we're not it, skip it */
694 owner = purple_blist_node_get_string(gn, GROUP_KEY_OWNER); 694 owner = purple_blist_node_get_string(gn, GROUP_KEY_OWNER);
695 if(owner && strcmp(owner, purple_account_get_username(acct))) 695 if(owner && strcmp(owner, purple_account_get_username(acct)))
696 continue; 696 continue;
697 697
738 mwSametimeUser_setShortName(stu, purple_buddy_get_server_alias(bdy)); 738 mwSametimeUser_setShortName(stu, purple_buddy_get_server_alias(bdy));
739 mwSametimeUser_setAlias(stu, purple_buddy_get_local_buddy_alias(bdy)); 739 mwSametimeUser_setAlias(stu, purple_buddy_get_local_buddy_alias(bdy));
740 } 740 }
741 } 741 }
742 } 742 }
743 } 743 }
744 } 744 }
745 745
746 746
747 static void blist_store(struct mwPurplePluginData *pd) { 747 static void blist_store(struct mwPurplePluginData *pd) {
748 748
840 purple_blist_remove_buddy(buddy); 840 purple_blist_remove_buddy(buddy);
841 } 841 }
842 842
843 blist_schedule(pd); 843 blist_schedule(pd);
844 844
845 g_list_free(add); 845 g_list_free(add);
846 } 846 }
847 847
848 848
849 /** ensure that a PurpleBuddy exists in the group with data 849 /** ensure that a PurpleBuddy exists in the group with data
850 appropriately matching the st user entry from the st list */ 850 appropriately matching the st user entry from the st list */
864 g_return_val_if_fail(strlen(id) > 0, NULL); 864 g_return_val_if_fail(strlen(id) > 0, NULL);
865 865
866 buddy = purple_find_buddy_in_group(acct, id, group); 866 buddy = purple_find_buddy_in_group(acct, id, group);
867 if(! buddy) { 867 if(! buddy) {
868 buddy = purple_buddy_new(acct, id, alias); 868 buddy = purple_buddy_new(acct, id, alias);
869 869
870 purple_blist_add_buddy(buddy, NULL, group, NULL); 870 purple_blist_add_buddy(buddy, NULL, group, NULL);
871 buddy_add(pd, buddy); 871 buddy_add(pd, buddy);
872 } 872 }
873 873
874 purple_blist_alias_buddy(buddy, alias); 874 purple_blist_alias_buddy(buddy, alias);
875 purple_blist_server_alias_buddy(buddy, name); 875 purple_blist_server_alias_buddy(buddy, name);
876 purple_blist_node_set_string((PurpleBlistNode *) buddy, BUDDY_KEY_NAME, name); 876 purple_blist_node_set_string((PurpleBlistNode *) buddy, BUDDY_KEY_NAME, name);
877 purple_blist_node_set_int((PurpleBlistNode *) buddy, BUDDY_KEY_TYPE, type); 877 purple_blist_node_set_int((PurpleBlistNode *) buddy, BUDDY_KEY_TYPE, type);
878 878
886 886
887 struct mwAwareIdBlock idb = { mwAware_GROUP, NULL, NULL }; 887 struct mwAwareIdBlock idb = { mwAware_GROUP, NULL, NULL };
888 struct mwAwareList *list; 888 struct mwAwareList *list;
889 const char *n; 889 const char *n;
890 GList *add; 890 GList *add;
891 891
892 n = purple_blist_node_get_string((PurpleBlistNode *) group, GROUP_KEY_NAME); 892 n = purple_blist_node_get_string((PurpleBlistNode *) group, GROUP_KEY_NAME);
893 if(! n) n = purple_group_get_name(group); 893 if(! n) n = purple_group_get_name(group);
894 894
895 idb.user = (char *) n; 895 idb.user = (char *) n;
896 add = g_list_prepend(NULL, &idb); 896 add = g_list_prepend(NULL, &idb);
963 963
964 if(type == mwSametimeGroup_DYNAMIC) { 964 if(type == mwSametimeGroup_DYNAMIC) {
965 purple_blist_node_set_string(gn, GROUP_KEY_OWNER, owner); 965 purple_blist_node_set_string(gn, GROUP_KEY_OWNER, owner);
966 group_add(gc->proto_data, group); 966 group_add(gc->proto_data, group);
967 } 967 }
968 968
969 return group; 969 return group;
970 } 970 }
971 971
972 972
973 /** merge the entries from a st list into the purple blist */ 973 /** merge the entries from a st list into the purple blist */
1023 bn; 1023 bn;
1024 bn = purple_blist_node_get_sibling_next(bn)) { 1024 bn = purple_blist_node_get_sibling_next(bn)) {
1025 PurpleBuddy *gb = (PurpleBuddy *) bn; 1025 PurpleBuddy *gb = (PurpleBuddy *) bn;
1026 1026
1027 if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue; 1027 if(! PURPLE_BLIST_NODE_IS_BUDDY(bn)) continue;
1028 1028
1029 if(purple_buddy_get_account(gb) == acct) { 1029 if(purple_buddy_get_account(gb) == acct) {
1030 DEBUG_INFO("clearing %s from group\n", NSTR(purple_buddy_get_name(gb))); 1030 DEBUG_INFO("clearing %s from group\n", NSTR(purple_buddy_get_name(gb)));
1031 prune = g_list_prepend(prune, gb); 1031 prune = g_list_prepend(prune, gb);
1032 } 1032 }
1033 } 1033 }
1055 static void group_prune(PurpleConnection *gc, PurpleGroup *group, 1055 static void group_prune(PurpleConnection *gc, PurpleGroup *group,
1056 struct mwSametimeGroup *stgroup) { 1056 struct mwSametimeGroup *stgroup) {
1057 1057
1058 PurpleAccount *acct; 1058 PurpleAccount *acct;
1059 PurpleBlistNode *gn, *cn, *bn; 1059 PurpleBlistNode *gn, *cn, *bn;
1060 1060
1061 GHashTable *stusers; 1061 GHashTable *stusers;
1062 GList *prune = NULL; 1062 GList *prune = NULL;
1063 GList *ul, *utl; 1063 GList *ul, *utl;
1064 1064
1065 g_return_if_fail(group != NULL); 1065 g_return_if_fail(group != NULL);
1068 1068
1069 acct = purple_connection_get_account(gc); 1069 acct = purple_connection_get_account(gc);
1070 g_return_if_fail(acct != NULL); 1070 g_return_if_fail(acct != NULL);
1071 1071
1072 stusers = g_hash_table_new(g_str_hash, g_str_equal); 1072 stusers = g_hash_table_new(g_str_hash, g_str_equal);
1073 1073
1074 /* build a hash table for quick lookup while pruning the group 1074 /* build a hash table for quick lookup while pruning the group
1075 contents */ 1075 contents */
1076 utl = mwSametimeGroup_getUsers(stgroup); 1076 utl = mwSametimeGroup_getUsers(stgroup);
1077 for(ul = utl; ul; ul = ul->next) { 1077 for(ul = utl; ul; ul = ul->next) {
1078 const char *id = mwSametimeUser_getUser(ul->data); 1078 const char *id = mwSametimeUser_getUser(ul->data);
1203 if(owner && strcmp(owner, acct_n)) { 1203 if(owner && strcmp(owner, acct_n)) {
1204 /* it's a specialty group belonging to another account with some 1204 /* it's a specialty group belonging to another account with some
1205 of our members in it, so don't fully delete it */ 1205 of our members in it, so don't fully delete it */
1206 del = FALSE; 1206 del = FALSE;
1207 } 1207 }
1208 1208
1209 group_clear(g_prune->data, acct, del); 1209 group_clear(g_prune->data, acct, del);
1210 g_prune = g_list_delete_link(g_prune, g_prune); 1210 g_prune = g_list_delete_link(g_prune, g_prune);
1211 } 1211 }
1212 1212
1213 /* done with the pruning, let's merge in the additions */ 1213 /* done with the pruning, let's merge in the additions */
1278 1278
1279 who.user = (char *) purple_conversation_get_name(g_conv); 1279 who.user = (char *) purple_conversation_get_name(g_conv);
1280 conv = mwServiceIm_getConversation(pd->srvc_im, &who); 1280 conv = mwServiceIm_getConversation(pd->srvc_im, &who);
1281 1281
1282 convo_features(conv); 1282 convo_features(conv);
1283 1283
1284 if(mwConversation_isClosed(conv)) 1284 if(mwConversation_isClosed(conv))
1285 mwConversation_open(conv); 1285 mwConversation_open(conv);
1286 } 1286 }
1287 1287
1288 1288
1389 add_buds = g_list_append(add_buds, b); 1389 add_buds = g_list_append(add_buds, b);
1390 } 1390 }
1391 } 1391 }
1392 } 1392 }
1393 } 1393 }
1394 1394
1395 if(add_buds) { 1395 if(add_buds) {
1396 purple_account_add_buddies(acct, add_buds); 1396 purple_account_add_buddies(acct, add_buds);
1397 g_list_free(add_buds); 1397 g_list_free(add_buds);
1398 } 1398 }
1399 } 1399 }
1410 gc = pd->gc; 1410 gc = pd->gc;
1411 acct = purple_connection_get_account(gc); 1411 acct = purple_connection_get_account(gc);
1412 1412
1413 /* grab the buddy list from the server */ 1413 /* grab the buddy list from the server */
1414 unit = mwStorageUnit_new(mwStore_AWARE_LIST); 1414 unit = mwStorageUnit_new(mwStore_AWARE_LIST);
1415 mwServiceStorage_load(pd->srvc_store, unit, fetch_blist_cb, pd, NULL); 1415 mwServiceStorage_load(pd->srvc_store, unit, fetch_blist_cb, pd, NULL);
1416 1416
1417 /* find all the NAB groups and subscribe to them */ 1417 /* find all the NAB groups and subscribe to them */
1418 for(l = purple_blist_get_root(); l; 1418 for(l = purple_blist_get_root(); l;
1419 l = purple_blist_node_get_sibling_next(l)) { 1419 l = purple_blist_node_get_sibling_next(l)) {
1420 PurpleGroup *group = (PurpleGroup *) l; 1420 PurpleGroup *group = (PurpleGroup *) l;
1490 1490
1491 /* set out initial status */ 1491 /* set out initial status */
1492 acct = purple_connection_get_account(pd->gc); 1492 acct = purple_connection_get_account(pd->gc);
1493 status = purple_account_get_active_status(acct); 1493 status = purple_account_get_active_status(acct);
1494 mw_prpl_set_status(acct, status); 1494 mw_prpl_set_status(acct, status);
1495 1495
1496 /* start watching for new conversations */ 1496 /* start watching for new conversations */
1497 purple_signal_connect(purple_conversations_get_handle(), 1497 purple_signal_connect(purple_conversations_get_handle(),
1498 "conversation-created", pd, 1498 "conversation-created", pd,
1499 PURPLE_CALLBACK(conversation_created_cb), pd); 1499 PURPLE_CALLBACK(conversation_created_cb), pd);
1500 1500
1501 /* watch for group extended menu items */ 1501 /* watch for group extended menu items */
1502 purple_signal_connect(purple_blist_get_handle(), 1502 purple_signal_connect(purple_blist_get_handle(),
1503 "blist-node-extended-menu", pd, 1503 "blist-node-extended-menu", pd,
1504 PURPLE_CALLBACK(blist_node_menu_cb), pd); 1504 PURPLE_CALLBACK(blist_node_menu_cb), pd);
1505 1505
1506 /* use our services to do neat things */ 1506 /* use our services to do neat things */
1507 services_starting(pd); 1507 services_starting(pd);
1508 } 1508 }
1509 1509
1510 1510
1731 static void read_cb(gpointer data, gint source, PurpleInputCondition cond) { 1731 static void read_cb(gpointer data, gint source, PurpleInputCondition cond) {
1732 struct mwPurplePluginData *pd = data; 1732 struct mwPurplePluginData *pd = data;
1733 int ret = 0, err = 0; 1733 int ret = 0, err = 0;
1734 1734
1735 g_return_if_fail(pd != NULL); 1735 g_return_if_fail(pd != NULL);
1736 1736
1737 ret = read_recv(pd->session, pd->socket); 1737 ret = read_recv(pd->session, pd->socket);
1738 1738
1739 /* normal operation ends here */ 1739 /* normal operation ends here */
1740 if(ret > 0) return; 1740 if(ret > 0) return;
1741 1741
1824 PurpleAccount *acct; 1824 PurpleAccount *acct;
1825 PurpleConversation *conv; 1825 PurpleConversation *conv;
1826 PurpleBuddy *buddy; 1826 PurpleBuddy *buddy;
1827 char *who = from->user_id; 1827 char *who = from->user_id;
1828 char *msg; 1828 char *msg;
1829 1829
1830 pd = mwSession_getClientData(s); 1830 pd = mwSession_getClientData(s);
1831 acct = purple_connection_get_account(pd->gc); 1831 acct = purple_connection_get_account(pd->gc);
1832 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acct); 1832 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acct);
1833 if(! conv) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, who); 1833 if(! conv) conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, who);
1834 1834
1884 1884
1885 1885
1886 static void mw_conf_invited(struct mwConference *conf, 1886 static void mw_conf_invited(struct mwConference *conf,
1887 struct mwLoginInfo *inviter, 1887 struct mwLoginInfo *inviter,
1888 const char *invitation) { 1888 const char *invitation) {
1889 1889
1890 struct mwServiceConference *srvc; 1890 struct mwServiceConference *srvc;
1891 struct mwSession *session; 1891 struct mwSession *session;
1892 struct mwPurplePluginData *pd; 1892 struct mwPurplePluginData *pd;
1893 PurpleConnection *gc; 1893 PurpleConnection *gc;
1894 1894
1941 conf_find_by_id(struct mwPurplePluginData *pd, int id) { 1941 conf_find_by_id(struct mwPurplePluginData *pd, int id) {
1942 1942
1943 struct mwServiceConference *srvc = pd->srvc_conf; 1943 struct mwServiceConference *srvc = pd->srvc_conf;
1944 struct mwConference *conf = NULL; 1944 struct mwConference *conf = NULL;
1945 GList *l, *ll; 1945 GList *l, *ll;
1946 1946
1947 ll = mwServiceConference_getConferences(srvc); 1947 ll = mwServiceConference_getConferences(srvc);
1948 for(l = ll; l; l = l->next) { 1948 for(l = ll; l; l = l->next) {
1949 struct mwConference *c = l->data; 1949 struct mwConference *c = l->data;
1950 PurpleConvChat *h = mwConference_getClientData(c); 1950 PurpleConvChat *h = mwConference_getClientData(c);
1951 1951
1953 conf = c; 1953 conf = c;
1954 break; 1954 break;
1955 } 1955 }
1956 } 1956 }
1957 g_list_free(ll); 1957 g_list_free(ll);
1958 1958
1959 return conf; 1959 return conf;
1960 } 1960 }
1961 1961
1962 1962
1963 static void mw_conf_opened(struct mwConference *conf, GList *members) { 1963 static void mw_conf_opened(struct mwConference *conf, GList *members) {
2040 } 2040 }
2041 2041
2042 2042
2043 static void mw_conf_peer_parted(struct mwConference *conf, 2043 static void mw_conf_peer_parted(struct mwConference *conf,
2044 struct mwLoginInfo *peer) { 2044 struct mwLoginInfo *peer) {
2045 2045
2046 struct mwServiceConference *srvc; 2046 struct mwServiceConference *srvc;
2047 struct mwSession *session; 2047 struct mwSession *session;
2048 struct mwPurplePluginData *pd; 2048 struct mwPurplePluginData *pd;
2049 PurpleConnection *gc; 2049 PurpleConnection *gc;
2050 PurpleConvChat *g_conf; 2050 PurpleConvChat *g_conf;
2065 } 2065 }
2066 2066
2067 2067
2068 static void mw_conf_text(struct mwConference *conf, 2068 static void mw_conf_text(struct mwConference *conf,
2069 struct mwLoginInfo *who, const char *text) { 2069 struct mwLoginInfo *who, const char *text) {
2070 2070
2071 struct mwServiceConference *srvc; 2071 struct mwServiceConference *srvc;
2072 struct mwSession *session; 2072 struct mwSession *session;
2073 struct mwPurplePluginData *pd; 2073 struct mwPurplePluginData *pd;
2074 PurpleConnection *gc; 2074 PurpleConnection *gc;
2075 char *esc; 2075 char *esc;
2139 } 2139 }
2140 2140
2141 2141
2142 static void ft_incoming_init(PurpleXfer *xfer) { 2142 static void ft_incoming_init(PurpleXfer *xfer) {
2143 /* incoming transfer accepted */ 2143 /* incoming transfer accepted */
2144 2144
2145 /* - accept the mwFileTransfer 2145 /* - accept the mwFileTransfer
2146 - open/create the local FILE "wb" 2146 - open/create the local FILE "wb"
2147 - stick the FILE's fp in xfer->dest_fp 2147 - stick the FILE's fp in xfer->dest_fp
2148 */ 2148 */
2149 2149
2220 2220
2221 xfer = mwFileTransfer_getClientData(ft); 2221 xfer = mwFileTransfer_getClientData(ft);
2222 2222
2223 rem = mwFileTransfer_getRemaining(ft); 2223 rem = mwFileTransfer_getRemaining(ft);
2224 if(rem < MW_FT_LEN) o.len = rem; 2224 if(rem < MW_FT_LEN) o.len = rem;
2225 2225
2226 if(fread(buf, (size_t) o.len, 1, fp)) { 2226 if(fread(buf, (size_t) o.len, 1, fp)) {
2227 2227
2228 /* calculate progress and display it */ 2228 /* calculate progress and display it */
2229 xfer->bytes_sent += o.len; 2229 xfer->bytes_sent += o.len;
2230 xfer->bytes_remaining -= o.len; 2230 xfer->bytes_remaining -= o.len;
2259 } 2259 }
2260 2260
2261 if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) { 2261 if(purple_xfer_get_type(xfer) == PURPLE_XFER_SEND) {
2262 xfer->dest_fp = g_fopen(xfer->local_filename, "rb"); 2262 xfer->dest_fp = g_fopen(xfer->local_filename, "rb");
2263 ft_send(ft, xfer->dest_fp); 2263 ft_send(ft, xfer->dest_fp);
2264 } 2264 }
2265 } 2265 }
2266 2266
2267 2267
2268 static void mw_ft_closed(struct mwFileTransfer *ft, guint32 code) { 2268 static void mw_ft_closed(struct mwFileTransfer *ft, guint32 code) {
2269 /* 2269 /*
2452 switch(type) { 2452 switch(type) {
2453 case mwImSend_PLAIN: 2453 case mwImSend_PLAIN:
2454 m->data = g_strdup(data); 2454 m->data = g_strdup(data);
2455 m->clear = g_free; 2455 m->clear = g_free;
2456 break; 2456 break;
2457 2457
2458 case mwImSend_TYPING: 2458 case mwImSend_TYPING:
2459 default: 2459 default:
2460 m->data = (gpointer) data; 2460 m->data = (gpointer) data;
2461 m->clear = NULL; 2461 m->clear = NULL;
2462 } 2462 }
2468 /* Does what it takes to get an error displayed for a conversation */ 2468 /* Does what it takes to get an error displayed for a conversation */
2469 static void convo_error(struct mwConversation *conv, guint32 err) { 2469 static void convo_error(struct mwConversation *conv, guint32 err) {
2470 PurpleConversation *gconv; 2470 PurpleConversation *gconv;
2471 char *tmp, *text; 2471 char *tmp, *text;
2472 struct mwIdBlock *idb; 2472 struct mwIdBlock *idb;
2473 2473
2474 idb = mwConversation_getTarget(conv); 2474 idb = mwConversation_getTarget(conv);
2475 2475
2476 tmp = mwError(err); 2476 tmp = mwError(err);
2477 text = g_strconcat(_("Unable to send message: "), tmp, NULL); 2477 text = g_strconcat(_("Unable to send message: "), tmp, NULL);
2478 2478
2479 gconv = convo_get_gconv(conv); 2479 gconv = convo_get_gconv(conv);
2480 if(gconv && !purple_conv_present_error(idb->user, gconv->account, text)) { 2480 if(gconv && !purple_conv_present_error(idb->user, gconv->account, text)) {
2481 2481
2482 g_free(text); 2482 g_free(text);
2483 text = g_strdup_printf(_("Unable to send message to %s:"), 2483 text = g_strdup_printf(_("Unable to send message to %s:"),
2484 (idb->user)? idb->user: "(unknown)"); 2484 (idb->user)? idb->user: "(unknown)");
2485 purple_notify_error(purple_account_get_connection(gconv->account), 2485 purple_notify_error(purple_account_get_connection(gconv->account),
2486 NULL, text, tmp); 2486 NULL, text, tmp);
2487 } 2487 }
2488 2488
2489 g_free(tmp); 2489 g_free(tmp);
2490 g_free(text); 2490 g_free(text);
2491 } 2491 }
2492 2492
2493 2493
2494 static void convo_queue_send(struct mwConversation *conv) { 2494 static void convo_queue_send(struct mwConversation *conv) {
2495 struct convo_data *cd; 2495 struct convo_data *cd;
2496 GList *l; 2496 GList *l;
2497 2497
2498 cd = mwConversation_getClientData(conv); 2498 cd = mwConversation_getClientData(conv);
2499 2499
2500 for(l = cd->queue; l; l = g_list_delete_link(l, l)) { 2500 for(l = cd->queue; l; l = g_list_delete_link(l, l)) {
2501 struct convo_msg *m = l->data; 2501 struct convo_msg *m = l->data;
2502 2502
2578 2578
2579 /* set up the queue */ 2579 /* set up the queue */
2580 cd = mwConversation_getClientData(conv); 2580 cd = mwConversation_getClientData(conv);
2581 if(cd) { 2581 if(cd) {
2582 convo_queue_send(conv); 2582 convo_queue_send(conv);
2583 2583
2584 if(! convo_get_gconv(conv)) { 2584 if(! convo_get_gconv(conv)) {
2585 mwConversation_free(conv); 2585 mwConversation_free(conv);
2586 return; 2586 return;
2587 } 2587 }
2588 2588
2592 2592
2593 { /* record the client key for the buddy */ 2593 { /* record the client key for the buddy */
2594 PurpleBuddy *buddy; 2594 PurpleBuddy *buddy;
2595 struct mwLoginInfo *info; 2595 struct mwLoginInfo *info;
2596 info = mwConversation_getTargetInfo(conv); 2596 info = mwConversation_getTargetInfo(conv);
2597 2597
2598 buddy = purple_find_buddy(acct, info->user_id); 2598 buddy = purple_find_buddy(acct, info->user_id);
2599 if(buddy) { 2599 if(buddy) {
2600 purple_blist_node_set_int((PurpleBlistNode *) buddy, 2600 purple_blist_node_set_int((PurpleBlistNode *) buddy,
2601 BUDDY_KEY_CLIENT, info->type); 2601 BUDDY_KEY_CLIENT, info->type);
2602 } 2602 }
2739 img_by_cid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); 2739 img_by_cid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
2740 images = NULL; 2740 images = NULL;
2741 2741
2742 /* don't want the contained string to ever be NULL */ 2742 /* don't want the contained string to ever be NULL */
2743 str = g_string_new(""); 2743 str = g_string_new("");
2744 2744
2745 doc = purple_mime_document_parse(data); 2745 doc = purple_mime_document_parse(data);
2746 2746
2747 /* handle all the MIME parts */ 2747 /* handle all the MIME parts */
2748 parts = purple_mime_document_get_parts(doc); 2748 parts = purple_mime_document_get_parts(doc);
2749 for(; parts; parts = parts->next) { 2749 for(; parts; parts = parts->next) {
2753 type = purple_mime_part_get_field(part, "content-type"); 2753 type = purple_mime_part_get_field(part, "content-type");
2754 DEBUG_INFO("MIME part Content-Type: %s\n", NSTR(type)); 2754 DEBUG_INFO("MIME part Content-Type: %s\n", NSTR(type));
2755 2755
2756 if(! type) { 2756 if(! type) {
2757 ; /* feh */ 2757 ; /* feh */
2758 2758
2759 } else if(purple_str_has_prefix(type, "image")) { 2759 } else if(purple_str_has_prefix(type, "image")) {
2760 /* put images into the image store */ 2760 /* put images into the image store */
2761 2761
2762 guchar *d_dat; 2762 guchar *d_dat;
2763 gsize d_len; 2763 gsize d_len;
2764 char *cid; 2764 char *cid;
2765 int img; 2765 int img;
2766 2766
2767 /* obtain and unencode the data */ 2767 /* obtain and unencode the data */
2768 purple_mime_part_get_data_decoded(part, &d_dat, &d_len); 2768 purple_mime_part_get_data_decoded(part, &d_dat, &d_len);
2769 2769
2770 /* look up the content id */ 2770 /* look up the content id */
2771 cid = (char *) purple_mime_part_get_field(part, "Content-ID"); 2771 cid = (char *) purple_mime_part_get_field(part, "Content-ID");
2772 cid = make_cid(cid); 2772 cid = make_cid(cid);
2773 2773
2774 /* add image to the purple image store */ 2774 /* add image to the purple image store */
2777 /* map the cid to the image store identifier */ 2777 /* map the cid to the image store identifier */
2778 g_hash_table_insert(img_by_cid, cid, GINT_TO_POINTER(img)); 2778 g_hash_table_insert(img_by_cid, cid, GINT_TO_POINTER(img));
2779 2779
2780 /* recall the image for dereferencing later */ 2780 /* recall the image for dereferencing later */
2781 images = g_list_append(images, GINT_TO_POINTER(img)); 2781 images = g_list_append(images, GINT_TO_POINTER(img));
2782 2782
2783 } else if(purple_str_has_prefix(type, "text")) { 2783 } else if(purple_str_has_prefix(type, "text")) {
2784 2784
2785 /* concatenate all the text parts together */ 2785 /* concatenate all the text parts together */
2786 guchar *data; 2786 guchar *data;
2787 gsize len; 2787 gsize len;
2788 2788
2789 purple_mime_part_get_data_decoded(part, &data, &len); 2789 purple_mime_part_get_data_decoded(part, &data, &len);
2790 g_string_append(str, (const char *)data); 2790 g_string_append(str, (const char *)data);
2791 g_free(data); 2791 g_free(data);
2792 } 2792 }
2793 } 2793 }
2794 2794
2795 purple_mime_document_free(doc); 2795 purple_mime_document_free(doc);
2796 2796
2797 /* @todo should put this in its own function */ 2797 /* @todo should put this in its own function */
2798 { /* replace each IMG tag's SRC attribute with an ID attribute. This 2798 { /* replace each IMG tag's SRC attribute with an ID attribute. This
2837 } 2837 }
2838 2838
2839 im_recv_html(conv, pd, str->str); 2839 im_recv_html(conv, pd, str->str);
2840 2840
2841 g_string_free(str, TRUE); 2841 g_string_free(str, TRUE);
2842 2842
2843 /* clean up the cid table */ 2843 /* clean up the cid table */
2844 g_hash_table_destroy(img_by_cid); 2844 g_hash_table_destroy(img_by_cid);
2845 2845
2846 /* dereference all the imgages */ 2846 /* dereference all the imgages */
2847 while(images) { 2847 while(images) {
2903 srvc = mwConversation_getService(conv); 2903 srvc = mwConversation_getService(conv);
2904 session = mwService_getSession(MW_SERVICE(srvc)); 2904 session = mwService_getSession(MW_SERVICE(srvc));
2905 pd = mwSession_getClientData(session); 2905 pd = mwSession_getClientData(session);
2906 2906
2907 idb = mwConversation_getTarget(conv); 2907 idb = mwConversation_getTarget(conv);
2908 2908
2909 ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); 2909 ht = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free);
2910 g_hash_table_insert(ht, CHAT_KEY_CREATOR, g_strdup(idb->user)); 2910 g_hash_table_insert(ht, CHAT_KEY_CREATOR, g_strdup(idb->user));
2911 g_hash_table_insert(ht, CHAT_KEY_NAME, g_strdup(name)); 2911 g_hash_table_insert(ht, CHAT_KEY_NAME, g_strdup(name));
2912 g_hash_table_insert(ht, CHAT_KEY_TOPIC, g_strdup(title)); 2912 g_hash_table_insert(ht, CHAT_KEY_TOPIC, g_strdup(title));
2913 g_hash_table_insert(ht, CHAT_KEY_INVITE, g_strdup(message)); 2913 g_hash_table_insert(ht, CHAT_KEY_INVITE, g_strdup(message));
3244 } 3244 }
3245 3245
3246 3246
3247 static const char* mw_prpl_list_emblem(PurpleBuddy *b) 3247 static const char* mw_prpl_list_emblem(PurpleBuddy *b)
3248 { 3248 {
3249 if(buddy_is_external(b)) 3249 if(buddy_is_external(b))
3250 return "external"; 3250 return "external";
3251 3251
3252 return NULL; 3252 return NULL;
3253 } 3253 }
3254 3254
3290 3290
3291 3291
3292 static char *user_supports_text(struct mwServiceAware *srvc, const char *who) { 3292 static char *user_supports_text(struct mwServiceAware *srvc, const char *who) {
3293 const char *feat[] = {NULL, NULL, NULL, NULL, NULL}; 3293 const char *feat[] = {NULL, NULL, NULL, NULL, NULL};
3294 const char **f = feat; 3294 const char **f = feat;
3295 3295
3296 if(user_supports(srvc, who, mwAttribute_AV_PREFS_SET)) { 3296 if(user_supports(srvc, who, mwAttribute_AV_PREFS_SET)) {
3297 gboolean mic, speak, video; 3297 gboolean mic, speak, video;
3298 3298
3299 mic = user_supports(srvc, who, mwAttribute_MICROPHONE); 3299 mic = user_supports(srvc, who, mwAttribute_MICROPHONE);
3300 speak = user_supports(srvc, who, mwAttribute_SPEAKERS); 3300 speak = user_supports(srvc, who, mwAttribute_SPEAKERS);
3301 video = user_supports(srvc, who, mwAttribute_VIDEO_CAMERA); 3301 video = user_supports(srvc, who, mwAttribute_VIDEO_CAMERA);
3302 3302
3303 if(mic) *f++ = _("Microphone"); 3303 if(mic) *f++ = _("Microphone");
3304 if(speak) *f++ = _("Speakers"); 3304 if(speak) *f++ = _("Speakers");
3305 if(video) *f++ = _("Video Camera"); 3305 if(video) *f++ = _("Video Camera");
3306 } 3306 }
3307 3307
3308 if(user_supports(srvc, who, mwAttribute_FILE_TRANSFER)) 3308 if(user_supports(srvc, who, mwAttribute_FILE_TRANSFER))
3309 *f++ = _("File Transfer"); 3309 *f++ = _("File Transfer");
3310 3310
3311 return (*feat)? g_strjoinv(", ", (char **)feat): NULL; 3311 return (*feat)? g_strjoinv(", ", (char **)feat): NULL;
3312 /* jenni loves siege */ 3312 /* jenni loves siege */
3313 } 3313 }
3314 3314
3315 3315
3429 PurpleConnection *gc; 3429 PurpleConnection *gc;
3430 3430
3431 const char *msgA; 3431 const char *msgA;
3432 const char *msgB; 3432 const char *msgB;
3433 char *msg1; 3433 char *msg1;
3434 3434
3435 g_return_if_fail(buddy != NULL); 3435 g_return_if_fail(buddy != NULL);
3436 3436
3437 acct = purple_buddy_get_account(buddy); 3437 acct = purple_buddy_get_account(buddy);
3438 g_return_if_fail(acct != NULL); 3438 g_return_if_fail(acct != NULL);
3439 3439
3440 gc = purple_account_get_connection(acct); 3440 gc = purple_account_get_connection(acct);
3441 g_return_if_fail(gc != NULL); 3441 g_return_if_fail(gc != NULL);
3442 3442
3443 fields = purple_request_fields_new(); 3443 fields = purple_request_fields_new();
3444 3444
3445 g = purple_request_field_group_new(NULL); 3445 g = purple_request_field_group_new(NULL);
3446 purple_request_fields_add_group(fields, g); 3446 purple_request_fields_add_group(fields, g);
3447 3447
3448 f = purple_request_field_string_new(CHAT_KEY_TOPIC, _("Topic"), NULL, FALSE); 3448 f = purple_request_field_string_new(CHAT_KEY_TOPIC, _("Topic"), NULL, FALSE);
3449 purple_request_field_group_add_field(g, f); 3449 purple_request_field_group_add_field(g, f);
3450 3450
3451 f = purple_request_field_string_new(CHAT_KEY_INVITE, _("Message"), msg, FALSE); 3451 f = purple_request_field_string_new(CHAT_KEY_INVITE, _("Message"), msg, FALSE);
3452 purple_request_field_group_add_field(g, f); 3452 purple_request_field_group_add_field(g, f);
3453 3453
3454 msgA = _("Create conference with user"); 3454 msgA = _("Create conference with user");
3455 msgB = _("Please enter a topic for the new conference, and an invitation" 3455 msgB = _("Please enter a topic for the new conference, and an invitation"
3456 " message to be sent to %s"); 3456 " message to be sent to %s");
3457 msg1 = g_strdup_printf(msgB, purple_buddy_get_name(buddy)); 3457 msg1 = g_strdup_printf(msgB, purple_buddy_get_name(buddy));
3458 3458
3475 static void conf_select_prompt_invite(PurpleBuddy *buddy, 3475 static void conf_select_prompt_invite(PurpleBuddy *buddy,
3476 PurpleRequestFields *fields) { 3476 PurpleRequestFields *fields) {
3477 PurpleRequestField *f; 3477 PurpleRequestField *f;
3478 GList *l; 3478 GList *l;
3479 const char *msg; 3479 const char *msg;
3480 3480
3481 f = purple_request_fields_get_field(fields, CHAT_KEY_INVITE); 3481 f = purple_request_fields_get_field(fields, CHAT_KEY_INVITE);
3482 msg = purple_request_field_string_get_value(f); 3482 msg = purple_request_field_string_get_value(f);
3483 3483
3484 f = purple_request_fields_get_field(fields, "conf"); 3484 f = purple_request_fields_get_field(fields, "conf");
3485 l = purple_request_field_list_get_selected(f); 3485 l = purple_request_field_list_get_selected(f);
3486 3486
3487 if(l) { 3487 if(l) {
3488 gpointer d = purple_request_field_list_get_data(f, l->data); 3488 gpointer d = purple_request_field_list_get_data(f, l->data);
3489 3489
3490 if(GPOINTER_TO_INT(d) == 0x01) { 3490 if(GPOINTER_TO_INT(d) == 0x01) {
3491 blist_menu_conf_create(buddy, msg); 3491 blist_menu_conf_create(buddy, msg);
3492 3492
3493 } else { 3493 } else {
3494 struct mwIdBlock idb = { (char *)purple_buddy_get_name(buddy), NULL }; 3494 struct mwIdBlock idb = { (char *)purple_buddy_get_name(buddy), NULL };
3498 } 3498 }
3499 3499
3500 3500
3501 static void blist_menu_conf_list(PurpleBuddy *buddy, 3501 static void blist_menu_conf_list(PurpleBuddy *buddy,
3502 GList *confs) { 3502 GList *confs) {
3503 3503
3504 PurpleRequestFields *fields; 3504 PurpleRequestFields *fields;
3505 PurpleRequestFieldGroup *g; 3505 PurpleRequestFieldGroup *g;
3506 PurpleRequestField *f; 3506 PurpleRequestField *f;
3507 3507
3508 PurpleAccount *acct; 3508 PurpleAccount *acct;
3517 3517
3518 gc = purple_account_get_connection(acct); 3518 gc = purple_account_get_connection(acct);
3519 g_return_if_fail(gc != NULL); 3519 g_return_if_fail(gc != NULL);
3520 3520
3521 fields = purple_request_fields_new(); 3521 fields = purple_request_fields_new();
3522 3522
3523 g = purple_request_field_group_new(NULL); 3523 g = purple_request_field_group_new(NULL);
3524 purple_request_fields_add_group(fields, g); 3524 purple_request_fields_add_group(fields, g);
3525 3525
3526 f = purple_request_field_list_new("conf", _("Available Conferences")); 3526 f = purple_request_field_list_new("conf", _("Available Conferences"));
3527 purple_request_field_list_set_multi_select(f, FALSE); 3527 purple_request_field_list_set_multi_select(f, FALSE);
3530 purple_request_field_list_add_icon(f, mwConference_getTitle(c), NULL, c); 3530 purple_request_field_list_add_icon(f, mwConference_getTitle(c), NULL, c);
3531 } 3531 }
3532 purple_request_field_list_add_icon(f, _("Create New Conference..."), 3532 purple_request_field_list_add_icon(f, _("Create New Conference..."),
3533 NULL, GINT_TO_POINTER(0x01)); 3533 NULL, GINT_TO_POINTER(0x01));
3534 purple_request_field_group_add_field(g, f); 3534 purple_request_field_group_add_field(g, f);
3535 3535
3536 f = purple_request_field_string_new(CHAT_KEY_INVITE, "Message", NULL, FALSE); 3536 f = purple_request_field_string_new(CHAT_KEY_INVITE, "Message", NULL, FALSE);
3537 purple_request_field_group_add_field(g, f); 3537 purple_request_field_group_add_field(g, f);
3538 3538
3539 msgA = _("Invite user to a conference"); 3539 msgA = _("Invite user to a conference");
3540 msgB = _("Select a conference from the list below to send an invite to" 3540 msgB = _("Select a conference from the list below to send an invite to"
3541 " user %s. Select \"Create New Conference\" if you'd like to" 3541 " user %s. Select \"Create New Conference\" if you'd like to"
3542 " create a new conference to invite this user to."); 3542 " create a new conference to invite this user to.");
3543 msg = g_strdup_printf(msgB, purple_buddy_get_name(buddy)); 3543 msg = g_strdup_printf(msgB, purple_buddy_get_name(buddy));
3653 3653
3654 3654
3655 static GList *mw_prpl_chat_info(PurpleConnection *gc) { 3655 static GList *mw_prpl_chat_info(PurpleConnection *gc) {
3656 GList *l = NULL; 3656 GList *l = NULL;
3657 struct proto_chat_entry *pce; 3657 struct proto_chat_entry *pce;
3658 3658
3659 pce = g_new0(struct proto_chat_entry, 1); 3659 pce = g_new0(struct proto_chat_entry, 1);
3660 pce->label = _("Topic:"); 3660 pce->label = _("Topic:");
3661 pce->identifier = CHAT_KEY_TOPIC; 3661 pce->identifier = CHAT_KEY_TOPIC;
3662 l = g_list_append(l, pce); 3662 l = g_list_append(l, pce);
3663 3663
3664 return l; 3664 return l;
3665 } 3665 }
3666 3666
3667 3667
3668 static GHashTable *mw_prpl_chat_info_defaults(PurpleConnection *gc, 3668 static GHashTable *mw_prpl_chat_info_defaults(PurpleConnection *gc,
3706 3706
3707 static void prompt_host(PurpleConnection *gc) { 3707 static void prompt_host(PurpleConnection *gc) {
3708 PurpleAccount *acct; 3708 PurpleAccount *acct;
3709 const char *msgA; 3709 const char *msgA;
3710 char *msg; 3710 char *msg;
3711 3711
3712 acct = purple_connection_get_account(gc); 3712 acct = purple_connection_get_account(gc);
3713 msgA = _("No host or IP address has been configured for the" 3713 msgA = _("No host or IP address has been configured for the"
3714 " Meanwhile account %s. Please enter one below to" 3714 " Meanwhile account %s. Please enter one below to"
3715 " continue logging in."); 3715 " continue logging in.");
3716 msg = g_strdup_printf(msgA, NSTR(purple_account_get_username(acct))); 3716 msg = g_strdup_printf(msgA, NSTR(purple_account_get_username(acct)));
3717 3717
3718 purple_request_input(gc, _("Meanwhile Connection Setup"), 3718 purple_request_input(gc, _("Meanwhile Connection Setup"),
3719 _("No Sametime Community Server Specified"), msg, 3719 _("No Sametime Community Server Specified"), msg,
3720 MW_PLUGIN_DEFAULT_HOST, FALSE, FALSE, NULL, 3720 MW_PLUGIN_DEFAULT_HOST, FALSE, FALSE, NULL,
3721 _("Connect"), G_CALLBACK(prompt_host_ok_cb), 3721 _("Connect"), G_CALLBACK(prompt_host_ok_cb),
3722 _("Cancel"), G_CALLBACK(prompt_host_cancel_cb), 3722 _("Cancel"), G_CALLBACK(prompt_host_cancel_cb),
3746 if(host) { 3746 if(host) {
3747 /* annoying user split from 1.2.0, need to undo it */ 3747 /* annoying user split from 1.2.0, need to undo it */
3748 *host++ = '\0'; 3748 *host++ = '\0';
3749 purple_account_set_string(account, MW_KEY_HOST, host); 3749 purple_account_set_string(account, MW_KEY_HOST, host);
3750 purple_account_set_username(account, user); 3750 purple_account_set_username(account, user);
3751 3751
3752 } else { 3752 } else {
3753 host = (char *) purple_account_get_string(account, MW_KEY_HOST, 3753 host = (char *) purple_account_get_string(account, MW_KEY_HOST,
3754 MW_PLUGIN_DEFAULT_HOST); 3754 MW_PLUGIN_DEFAULT_HOST);
3755 } 3755 }
3756 3756
3785 minor = purple_account_get_int(account, MW_KEY_MINOR, 0x196f); 3785 minor = purple_account_get_int(account, MW_KEY_MINOR, 0x196f);
3786 3786
3787 DEBUG_INFO("client id: 0x%04x\n", client); 3787 DEBUG_INFO("client id: 0x%04x\n", client);
3788 DEBUG_INFO("client major: 0x%04x\n", major); 3788 DEBUG_INFO("client major: 0x%04x\n", major);
3789 DEBUG_INFO("client minor: 0x%04x\n", minor); 3789 DEBUG_INFO("client minor: 0x%04x\n", minor);
3790 3790
3791 mwSession_setProperty(pd->session, mwSession_CLIENT_TYPE_ID, 3791 mwSession_setProperty(pd->session, mwSession_CLIENT_TYPE_ID,
3792 GUINT_TO_POINTER(client), NULL); 3792 GUINT_TO_POINTER(client), NULL);
3793 3793
3794 mwSession_setProperty(pd->session, mwSession_CLIENT_VER_MAJOR, 3794 mwSession_setProperty(pd->session, mwSession_CLIENT_VER_MAJOR,
3795 GUINT_TO_POINTER(major), NULL); 3795 GUINT_TO_POINTER(major), NULL);
3796 3796
3797 mwSession_setProperty(pd->session, mwSession_CLIENT_VER_MINOR, 3797 mwSession_setProperty(pd->session, mwSession_CLIENT_VER_MINOR,
3798 GUINT_TO_POINTER(minor), NULL); 3798 GUINT_TO_POINTER(minor), NULL);
3926 tmp = (char *) message; 3926 tmp = (char *) message;
3927 while(*tmp && purple_markup_find_tag("img", tmp, (const char **) &start, 3927 while(*tmp && purple_markup_find_tag("img", tmp, (const char **) &start,
3928 (const char **) &end, &attr)) { 3928 (const char **) &end, &attr)) {
3929 char *id; 3929 char *id;
3930 PurpleStoredImage *img = NULL; 3930 PurpleStoredImage *img = NULL;
3931 3931
3932 gsize len = (start - tmp); 3932 gsize len = (start - tmp);
3933 3933
3934 /* append the in-between-tags text */ 3934 /* append the in-between-tags text */
3935 if(len) g_string_append_len(str, tmp, len); 3935 if(len) g_string_append_len(str, tmp, len);
3936 3936
3969 g_free(data); 3969 g_free(data);
3970 3970
3971 /* append the modified tag */ 3971 /* append the modified tag */
3972 g_string_append_printf(str, "<img src=\"cid:%s\">", cid); 3972 g_string_append_printf(str, "<img src=\"cid:%s\">", cid);
3973 g_free(cid); 3973 g_free(cid);
3974 3974
3975 } else { 3975 } else {
3976 /* append the literal image tag, since we couldn't find a 3976 /* append the literal image tag, since we couldn't find a
3977 relative imgstore object */ 3977 relative imgstore object */
3978 gsize len = (end - start) + 1; 3978 gsize len = (end - start) + 1;
3979 g_string_append_len(str, start, len); 3979 g_string_append_len(str, start, len);
4043 /* send a MIME message */ 4043 /* send a MIME message */
4044 4044
4045 tmp = im_mime_convert(gc, conv, message); 4045 tmp = im_mime_convert(gc, conv, message);
4046 ret = mwConversation_send(conv, mwImSend_MIME, tmp); 4046 ret = mwConversation_send(conv, mwImSend_MIME, tmp);
4047 g_free(tmp); 4047 g_free(tmp);
4048 4048
4049 } else if(mwConversation_supports(conv, mwImSend_HTML)) { 4049 } else if(mwConversation_supports(conv, mwImSend_HTML)) {
4050 /* send an HTML message */ 4050 /* send an HTML message */
4051 4051
4052 char *ncr; 4052 char *ncr;
4053 ncr = purple_utf8_ncr_encode(message); 4053 ncr = purple_utf8_ncr_encode(message);
4061 /* default to text */ 4061 /* default to text */
4062 tmp = purple_markup_strip_html(message); 4062 tmp = purple_markup_strip_html(message);
4063 ret = mwConversation_send(conv, mwImSend_PLAIN, tmp); 4063 ret = mwConversation_send(conv, mwImSend_PLAIN, tmp);
4064 g_free(tmp); 4064 g_free(tmp);
4065 } 4065 }
4066 4066
4067 return !ret; 4067 return !ret;
4068 4068
4069 } else { 4069 } else {
4070 4070
4071 /* queue up the message safely as plain text */ 4071 /* queue up the message safely as plain text */
4082 4082
4083 4083
4084 static unsigned int mw_prpl_send_typing(PurpleConnection *gc, 4084 static unsigned int mw_prpl_send_typing(PurpleConnection *gc,
4085 const char *name, 4085 const char *name,
4086 PurpleTypingState state) { 4086 PurpleTypingState state) {
4087 4087
4088 struct mwPurplePluginData *pd; 4088 struct mwPurplePluginData *pd;
4089 struct mwIdBlock who = { (char *) name, NULL }; 4089 struct mwIdBlock who = { (char *) name, NULL };
4090 struct mwConversation *conv; 4090 struct mwConversation *conv;
4091 4091
4092 gpointer t = GINT_TO_POINTER(!! state); 4092 gpointer t = GINT_TO_POINTER(!! state);
4098 4098
4099 conv = mwServiceIm_getConversation(pd->srvc_im, &who); 4099 conv = mwServiceIm_getConversation(pd->srvc_im, &who);
4100 4100
4101 if(mwConversation_isOpen(conv)) { 4101 if(mwConversation_isOpen(conv)) {
4102 mwConversation_send(conv, mwImSend_TYPING, t); 4102 mwConversation_send(conv, mwImSend_TYPING, t);
4103 4103
4104 } else if((state == PURPLE_TYPING) || (state == PURPLE_TYPED)) { 4104 } else if((state == PURPLE_TYPING) || (state == PURPLE_TYPED)) {
4105 /* only open a channel for sending typing notification, not for 4105 /* only open a channel for sending typing notification, not for
4106 when typing has stopped. There's no point in re-opening a 4106 when typing has stopped. There's no point in re-opening a
4107 channel just to tell someone that this side isn't typing. */ 4107 channel just to tell someone that this side isn't typing. */
4108 4108
4109 convo_queue(conv, mwImSend_TYPING, t); 4109 convo_queue(conv, mwImSend_TYPING, t);
4110 4110
4111 if(! mwConversation_isPending(conv)) { 4111 if(! mwConversation_isPending(conv)) {
4112 mwConversation_open(conv); 4112 mwConversation_open(conv);
4113 } 4113 }
4114 } 4114 }
4115 4115
4119 4119
4120 static const char *mw_client_name(guint16 type) { 4120 static const char *mw_client_name(guint16 type) {
4121 switch(type) { 4121 switch(type) {
4122 case mwLogin_LIB: 4122 case mwLogin_LIB:
4123 return "Lotus Binary Library"; 4123 return "Lotus Binary Library";
4124 4124
4125 case mwLogin_JAVA_WEB: 4125 case mwLogin_JAVA_WEB:
4126 return "Lotus Java Client Applet"; 4126 return "Lotus Java Client Applet";
4127 4127
4128 case mwLogin_BINARY: 4128 case mwLogin_BINARY:
4129 return "Lotus Sametime Connect"; 4129 return "Lotus Sametime Connect";
4212 tmp = g_strdup(mw_client_name(type)); 4212 tmp = g_strdup(mw_client_name(type));
4213 if (!tmp) 4213 if (!tmp)
4214 tmp = g_strdup_printf(_("Unknown (0x%04x)<br>"), type); 4214 tmp = g_strdup_printf(_("Unknown (0x%04x)<br>"), type);
4215 4215
4216 purple_notify_user_info_add_pair(user_info, _("Last Known Client"), tmp); 4216 purple_notify_user_info_add_pair(user_info, _("Last Known Client"), tmp);
4217 4217
4218 g_free(tmp); 4218 g_free(tmp);
4219 } 4219 }
4220 } 4220 }
4221 4221
4222 tmp = user_supports_text(pd->srvc_aware, who); 4222 tmp = user_supports_text(pd->srvc_aware, who);
4223 if(tmp) { 4223 if(tmp) {
4224 purple_notify_user_info_add_pair(user_info, _("Supports"), tmp); 4224 purple_notify_user_info_add_pair(user_info, _("Supports"), tmp);
4225 g_free(tmp); 4225 g_free(tmp);
4226 } 4226 }
4242 this notification, so that it can create its own */ 4242 this notification, so that it can create its own */
4243 4243
4244 purple_notify_userinfo(gc, who, user_info, NULL, NULL); 4244 purple_notify_userinfo(gc, who, user_info, NULL, NULL);
4245 purple_notify_user_info_destroy(user_info); 4245 purple_notify_user_info_destroy(user_info);
4246 } 4246 }
4247 4247
4248 4248
4249 static void mw_prpl_set_status(PurpleAccount *acct, PurpleStatus *status) { 4249 static void mw_prpl_set_status(PurpleAccount *acct, PurpleStatus *status) {
4250 PurpleConnection *gc; 4250 PurpleConnection *gc;
4251 const char *state; 4251 const char *state;
4252 char *message = NULL; 4252 char *message = NULL;
4253 struct mwSession *session; 4253 struct mwSession *session;
4254 struct mwUserStatus stat; 4254 struct mwUserStatus stat;
4255 4255
4256 g_return_if_fail(acct != NULL); 4256 g_return_if_fail(acct != NULL);
4257 gc = purple_account_get_connection(acct); 4257 gc = purple_account_get_connection(acct);
4258 4258
4259 state = purple_status_get_id(status); 4259 state = purple_status_get_id(status);
4260 4260
4261 DEBUG_INFO("Set status to %s\n", purple_status_get_name(status)); 4261 DEBUG_INFO("Set status to %s\n", purple_status_get_name(status));
4262 4262
4263 g_return_if_fail(gc != NULL); 4263 g_return_if_fail(gc != NULL);
4264 4264
4265 session = gc_to_session(gc); 4265 session = gc_to_session(gc);
4266 g_return_if_fail(session != NULL); 4266 g_return_if_fail(session != NULL);
4267 4267
4268 /* get a working copy of the current status */ 4268 /* get a working copy of the current status */
4269 mwUserStatus_clone(&stat, mwSession_getUserStatus(session)); 4269 mwUserStatus_clone(&stat, mwSession_getUserStatus(session));
4270 4270
4271 /* determine the state */ 4271 /* determine the state */
4272 if(! strcmp(state, MW_STATE_ACTIVE)) { 4272 if(! strcmp(state, MW_STATE_ACTIVE)) {
4273 stat.status = mwStatus_ACTIVE; 4273 stat.status = mwStatus_ACTIVE;
4274 4274
4275 } else if(! strcmp(state, MW_STATE_AWAY)) { 4275 } else if(! strcmp(state, MW_STATE_AWAY)) {
4276 stat.status = mwStatus_AWAY; 4276 stat.status = mwStatus_AWAY;
4277 4277
4278 } else if(! strcmp(state, MW_STATE_BUSY)) { 4278 } else if(! strcmp(state, MW_STATE_BUSY)) {
4279 stat.status = mwStatus_BUSY; 4279 stat.status = mwStatus_BUSY;
4280 } 4280 }
4281 4281
4282 /* determine the message */ 4282 /* determine the message */
4283 message = (char *) purple_status_get_attr_string(status, MW_STATE_MESSAGE); 4283 message = (char *) purple_status_get_attr_string(status, MW_STATE_MESSAGE);
4284 4284
4285 if(message) { 4285 if(message) {
4286 /* all the possible non-NULL values of message up to this point 4286 /* all the possible non-NULL values of message up to this point
4287 are const, so we don't need to free them */ 4287 are const, so we don't need to free them */
4288 message = purple_markup_strip_html(message); 4288 message = purple_markup_strip_html(message);
4289 } 4289 }
4290 4290
4291 /* out with the old */ 4291 /* out with the old */
4292 g_free(stat.desc); 4292 g_free(stat.desc);
4293 4293
4294 /* in with the new */ 4294 /* in with the new */
4295 stat.desc = (char *) message; 4295 stat.desc = (char *) message;
4296 4296
4297 mwSession_setUserStatus(session, &stat); 4297 mwSession_setUserStatus(session, &stat);
4298 mwUserStatus_clear(&stat); 4298 mwUserStatus_clear(&stat);
4299 } 4299 }
4300 4300
4301 4301
4302 static void mw_prpl_set_idle(PurpleConnection *gc, int t) { 4302 static void mw_prpl_set_idle(PurpleConnection *gc, int t) {
4303 struct mwSession *session; 4303 struct mwSession *session;
4304 struct mwUserStatus stat; 4304 struct mwUserStatus stat;
4305 4305
4306 4306
4307 session = gc_to_session(gc); 4307 session = gc_to_session(gc);
4308 g_return_if_fail(session != NULL); 4308 g_return_if_fail(session != NULL);
4309 4309
4310 mwUserStatus_clone(&stat, mwSession_getUserStatus(session)); 4310 mwUserStatus_clone(&stat, mwSession_getUserStatus(session));
4345 4345
4346 4346
4347 static void notify_add(PurpleConnection *gc, GList *row, void *user_data) { 4347 static void notify_add(PurpleConnection *gc, GList *row, void *user_data) {
4348 BuddyAddData *data = user_data; 4348 BuddyAddData *data = user_data;
4349 const char *group_name = NULL; 4349 const char *group_name = NULL;
4350 4350
4351 if (data && data->group) { 4351 if (data && data->group) {
4352 group_name = purple_group_get_name(data->group); 4352 group_name = purple_group_get_name(data->group);
4353 } 4353 }
4354 4354
4355 purple_blist_request_add_buddy(purple_connection_get_account(gc), 4355 purple_blist_request_add_buddy(purple_connection_get_account(gc),
4390 notify_add); 4390 notify_add);
4391 4391
4392 for(l = result->matches; l; l = l->next) { 4392 for(l = result->matches; l; l = l->next) {
4393 struct mwResolveMatch *match = l->data; 4393 struct mwResolveMatch *match = l->data;
4394 GList *row = NULL; 4394 GList *row = NULL;
4395 4395
4396 DEBUG_INFO("multi resolve: %s, %s\n", 4396 DEBUG_INFO("multi resolve: %s, %s\n",
4397 NSTR(match->id), NSTR(match->name)); 4397 NSTR(match->id), NSTR(match->name));
4398 4398
4399 if(!match->id || !match->name) 4399 if(!match->id || !match->name)
4400 continue; 4400 continue;
4401 4401
4402 row = g_list_append(row, g_strdup(match->name)); 4402 row = g_list_append(row, g_strdup(match->name));
4403 row = g_list_append(row, g_strdup(match->id)); 4403 row = g_list_append(row, g_strdup(match->id));
4404 purple_notify_searchresults_row_add(sres, row); 4404 purple_notify_searchresults_row_add(sres, row);
4405 } 4405 }
4406 4406
4438 res = results->data; 4438 res = results->data;
4439 4439
4440 if(!code && res && res->matches) { 4440 if(!code && res && res->matches) {
4441 if(!res->matches->next) { 4441 if(!res->matches->next) {
4442 struct mwResolveMatch *match = res->matches->data; 4442 struct mwResolveMatch *match = res->matches->data;
4443 4443
4444 /* only one? that might be the right one! */ 4444 /* only one? that might be the right one! */
4445 if(strcmp(res->name, match->id)) { 4445 if(strcmp(res->name, match->id)) {
4446 /* uh oh, the single result isn't identical to the search 4446 /* uh oh, the single result isn't identical to the search
4447 term, better safe then sorry, so let's make sure it's who 4447 term, better safe then sorry, so let's make sure it's who
4448 the user meant to add */ 4448 the user meant to add */
4449 purple_blist_remove_buddy(buddy); 4449 purple_blist_remove_buddy(buddy);
4450 multi_resolved_query(res, gc, data); 4450 multi_resolved_query(res, gc, data);
4451 4451
4452 } else { 4452 } else {
4453 4453
4454 /* same person, set the server alias */ 4454 /* same person, set the server alias */
4455 purple_blist_server_alias_buddy(buddy, match->name); 4455 purple_blist_server_alias_buddy(buddy, match->name);
4456 purple_blist_node_set_string((PurpleBlistNode *) buddy, 4456 purple_blist_node_set_string((PurpleBlistNode *) buddy,
4461 4461
4462 blist_schedule(pd); 4462 blist_schedule(pd);
4463 4463
4464 g_free(data); 4464 g_free(data);
4465 } 4465 }
4466 4466
4467 } else { 4467 } else {
4468 /* prompt user if more than one match was returned */ 4468 /* prompt user if more than one match was returned */
4469 purple_blist_remove_buddy(buddy); 4469 purple_blist_remove_buddy(buddy);
4470 multi_resolved_query(res, gc, data); 4470 multi_resolved_query(res, gc, data);
4471 } 4471 }
4472 4472
4473 return; 4473 return;
4474 } 4474 }
4475 4475
4476 #if 0 4476 #if 0
4477 /* fall-through indicates that we couldn't find a matching user in 4477 /* fall-through indicates that we couldn't find a matching user in
4626 } 4626 }
4627 4627
4628 4628
4629 static void privacy_fill(struct mwPrivacyInfo *priv, 4629 static void privacy_fill(struct mwPrivacyInfo *priv,
4630 GSList *members) { 4630 GSList *members) {
4631 4631
4632 struct mwUserItem *u; 4632 struct mwUserItem *u;
4633 guint count; 4633 guint count;
4634 4634
4635 count = g_slist_length(members); 4635 count = g_slist_length(members);
4636 DEBUG_INFO("privacy_fill: %u members\n", count); 4636 DEBUG_INFO("privacy_fill: %u members\n", count);
4688 4688
4689 case PURPLE_PRIVACY_DENY_ALL: 4689 case PURPLE_PRIVACY_DENY_ALL:
4690 DEBUG_INFO("PURPLE_PRIVACY_DENY_ALL\n"); 4690 DEBUG_INFO("PURPLE_PRIVACY_DENY_ALL\n");
4691 privacy.deny = FALSE; 4691 privacy.deny = FALSE;
4692 break; 4692 break;
4693 4693
4694 default: 4694 default:
4695 DEBUG_INFO("acct->perm_deny is 0x%x\n", acct->perm_deny); 4695 DEBUG_INFO("acct->perm_deny is 0x%x\n", acct->perm_deny);
4696 return; 4696 return;
4697 } 4697 }
4698 4698
4743 static void mw_prpl_join_chat(PurpleConnection *gc, 4743 static void mw_prpl_join_chat(PurpleConnection *gc,
4744 GHashTable *components) { 4744 GHashTable *components) {
4745 4745
4746 struct mwPurplePluginData *pd; 4746 struct mwPurplePluginData *pd;
4747 char *c, *t; 4747 char *c, *t;
4748 4748
4749 pd = gc->proto_data; 4749 pd = gc->proto_data;
4750 4750
4751 c = g_hash_table_lookup(components, CHAT_KEY_NAME); 4751 c = g_hash_table_lookup(components, CHAT_KEY_NAME);
4752 t = g_hash_table_lookup(components, CHAT_KEY_TOPIC); 4752 t = g_hash_table_lookup(components, CHAT_KEY_TOPIC);
4753 4753
4754 if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) { 4754 if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) {
4755 /* use place service */ 4755 /* use place service */
4756 struct mwServicePlace *srvc; 4756 struct mwServicePlace *srvc;
4757 struct mwPlace *place = NULL; 4757 struct mwPlace *place = NULL;
4758 4758
4759 srvc = pd->srvc_place; 4759 srvc = pd->srvc_place;
4760 place = mwPlace_new(srvc, c, t); 4760 place = mwPlace_new(srvc, c, t);
4761 mwPlace_open(place); 4761 mwPlace_open(place);
4762 4762
4763 } else { 4763 } else {
4764 /* use conference service */ 4764 /* use conference service */
4765 struct mwServiceConference *srvc; 4765 struct mwServiceConference *srvc;
4766 struct mwConference *conf = NULL; 4766 struct mwConference *conf = NULL;
4767 4767
4769 if(c) conf = conf_find(srvc, c); 4769 if(c) conf = conf_find(srvc, c);
4770 4770
4771 if(conf) { 4771 if(conf) {
4772 DEBUG_INFO("accepting conference invitation\n"); 4772 DEBUG_INFO("accepting conference invitation\n");
4773 mwConference_accept(conf); 4773 mwConference_accept(conf);
4774 4774
4775 } else { 4775 } else {
4776 DEBUG_INFO("creating new conference\n"); 4776 DEBUG_INFO("creating new conference\n");
4777 conf = mwConference_new(srvc, t); 4777 conf = mwConference_new(srvc, t);
4778 mwConference_open(conf); 4778 mwConference_open(conf);
4779 } 4779 }
4785 GHashTable *components) { 4785 GHashTable *components) {
4786 4786
4787 struct mwPurplePluginData *pd; 4787 struct mwPurplePluginData *pd;
4788 struct mwServiceConference *srvc; 4788 struct mwServiceConference *srvc;
4789 char *c; 4789 char *c;
4790 4790
4791 pd = gc->proto_data; 4791 pd = gc->proto_data;
4792 srvc = pd->srvc_conf; 4792 srvc = pd->srvc_conf;
4793 4793
4794 if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) { 4794 if(g_hash_table_lookup(components, CHAT_KEY_IS_PLACE)) {
4795 ; /* nothing needs doing */ 4795 ; /* nothing needs doing */
5044 pd = gc->proto_data; 5044 pd = gc->proto_data;
5045 g_return_val_if_fail(pd != NULL, FALSE); 5045 g_return_val_if_fail(pd != NULL, FALSE);
5046 5046
5047 srvc = pd->srvc_aware; 5047 srvc = pd->srvc_aware;
5048 g_return_val_if_fail(srvc != NULL, FALSE); 5048 g_return_val_if_fail(srvc != NULL, FALSE);
5049 5049
5050 acct = purple_connection_get_account(gc); 5050 acct = purple_connection_get_account(gc);
5051 g_return_val_if_fail(acct != NULL, FALSE); 5051 g_return_val_if_fail(acct != NULL, FALSE);
5052 5052
5053 return purple_find_buddy(acct, who) && 5053 return purple_find_buddy(acct, who) &&
5054 user_supports(srvc, who, mwAttribute_FILE_TRANSFER); 5054 user_supports(srvc, who, mwAttribute_FILE_TRANSFER);
5095 5095
5096 { 5096 {
5097 char *tmp = strrchr(filename, G_DIR_SEPARATOR); 5097 char *tmp = strrchr(filename, G_DIR_SEPARATOR);
5098 if(tmp++) filename = tmp; 5098 if(tmp++) filename = tmp;
5099 } 5099 }
5100 5100
5101 ft = mwFileTransfer_new(srvc, &idb, NULL, filename, filesize); 5101 ft = mwFileTransfer_new(srvc, &idb, NULL, filename, filesize);
5102 5102
5103 purple_xfer_ref(xfer); 5103 purple_xfer_ref(xfer);
5104 mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref); 5104 mwFileTransfer_setClientData(ft, xfer, (GDestroyNotify) purple_xfer_unref);
5105 xfer->data = ft; 5105 xfer->data = ft;
5108 } 5108 }
5109 5109
5110 5110
5111 static void ft_outgoing_cancel(PurpleXfer *xfer) { 5111 static void ft_outgoing_cancel(PurpleXfer *xfer) {
5112 struct mwFileTransfer *ft = xfer->data; 5112 struct mwFileTransfer *ft = xfer->data;
5113 5113
5114 DEBUG_INFO("ft_outgoing_cancel called\n"); 5114 DEBUG_INFO("ft_outgoing_cancel called\n");
5115 5115
5116 if(ft) mwFileTransfer_cancel(ft); 5116 if(ft) mwFileTransfer_cancel(ft);
5117 } 5117 }
5118 5118
5208 .send_file = mw_prpl_send_file, 5208 .send_file = mw_prpl_send_file,
5209 .new_xfer = mw_prpl_new_xfer, 5209 .new_xfer = mw_prpl_new_xfer,
5210 .offline_message = NULL, 5210 .offline_message = NULL,
5211 .whiteboard_prpl_ops = NULL, 5211 .whiteboard_prpl_ops = NULL,
5212 .send_raw = NULL, 5212 .send_raw = NULL,
5213 .struct_size = sizeof(PurplePluginProtocolInfo) 5213 .struct_size = sizeof(PurplePluginProtocolInfo)
5214 }; 5214 };
5215 5215
5216 5216
5217 static PurplePluginPrefFrame * 5217 static PurplePluginPrefFrame *
5218 mw_plugin_get_plugin_pref_frame(PurplePlugin *plugin) { 5218 mw_plugin_get_plugin_pref_frame(PurplePlugin *plugin) {
5219 PurplePluginPrefFrame *frame; 5219 PurplePluginPrefFrame *frame;
5220 PurplePluginPref *pref; 5220 PurplePluginPref *pref;
5221 5221
5222 frame = purple_plugin_pref_frame_new(); 5222 frame = purple_plugin_pref_frame_new();
5223 5223
5224 pref = purple_plugin_pref_new_with_label(_("Remotely Stored Buddy List")); 5224 pref = purple_plugin_pref_new_with_label(_("Remotely Stored Buddy List"));
5225 purple_plugin_pref_frame_add(frame, pref); 5225 purple_plugin_pref_frame_add(frame, pref);
5226 5226
5227 5227
5228 pref = purple_plugin_pref_new_with_name(MW_PRPL_OPT_BLIST_ACTION); 5228 pref = purple_plugin_pref_new_with_name(MW_PRPL_OPT_BLIST_ACTION);
5229 purple_plugin_pref_set_label(pref, _("Buddy List Storage Mode")); 5229 purple_plugin_pref_set_label(pref, _("Buddy List Storage Mode"));
5230 5230
5231 purple_plugin_pref_set_type(pref, PURPLE_PLUGIN_PREF_CHOICE); 5231 purple_plugin_pref_set_type(pref, PURPLE_PLUGIN_PREF_CHOICE);
5342 } 5342 }
5343 5343
5344 5344
5345 static void remote_group_multi_cleanup(gpointer ignore, 5345 static void remote_group_multi_cleanup(gpointer ignore,
5346 PurpleRequestFields *fields) { 5346 PurpleRequestFields *fields) {
5347 5347
5348 PurpleRequestField *f; 5348 PurpleRequestField *f;
5349 GList *l; 5349 GList *l;
5350 5350
5351 f = purple_request_fields_get_field(fields, "group"); 5351 f = purple_request_fields_get_field(fields, "group");
5352 l = purple_request_field_list_get_items(f); 5352 l = purple_request_field_list_get_items(f);
5374 5374
5375 g_return_if_fail(pd != NULL); 5375 g_return_if_fail(pd != NULL);
5376 5376
5377 gc = pd->gc; 5377 gc = pd->gc;
5378 acct = purple_connection_get_account(gc); 5378 acct = purple_connection_get_account(gc);
5379 5379
5380 /* collision checking */ 5380 /* collision checking */
5381 group = purple_find_group(name); 5381 group = purple_find_group(name);
5382 if(group) { 5382 if(group) {
5383 const char *msgA; 5383 const char *msgA;
5384 const char *msgB; 5384 const char *msgB;
5495 pd = mwSession_getClientData(session); 5495 pd = mwSession_getClientData(session);
5496 g_return_if_fail(pd != NULL); 5496 g_return_if_fail(pd != NULL);
5497 5497
5498 gc = pd->gc; 5498 gc = pd->gc;
5499 g_return_if_fail(gc != NULL); 5499 g_return_if_fail(gc != NULL);
5500 5500
5501 if(!code && results) { 5501 if(!code && results) {
5502 res = results->data; 5502 res = results->data;
5503 5503
5504 if(res->matches) { 5504 if(res->matches) {
5505 remote_group_multi(res, pd); 5505 remote_group_multi(res, pd);
5535 pd = gc->proto_data; 5535 pd = gc->proto_data;
5536 srvc = pd->srvc_resolve; 5536 srvc = pd->srvc_resolve;
5537 5537
5538 query = g_list_prepend(NULL, (char *) name); 5538 query = g_list_prepend(NULL, (char *) name);
5539 flags = mwResolveFlag_FIRST | mwResolveFlag_GROUPS; 5539 flags = mwResolveFlag_FIRST | mwResolveFlag_GROUPS;
5540 5540
5541 req = mwServiceResolve_resolve(srvc, query, flags, remote_group_resolved, 5541 req = mwServiceResolve_resolve(srvc, query, flags, remote_group_resolved,
5542 NULL, NULL); 5542 NULL, NULL);
5543 g_list_free(query); 5543 g_list_free(query);
5544 5544
5545 if(req == SEARCH_ERROR) { 5545 if(req == SEARCH_ERROR) {
5597 struct mwResolveMatch *match = l->data; 5597 struct mwResolveMatch *match = l->data;
5598 GList *row = NULL; 5598 GList *row = NULL;
5599 5599
5600 if(!match->id || !match->name) 5600 if(!match->id || !match->name)
5601 continue; 5601 continue;
5602 5602
5603 row = g_list_append(row, g_strdup(match->name)); 5603 row = g_list_append(row, g_strdup(match->name));
5604 row = g_list_append(row, g_strdup(match->id)); 5604 row = g_list_append(row, g_strdup(match->id));
5605 purple_notify_searchresults_row_add(sres, row); 5605 purple_notify_searchresults_row_add(sres, row);
5606 } 5606 }
5607 5607
5657 enum mwResolveFlag flags; 5657 enum mwResolveFlag flags;
5658 guint32 req; 5658 guint32 req;
5659 5659
5660 pd = gc->proto_data; 5660 pd = gc->proto_data;
5661 srvc = pd->srvc_resolve; 5661 srvc = pd->srvc_resolve;
5662 5662
5663 query = g_list_prepend(NULL, (char *) name); 5663 query = g_list_prepend(NULL, (char *) name);
5664 flags = mwResolveFlag_FIRST | mwResolveFlag_USERS; 5664 flags = mwResolveFlag_FIRST | mwResolveFlag_USERS;
5665 5665
5666 req = mwServiceResolve_resolve(srvc, query, flags, search_resolved, 5666 req = mwServiceResolve_resolve(srvc, query, flags, search_resolved,
5667 gc, NULL); 5667 gc, NULL);
5835 /* forward all our g_log messages to purple. Generally all the logging 5835 /* forward all our g_log messages to purple. Generally all the logging
5836 calls are using purple_log directly, but the g_return macros will 5836 calls are using purple_log directly, but the g_return macros will
5837 get caught here */ 5837 get caught here */
5838 log_handler[0] = g_log_set_handler(G_LOG_DOMAIN, logflags, 5838 log_handler[0] = g_log_set_handler(G_LOG_DOMAIN, logflags,
5839 mw_log_handler, NULL); 5839 mw_log_handler, NULL);
5840 5840
5841 /* redirect meanwhile's logging to purple's */ 5841 /* redirect meanwhile's logging to purple's */
5842 log_handler[1] = g_log_set_handler("meanwhile", logflags, 5842 log_handler[1] = g_log_set_handler("meanwhile", logflags,
5843 mw_log_handler, NULL); 5843 mw_log_handler, NULL);
5844 } 5844 }
5845 5845