comparison pidgin-twitter.c @ 167:10516b7b05a9

- ceased use of purple_imgstore_* - fixed for some memory leakage.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 29 Jul 2008 19:20:20 +0900
parents af85daac1a95
children 56e3873e58a8
comparison
equal deleted inserted replaced
166:af85daac1a95 167:10516b7b05a9
473 parse_status(nptr2, st); 473 parse_status(nptr2, st);
474 } 474 }
475 } 475 }
476 } 476 }
477 } 477 }
478
479 xmlFreeDoc(doc);
480 xmlCleanupParser();
478 481
479 /* process statuseslist */ 482 /* process statuseslist */
480 for(stp = statuseslist; stp; stp=stp->next) { 483 for(stp = statuseslist; stp; stp=stp->next) {
481 status_t *st = (status_t *)stp->data; 484 status_t *st = (status_t *)stp->data;
482 485
655 postedlist = g_list_prepend(postedlist, st); 658 postedlist = g_list_prepend(postedlist, st);
656 parse_status(nptr, st); 659 parse_status(nptr, st);
657 } 660 }
658 } 661 }
659 662
663 xmlFreeDoc(doc);
664 xmlCleanupParser();
665
660 } else { 666 } else {
661 gchar *m; 667 gchar *m;
662 m = g_strdup_printf("%s<BR>%s", 668 m = g_strdup_printf("%s<BR>%s",
663 msg, tm->status); 669 msg, tm->status);
664 /* FIXME: too strong. it should be more smart */ 670 /* FIXME: too strong. it should be more smart */
1548 1554
1549 GList *win_list; 1555 GList *win_list;
1550 GtkIMHtml *target_imhtml = NULL; 1556 GtkIMHtml *target_imhtml = NULL;
1551 GtkTextBuffer *target_buffer = NULL; 1557 GtkTextBuffer *target_buffer = NULL;
1552 GtkTextIter insertion_point; 1558 GtkTextIter insertion_point;
1553 gint icon_id;
1554 icon_data *data = NULL; 1559 icon_data *data = NULL;
1555 GHashTable *hash = NULL; 1560 GHashTable *hash = NULL;
1556 1561
1557 twitter_debug("called: service = %d\n", service); 1562 twitter_debug("called: service = %d\n", service);
1558 1563
1606 } 1611 }
1607 1612
1608 if(hash) 1613 if(hash)
1609 data = (icon_data *)g_hash_table_lookup(hash, user_name); 1614 data = (icon_data *)g_hash_table_lookup(hash, user_name);
1610 1615
1611 if(data)
1612 icon_id = data->icon_id;
1613 else
1614 icon_id = 0;
1615 1616
1616 /* in this function, we put an icon for pending marks. we should 1617 /* in this function, we put an icon for pending marks. we should
1617 * not invalidate the icon here, otherwise it may result in 1618 * not invalidate the icon here, otherwise it may result in
1618 * thrashing. --yaz */ 1619 * thrashing. --yaz */
1619 #if 0 1620 #if 0
1629 data->use_count = 0; 1630 data->use_count = 0;
1630 data->mtime = time(NULL); //xxx not good 1631 data->mtime = time(NULL); //xxx not good
1631 } 1632 }
1632 #endif 1633 #endif
1633 1634
1634 if(!icon_id) { 1635 if(!data || !data->pixbuf) {
1635 return; 1636 return;
1636 } 1637 }
1637 1638
1638 /* insert icon actually */ 1639 /* insert icon actually */
1639 if(purple_prefs_get_bool(OPT_SHOW_ICON)) { 1640 if(purple_prefs_get_bool(OPT_SHOW_ICON)) {
1640 PurpleStoredImage *img = purple_imgstore_find_by_id(icon_id);
1641 const GdkPixbuf *pixbuf = purple_imgstore_get_data(img);
1642 gtk_text_buffer_insert_pixbuf(target_buffer, 1641 gtk_text_buffer_insert_pixbuf(target_buffer,
1643 &insertion_point, 1642 &insertion_point,
1644 (GdkPixbuf *)pixbuf); 1643 data->pixbuf);
1645 data->use_count++; 1644 data->use_count++;
1646 } 1645 }
1647 gtk_text_buffer_delete_mark(target_buffer, requested_mark); 1646 gtk_text_buffer_delete_mark(target_buffer, requested_mark);
1648 requested_mark = NULL; 1647 requested_mark = NULL;
1649 } 1648 }
1690 g_list_foreach(mark_list, (GFunc) insert_icon_at_mark, gotdata); 1689 g_list_foreach(mark_list, (GFunc) insert_icon_at_mark, gotdata);
1691 mark_list = g_list_remove_all(mark_list, NULL); 1690 mark_list = g_list_remove_all(mark_list, NULL);
1692 g_list_free(mark_list); 1691 g_list_free(mark_list);
1693 data->request_list = NULL; 1692 data->request_list = NULL;
1694 } 1693 }
1694
1695 g_free(gotdata->user_name); 1695 g_free(gotdata->user_name);
1696 g_free(gotdata); 1696 g_free(gotdata);
1697 } 1697 }
1698 1698
1699 /* this function will be called when profile page has been retrieved */ 1699 /* this function will be called when profile page has been retrieved */
1812 size = purple_prefs_get_int(OPT_ICON_SIZE); 1812 size = purple_prefs_get_int(OPT_ICON_SIZE);
1813 if(size == 0) 1813 if(size == 0)
1814 size = DEFAULT_ICON_SIZE; 1814 size = DEFAULT_ICON_SIZE;
1815 1815
1816 dest = gdk_pixbuf_scale_simple(src, size, size, GDK_INTERP_HYPER); 1816 dest = gdk_pixbuf_scale_simple(src, size, size, GDK_INTERP_HYPER);
1817 gdk_pixbuf_unref (src); 1817 gdk_pixbuf_unref(src);
1818 1818
1819 return dest; 1819 return dest;
1820 } 1820 }
1821 1821
1822 static gchar *ext_list[] = { 1822 static gchar *ext_list[] = {
1833 { 1833 {
1834 got_icon_data *gotdata = (got_icon_data *)user_data; 1834 got_icon_data *gotdata = (got_icon_data *)user_data;
1835 gchar *user_name = gotdata->user_name; 1835 gchar *user_name = gotdata->user_name;
1836 gint service = gotdata->service; 1836 gint service = gotdata->service;
1837 1837
1838 gint icon_id;
1839 icon_data *data = NULL; 1838 icon_data *data = NULL;
1840 GHashTable *hash = NULL; 1839 GHashTable *hash = NULL;
1841 GdkPixbuf *pixbuf = NULL; 1840 GdkPixbuf *pixbuf = NULL;
1842 const gchar *dirname = NULL; 1841 const gchar *dirname = NULL;
1843 1842
1874 /* remove download request */ 1873 /* remove download request */
1875 data->requested = FALSE; 1874 data->requested = FALSE;
1876 data->fetch_data = NULL; 1875 data->fetch_data = NULL;
1877 1876
1878 /* return if user's icon had been downloaded */ 1877 /* return if user's icon had been downloaded */
1879 if(data->icon_id > 0) { 1878 if(data->pixbuf) {
1880 twitter_debug("%s's icon has already been downloaded\n", 1879 twitter_debug("%s's icon has already been downloaded\n",
1881 user_name); 1880 user_name);
1882 1881
1883 goto fin_got_icon_cb; 1882 goto fin_got_icon_cb;
1884 } 1883 }
1887 pixbuf = make_scaled_pixbuf(url_text, len); 1886 pixbuf = make_scaled_pixbuf(url_text, len);
1888 1887
1889 if(!pixbuf) 1888 if(!pixbuf)
1890 goto fin_got_icon_cb; 1889 goto fin_got_icon_cb;
1891 1890
1892 icon_id =
1893 purple_imgstore_add_with_id(pixbuf,
1894 gdk_pixbuf_get_rowstride(pixbuf) *
1895 gdk_pixbuf_get_height(pixbuf),
1896 user_name);
1897 1891
1898 if(!data) { 1892 if(!data) {
1899 twitter_debug("allocate icon_data (shouldn't be called)\n"); 1893 twitter_debug("allocate icon_data (shouldn't be called)\n");
1900 data = g_new0(icon_data, 1); 1894 data = g_new0(icon_data, 1);
1901 } 1895 }
1902 1896
1903 data->icon_id = icon_id; 1897 data->pixbuf = pixbuf;
1898
1899 twitter_debug("new icon pixbuf = %p size = %d\n",
1900 pixbuf,
1901 gdk_pixbuf_get_rowstride(pixbuf) *
1902 gdk_pixbuf_get_height(pixbuf));
1904 1903
1905 if(hash) 1904 if(hash)
1906 g_hash_table_insert(hash, g_strdup(user_name), data); 1905 g_hash_table_insert(hash, g_strdup(user_name), data);
1907 1906
1908 dirname = purple_prefs_get_string(OPT_ICON_DIR); 1907 dirname = purple_prefs_get_string(OPT_ICON_DIR);
1951 g_free(path); path = NULL; 1950 g_free(path); path = NULL;
1952 1951
1953 data->mtime = time(NULL); 1952 data->mtime = time(NULL);
1954 } 1953 }
1955 1954
1956 twitter_debug("Downloading %s's icon has been complete.(icon_id = %d)\n", 1955 twitter_debug("Downloading %s's icon has been complete.\n",
1957 user_name, icon_id); 1956 user_name);
1958 1957
1959 /* Insert the icon to messages that had been received. */ 1958 /* Insert the icon to messages that had been received. */
1960 insert_requested_icon(user_name, service); 1959 insert_requested_icon(user_name, service);
1961 1960
1962 fin_got_icon_cb: 1961 fin_got_icon_cb:
1997 return; 1996 return;
1998 1997
1999 /* since this function is called after mark_icon_for_user(), data 1998 /* since this function is called after mark_icon_for_user(), data
2000 * must exist here. */ 1999 * must exist here. */
2001 data = (icon_data *)g_hash_table_lookup(hash, user_name); 2000 data = (icon_data *)g_hash_table_lookup(hash, user_name);
2002 // g_hash_table_insert(hash, g_strdup(user_name), data); // XXX ???
2003 2001
2004 /* if img has been registerd, just return */ 2002 /* if img has been registerd, just return */
2005 if(data->icon_id > 0) 2003 if(data && data->pixbuf)
2006 return; 2004 return;
2007 2005
2008 /* check if saved file exists */ 2006 /* check if saved file exists */
2009 if(suffix && !renew) { 2007 if(suffix && !renew) {
2010 gchar *filename = NULL; 2008 gchar *filename = NULL;
2033 2031
2034 if(stat(path, &buf)) 2032 if(stat(path, &buf))
2035 data->mtime = buf.st_mtime; 2033 data->mtime = buf.st_mtime;
2036 2034
2037 pixbuf = make_scaled_pixbuf(imgdata, len); 2035 pixbuf = make_scaled_pixbuf(imgdata, len);
2036 g_free(imgdata);
2038 2037
2039 if(pixbuf) { 2038 if(pixbuf) {
2040 data->icon_id = 2039 data->pixbuf = pixbuf;
2041 purple_imgstore_add_with_id( 2040
2042 pixbuf, 2041 twitter_debug("new icon pixbuf = %p size = %d\n",
2043 gdk_pixbuf_get_rowstride(pixbuf) * 2042 pixbuf,
2044 gdk_pixbuf_get_height(pixbuf), 2043 gdk_pixbuf_get_rowstride(pixbuf) *
2045 user_name); 2044 gdk_pixbuf_get_height(pixbuf));
2046 2045
2047 data->img_type = *extp; 2046 data->img_type = *extp;
2048 2047
2049 twitter_debug("icon data has been loaded from file\n"); 2048 twitter_debug("icon data has been loaded from file\n");
2050 insert_requested_icon(user_name, service); 2049 insert_requested_icon(user_name, service);
2173 GMatchInfo *match_info = NULL; 2172 GMatchInfo *match_info = NULL;
2174 gchar *user_name = NULL; 2173 gchar *user_name = NULL;
2175 GtkIMHtml *imhtml; 2174 GtkIMHtml *imhtml;
2176 GtkTextBuffer *text_buffer; 2175 GtkTextBuffer *text_buffer;
2177 GtkTextIter insertion_point; 2176 GtkTextIter insertion_point;
2178 gint icon_id = 0;
2179 gint service = get_service_type(conv); 2177 gint service = get_service_type(conv);
2180 icon_data *data = NULL; 2178 icon_data *data = NULL;
2181 gint linenumber; 2179 gint linenumber;
2182 GHashTable *hash = NULL; 2180 GHashTable *hash = NULL;
2183 gboolean renew = FALSE; 2181 gboolean renew = FALSE;
2227 2225
2228 if(hash) 2226 if(hash)
2229 data = g_hash_table_lookup(hash, user_name); 2227 data = g_hash_table_lookup(hash, user_name);
2230 2228
2231 if(data) { 2229 if(data) {
2232 icon_id = data->icon_id;
2233
2234 /* check validity of icon */ 2230 /* check validity of icon */
2235 int count_thres = purple_prefs_get_int(OPT_ICON_MAX_COUNT); 2231 int count_thres = purple_prefs_get_int(OPT_ICON_MAX_COUNT);
2236 int days_thres = DAYS_TO_SECONDS(purple_prefs_get_int(OPT_ICON_MAX_DAYS)); 2232 int days_thres = DAYS_TO_SECONDS(
2233 purple_prefs_get_int(OPT_ICON_MAX_DAYS));
2237 2234
2238 if(data->use_count > count_thres || 2235 if(data->use_count > count_thres ||
2239 (data->mtime && ((time(NULL) - data->mtime)) > days_thres)) { 2236 (data->mtime && ((time(NULL) - data->mtime)) > days_thres)) {
2240 twitter_debug("count=%d mtime=%d\n", data->use_count, (int)(data->mtime)); 2237 twitter_debug("count=%d mtime=%d\n",
2241 icon_id = 0; 2238 data->use_count, (int)(data->mtime));
2242 data->icon_id = 0; 2239 g_object_unref(data->pixbuf);
2240 data->pixbuf = NULL;
2243 data->use_count = 0; 2241 data->use_count = 0;
2244 data->mtime = time(NULL); //xxx not good 2242 data->mtime = time(NULL); //xxx not good
2245 renew = TRUE; 2243 renew = TRUE;
2246 } 2244 }
2247 } 2245 }
2248 2246
2249 /* if we don't have the icon for this user, put a mark instead and 2247 /* if we don't have the icon for this user, put a mark instead and
2250 * request the icon */ 2248 * request the icon */
2251 if(!icon_id) { 2249 if(!data || !data->pixbuf) {
2252 twitter_debug("%s's icon is not in memory.\n", user_name); 2250 twitter_debug("%s's icon is not in memory.\n", user_name);
2253 mark_icon_for_user(gtk_text_buffer_create_mark( 2251 mark_icon_for_user(gtk_text_buffer_create_mark(
2254 text_buffer, NULL, &insertion_point, FALSE), 2252 text_buffer, NULL, &insertion_point, FALSE),
2255 user_name, service); 2253 user_name, service);
2256 /* request to attach icon to the buffer */ 2254 /* request to attach icon to the buffer */
2259 return; 2257 return;
2260 } 2258 }
2261 2259
2262 /* if we have icon for this user, insert icon immediately */ 2260 /* if we have icon for this user, insert icon immediately */
2263 if(purple_prefs_get_bool(OPT_SHOW_ICON)) { 2261 if(purple_prefs_get_bool(OPT_SHOW_ICON)) {
2264 PurpleStoredImage *img = purple_imgstore_find_by_id(icon_id);
2265 const GdkPixbuf *pixbuf = purple_imgstore_get_data(img);
2266 gtk_text_buffer_insert_pixbuf(text_buffer, 2262 gtk_text_buffer_insert_pixbuf(text_buffer,
2267 &insertion_point, 2263 &insertion_point,
2268 (GdkPixbuf *)pixbuf); 2264 data->pixbuf);
2269 data->use_count++; 2265 data->use_count++;
2270 } 2266 }
2271 g_free(user_name); user_name = NULL; 2267 g_free(user_name); user_name = NULL;
2272 2268
2273 twitter_debug("reach end of function\n"); 2269 twitter_debug("reach end of function\n");
2501 invalidate_icon_data_func(gpointer key, gpointer value, gpointer user_data) 2497 invalidate_icon_data_func(gpointer key, gpointer value, gpointer user_data)
2502 { 2498 {
2503 icon_data *data = (icon_data *)value; 2499 icon_data *data = (icon_data *)value;
2504 2500
2505 g_return_if_fail(data != NULL); 2501 g_return_if_fail(data != NULL);
2506 g_return_if_fail(data->icon_id > 0); 2502
2507 2503 g_object_unref(data->pixbuf);
2508 /* img->data is managed by gdkpixbuf, so we should not free here. */ 2504 data->pixbuf = NULL;
2509 #if 0
2510 PurpleStoredImage *img = purple_imgstore_find_by_id(data->icon_id);
2511 if(img)
2512 purple_imgstore_unref_by_id(data->icon_id);
2513 #endif
2514
2515 data->icon_id = 0;
2516 } 2505 }
2517 2506
2518 static void 2507 static void
2519 icon_size_prefs_cb(const char *name, PurplePrefType type, 2508 icon_size_prefs_cb(const char *name, PurplePrefType type,
2520 gconstpointer val, gpointer data) 2509 gconstpointer val, gpointer data)
2610 "pidgin-twitter", "prefs.ui", NULL); 2599 "pidgin-twitter", "prefs.ui", NULL);
2611 #endif 2600 #endif
2612 gtk_builder_add_from_file(builder, filename, &err); 2601 gtk_builder_add_from_file(builder, filename, &err);
2613 if(err) { 2602 if(err) {
2614 twitter_debug("%s\n", err->message); 2603 twitter_debug("%s\n", err->message);
2604 g_free(filename);
2615 return NULL; 2605 return NULL;
2616 } 2606 }
2617 2607
2618 g_free(filename); 2608 g_free(filename);
2619 2609