comparison libpurple/buddyicon.c @ 16390:4fc51a87ce42

Updates for the account buddy icon stuff. This doesn't yet work fully (and maybe not even partly), but it compiles.
author Richard Laager <rlaager@wiktel.com>
date Wed, 25 Apr 2007 21:48:56 +0000
parents 493ca924c199
children 24bbd7e46bfe
comparison
equal deleted inserted replaced
16389:493ca924c199 16390:4fc51a87ce42
46 }; 46 };
47 47
48 static GHashTable *account_cache = NULL; 48 static GHashTable *account_cache = NULL;
49 static GHashTable *icon_data_cache = NULL; 49 static GHashTable *icon_data_cache = NULL;
50 static GHashTable *icon_file_cache = NULL; 50 static GHashTable *icon_file_cache = NULL;
51 static GHashTable *custom_icon_cache = NULL; 51
52 /* This one is used for both custom buddy icons
53 * on PurpleContacts and account icons. */
54 static GHashTable *pointer_icon_cache = NULL;
55
52 static char *cache_dir = NULL; 56 static char *cache_dir = NULL;
53 static gboolean icon_caching = TRUE; 57 static gboolean icon_caching = TRUE;
54 58
55 /* For ~/.gaim to ~/.purple migration. */ 59 /* For ~/.gaim to ~/.purple migration. */
56 static char *old_icons_dir = NULL; 60 static char *old_icons_dir = NULL;
213 purple_buddy_icon_data_uncache_file(filename); 217 purple_buddy_icon_data_uncache_file(filename);
214 g_hash_table_remove(icon_data_cache, filename); 218 g_hash_table_remove(icon_data_cache, filename);
215 219
216 /* We could make this O(1) by using another hash table, but 220 /* We could make this O(1) by using another hash table, but
217 * this is probably good enough. */ 221 * this is probably good enough. */
218 g_hash_table_foreach_remove(custom_icon_cache, value_equals, img); 222 g_hash_table_foreach_remove(pointer_icon_cache, value_equals, img);
219 } 223 }
220 } 224 }
221 225
222 static PurpleStoredImage * 226 static PurpleStoredImage *
223 purple_buddy_icon_data_new(guchar *icon_data, size_t icon_len, const char *filename) 227 purple_buddy_icon_data_new(guchar *icon_data, size_t icon_len, const char *filename)
512 PurpleBuddyIcon *icon = purple_buddy_icon_new(account, username, icon_data, icon_len, checksum); 516 PurpleBuddyIcon *icon = purple_buddy_icon_new(account, username, icon_data, icon_len, checksum);
513 purple_buddy_icon_unref(icon); 517 purple_buddy_icon_unref(icon);
514 } 518 }
515 } 519 }
516 520
521 char *purple_buddy_icon_get_full_path(PurpleBuddyIcon *icon)
522 {
523 char *path;
524
525 g_return_val_if_fail(icon != NULL, NULL);
526
527 if (icon->img == NULL)
528 return NULL;
529
530 path = g_build_filename(purple_buddy_icons_get_cache_dir(),
531 purple_imgstore_get_filename(icon->img), NULL);
532 if (!g_file_test(path, G_FILE_TEST_EXISTS))
533 {
534 g_free(path);
535 return NULL;
536 }
537 return path;
538 }
539
517 const char * 540 const char *
518 purple_buddy_icons_get_checksum_for_user(PurpleBuddy *buddy) 541 purple_buddy_icons_get_checksum_for_user(PurpleBuddy *buddy)
519 { 542 {
520 return purple_blist_node_get_string((PurpleBlistNode*)buddy, 543 return purple_blist_node_get_string((PurpleBlistNode*)buddy,
521 "icon_checksum"); 544 "icon_checksum");
605 628
606 return (purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon") != NULL); 629 return (purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon") != NULL);
607 } 630 }
608 631
609 PurpleStoredImage * 632 PurpleStoredImage *
633 purple_buddy_icons_find_account_icon(PurpleAccount *account)
634 {
635 PurpleStoredImage *img;
636 const char *account_icon_file;
637 const char *dirname;
638 char *path;
639 guchar *data;
640 size_t len;
641
642 g_return_val_if_fail(account != NULL, NULL);
643
644 if ((img = g_hash_table_lookup(pointer_icon_cache, account)))
645 {
646 return purple_imgstore_ref(img);
647 }
648
649 account_icon_file = purple_account_get_string(account, "buddy_icon", NULL);
650
651 if (account_icon_file == NULL)
652 return NULL;
653
654 dirname = purple_buddy_icons_get_cache_dir();
655 path = g_build_filename(dirname, account_icon_file, NULL);
656
657 if (read_icon_file(path, &data, &len))
658 {
659 g_free(path);
660 img = purple_buddy_icon_data_new(data, len, account_icon_file);
661 g_free(data);
662 g_hash_table_insert(pointer_icon_cache, account, img);
663 return img;
664 }
665 g_free(path);
666
667 return NULL;
668 }
669
670 PurpleStoredImage *
671 purple_buddy_icons_set_account_icon(PurpleAccount *account,
672 guchar *icon_data, size_t icon_len)
673 {
674 PurpleStoredImage *old_img;
675 PurpleStoredImage *img = NULL;
676 char *old_icon;
677
678 old_img = g_hash_table_lookup(pointer_icon_cache, account);
679
680 if (icon_data != NULL && icon_len > 0)
681 {
682 img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
683 g_free(icon_data);
684 }
685
686 old_icon = g_strdup(purple_account_get_string(account, "buddy_icon", NULL));
687 if (img && purple_buddy_icons_is_caching())
688 {
689 const char *filename = purple_imgstore_get_filename(img);
690 purple_account_set_string(account, "buddy_icon", filename);
691 ref_filename(filename);
692 }
693 else
694 {
695 // TODO
696 // purple_account_remove_setting(account, "buddy_icon");
697 }
698 unref_filename(old_icon);
699
700 if (img)
701 g_hash_table_insert(pointer_icon_cache, account, img);
702 else
703 g_hash_table_remove(pointer_icon_cache, account);
704
705 if (purple_account_is_connected(account))
706 {
707 PurpleConnection *gc;
708 PurplePluginProtocolInfo *prpl_info;
709
710 gc = purple_account_get_connection(account);
711 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
712
713 if (prpl_info && prpl_info->set_buddy_icon)
714 prpl_info->set_buddy_icon(gc, img);
715 }
716
717 if (old_img)
718 purple_imgstore_unref(old_img);
719 else
720 {
721 /* The old icon may not have been loaded into memory. In that
722 * case, we'll need to uncache the filename. The filenames
723 * are ref-counted, so this is safe. */
724 purple_buddy_icon_data_uncache_file(old_icon);
725 }
726 g_free(old_icon);
727
728 return img;
729 }
730
731 PurpleStoredImage *
610 purple_buddy_icons_find_custom_icon(PurpleContact *contact) 732 purple_buddy_icons_find_custom_icon(PurpleContact *contact)
611 { 733 {
612 PurpleStoredImage *img; 734 PurpleStoredImage *img;
613 const char *custom_icon_file; 735 const char *custom_icon_file;
614 const char *dirname; 736 const char *dirname;
616 guchar *data; 738 guchar *data;
617 size_t len; 739 size_t len;
618 740
619 g_return_val_if_fail(contact != NULL, NULL); 741 g_return_val_if_fail(contact != NULL, NULL);
620 742
621 if ((img = g_hash_table_lookup(custom_icon_cache, contact))) 743 if ((img = g_hash_table_lookup(pointer_icon_cache, contact)))
622 { 744 {
623 return purple_imgstore_ref(img); 745 return purple_imgstore_ref(img);
624 } 746 }
625 747
626 custom_icon_file = purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon"); 748 custom_icon_file = purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon");
634 if (read_icon_file(path, &data, &len)) 756 if (read_icon_file(path, &data, &len))
635 { 757 {
636 g_free(path); 758 g_free(path);
637 img = purple_buddy_icon_data_new(data, len, custom_icon_file); 759 img = purple_buddy_icon_data_new(data, len, custom_icon_file);
638 g_free(data); 760 g_free(data);
639 g_hash_table_insert(custom_icon_cache, contact, img); 761 g_hash_table_insert(pointer_icon_cache, contact, img);
640 return img; 762 return img;
641 } 763 }
642 g_free(path); 764 g_free(path);
643 765
644 return NULL; 766 return NULL;
645 } 767 }
646 768
647 void 769 PurpleStoredImage *
648 purple_buddy_icons_set_custom_icon(PurpleContact *contact, 770 purple_buddy_icons_set_custom_icon(PurpleContact *contact,
649 guchar *icon_data, size_t icon_len) 771 guchar *icon_data, size_t icon_len)
650 { 772 {
651 PurpleStoredImage *old_img; 773 PurpleStoredImage *old_img;
652 PurpleStoredImage *img = NULL; 774 PurpleStoredImage *img = NULL;
653 char *old_icon; 775 char *old_icon;
654 PurpleBlistNode *child; 776 PurpleBlistNode *child;
655 777
656 old_img = g_hash_table_lookup(custom_icon_cache, contact); 778 old_img = g_hash_table_lookup(pointer_icon_cache, contact);
657 779
658 if (icon_data != NULL && icon_len > 0) 780 if (icon_data != NULL && icon_len > 0)
781 {
659 img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); 782 img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
783 g_free(icon_data);
784 }
660 785
661 old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)contact, 786 old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)contact,
662 "custom_buddy_icon")); 787 "custom_buddy_icon"));
663 if (img && purple_buddy_icons_is_caching()) 788 if (img && purple_buddy_icons_is_caching())
664 { 789 {
673 purple_blist_node_remove_setting((PurpleBlistNode *)contact, 798 purple_blist_node_remove_setting((PurpleBlistNode *)contact,
674 "custom_buddy_icon"); 799 "custom_buddy_icon");
675 } 800 }
676 unref_filename(old_icon); 801 unref_filename(old_icon);
677 802
678 g_hash_table_insert(custom_icon_cache, contact, img); 803 if (img)
804 g_hash_table_insert(pointer_icon_cache, contact, img);
805 else
806 g_hash_table_remove(pointer_icon_cache, contact);
679 807
680 for (child = contact->node.child ; child ; child = child->next) 808 for (child = contact->node.child ; child ; child = child->next)
681 { 809 {
682 PurpleBuddy *buddy; 810 PurpleBuddy *buddy;
683 PurpleConversation *conv; 811 PurpleConversation *conv;
704 * case, we'll need to uncache the filename. The filenames 832 * case, we'll need to uncache the filename. The filenames
705 * are ref-counted, so this is safe. */ 833 * are ref-counted, so this is safe. */
706 purple_buddy_icon_data_uncache_file(old_icon); 834 purple_buddy_icon_data_uncache_file(old_icon);
707 } 835 }
708 g_free(old_icon); 836 g_free(old_icon);
837
838 return img;
709 } 839 }
710 840
711 void 841 void
712 purple_buddy_icon_set_old_icons_dir(const char *dirname) 842 purple_buddy_icon_set_old_icons_dir(const char *dirname)
713 { 843 {
938 purple_buddy_icons_get_cache_dir(void) 1068 purple_buddy_icons_get_cache_dir(void)
939 { 1069 {
940 return cache_dir; 1070 return cache_dir;
941 } 1071 }
942 1072
943 // TODO: Deal with this
944 char *purple_buddy_icons_get_full_path(const char *icon) {
945 if (icon == NULL)
946 return NULL;
947
948 if (g_file_test(icon, G_FILE_TEST_IS_REGULAR))
949 return g_strdup(icon);
950 else
951 return g_build_filename(purple_buddy_icons_get_cache_dir(), icon, NULL);
952 }
953
954 void * 1073 void *
955 purple_buddy_icons_get_handle() 1074 purple_buddy_icons_get_handle()
956 { 1075 {
957 static int handle; 1076 static int handle;
958 1077
967 NULL, (GFreeFunc)g_hash_table_destroy); 1086 NULL, (GFreeFunc)g_hash_table_destroy);
968 1087
969 icon_data_cache = g_hash_table_new(g_str_hash, g_str_equal); 1088 icon_data_cache = g_hash_table_new(g_str_hash, g_str_equal);
970 icon_file_cache = g_hash_table_new_full(g_str_hash, g_str_equal, 1089 icon_file_cache = g_hash_table_new_full(g_str_hash, g_str_equal,
971 g_free, NULL); 1090 g_free, NULL);
972 custom_icon_cache = g_hash_table_new(g_direct_hash, g_direct_equal); 1091 pointer_icon_cache = g_hash_table_new(g_direct_hash, g_direct_equal);
973 1092
974 cache_dir = g_build_filename(purple_user_dir(), "icons", NULL); 1093 cache_dir = g_build_filename(purple_user_dir(), "icons", NULL);
975 1094
976 purple_signal_connect(purple_imgstore_get_handle(), "image-deleting", 1095 purple_signal_connect(purple_imgstore_get_handle(), "image-deleting",
977 purple_buddy_icons_get_handle(), 1096 purple_buddy_icons_get_handle(),
984 purple_signals_disconnect_by_handle(purple_buddy_icons_get_handle()); 1103 purple_signals_disconnect_by_handle(purple_buddy_icons_get_handle());
985 1104
986 g_hash_table_destroy(account_cache); 1105 g_hash_table_destroy(account_cache);
987 g_hash_table_destroy(icon_data_cache); 1106 g_hash_table_destroy(icon_data_cache);
988 g_hash_table_destroy(icon_file_cache); 1107 g_hash_table_destroy(icon_file_cache);
989 g_hash_table_destroy(custom_icon_cache); 1108 g_hash_table_destroy(pointer_icon_cache);
990 g_free(old_icons_dir); 1109 g_free(old_icons_dir);
991 } 1110 }
992 1111
993 void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int *height) 1112 void purple_buddy_icon_get_scale_size(PurpleBuddyIconSpec *spec, int *width, int *height)
994 { 1113 {