comparison pidgin/gtkrequest.c @ 32156:1693114a2655

applied changes from 6cf1aee8ac5e3c836af832eaf26ccedd611dc70b through e802003adbf0be4496de3de8ac03b47c1e471d00 Original commit message: Start looking at the GError parameter every time we call these functions: - gdk_pixbuf_loader_write - gdk_pixbuf_loader_close - gdk_pixbuf_new_from_file - gdk_pixbuf_new_from_file_at_size - gdk_pixbuf_new_from_file_at_scale There are times when gdkpixbuf returns a semi-invalid GdkPixbuf object and also sets the GError. If this happens we want to discard and ignore the GdkPixbuf object because it can cause problems. For example, calling gdk_pixbuf_scale_simple() causes gdkpixbuf to rapidly consume memory in an infinite loop. And that's bad. This commit adds some helper functions to gtkutils.[c|h] that make it a little easier to check the GError value. We should use them everywhere we call any of the above functions.
author Mark Doliner <mark@kingant.net>
date Wed, 22 Jun 2011 07:09:42 +0000
parents f56b66606fd2
children 142429bcb4c8
comparison
equal deleted inserted replaced
32155:5ffd5582f5fe 32156:1693114a2655
651 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); 651 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER);
652 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox); 652 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
653 653
654 /* Dialog icon. */ 654 /* Dialog icon. */
655 if (icon_data) { 655 if (icon_data) {
656 GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); 656 GdkPixbuf *pixbuf = pidgin_pixbuf_from_data(icon_data, icon_size);
657 GdkPixbuf *pixbuf = NULL; 657 if (pixbuf) {
658 if (gdk_pixbuf_loader_write(loader, icon_data, icon_size, NULL)) { 658 /* scale the image if it is too large */
659 pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); 659 int width = gdk_pixbuf_get_width(pixbuf);
660 if (pixbuf) { 660 int height = gdk_pixbuf_get_height(pixbuf);
661 /* scale the image if it is too large */ 661 if (width > 128 || height > 128) {
662 int width = gdk_pixbuf_get_width(pixbuf); 662 int scaled_width = width > height ? 128 : (128 * width) / height;
663 int height = gdk_pixbuf_get_height(pixbuf); 663 int scaled_height = height > width ? 128 : (128 * height) / width;
664 if (width > 128 || height > 128) { 664 GdkPixbuf *scaled =
665 int scaled_width = width > height ? 128 : (128 * width) / height; 665 gdk_pixbuf_scale_simple(pixbuf, scaled_width, scaled_height,
666 int scaled_height = height > width ? 128 : (128 * height) / width; 666 GDK_INTERP_BILINEAR);
667 GdkPixbuf *scaled = 667
668 gdk_pixbuf_scale_simple(pixbuf, scaled_width, scaled_height, 668 purple_debug_info("pidgin",
669 GDK_INTERP_BILINEAR); 669 "dialog icon was too large, scaled it down\n");
670 670 if (scaled) {
671 purple_debug_info("pidgin", 671 g_object_unref(pixbuf);
672 "dialog icon was too large, scale it down\n"); 672 pixbuf = scaled;
673 if (scaled) {
674 g_object_unref(pixbuf);
675 pixbuf = scaled;
676 }
677 } 673 }
678 img = gtk_image_new_from_pixbuf(pixbuf);
679 } 674 }
675 img = gtk_image_new_from_pixbuf(pixbuf);
676 g_object_unref(pixbuf);
680 } else { 677 } else {
681 purple_debug_info("pidgin", "failed to parse dialog icon\n"); 678 purple_debug_info("pidgin", "failed to parse dialog icon\n");
682 } 679 }
683 gdk_pixbuf_loader_close(loader, NULL);
684 g_object_unref(loader);
685 } 680 }
686 681
687 if (!img) { 682 if (!img) {
688 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION, 683 img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
689 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE)); 684 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
1014 static GtkWidget * 1009 static GtkWidget *
1015 create_image_field(PurpleRequestField *field) 1010 create_image_field(PurpleRequestField *field)
1016 { 1011 {
1017 GtkWidget *widget; 1012 GtkWidget *widget;
1018 GdkPixbuf *buf, *scale; 1013 GdkPixbuf *buf, *scale;
1019 GdkPixbufLoader *loader; 1014
1020 1015 buf = pidgin_pixbuf_from_data(
1021 loader = gdk_pixbuf_loader_new(); 1016 (const guchar *)purple_request_field_image_get_buffer(field),
1022 gdk_pixbuf_loader_write(loader, 1017 purple_request_field_image_get_size(field));
1023 (const guchar *)purple_request_field_image_get_buffer(field),
1024 purple_request_field_image_get_size(field),
1025 NULL);
1026 gdk_pixbuf_loader_close(loader, NULL);
1027 buf = gdk_pixbuf_loader_get_pixbuf(loader);
1028 1018
1029 scale = gdk_pixbuf_scale_simple(buf, 1019 scale = gdk_pixbuf_scale_simple(buf,
1030 purple_request_field_image_get_scale_x(field) * gdk_pixbuf_get_width(buf), 1020 purple_request_field_image_get_scale_x(field) * gdk_pixbuf_get_width(buf),
1031 purple_request_field_image_get_scale_y(field) * gdk_pixbuf_get_height(buf), 1021 purple_request_field_image_get_scale_y(field) * gdk_pixbuf_get_height(buf),
1032 GDK_INTERP_BILINEAR); 1022 GDK_INTERP_BILINEAR);
1033 widget = gtk_image_new_from_pixbuf(scale); 1023 widget = gtk_image_new_from_pixbuf(scale);
1034 g_object_unref(G_OBJECT(loader)); 1024 g_object_unref(G_OBJECT(buf));
1035 g_object_unref(G_OBJECT(scale)); 1025 g_object_unref(G_OBJECT(scale));
1036 1026
1037 return widget; 1027 return widget;
1038 } 1028 }
1039 1029
1130 { 1120 {
1131 const char *icon_path = (const char *)icons->data; 1121 const char *icon_path = (const char *)icons->data;
1132 GdkPixbuf* pixbuf = NULL; 1122 GdkPixbuf* pixbuf = NULL;
1133 1123
1134 if (icon_path) 1124 if (icon_path)
1135 pixbuf = gdk_pixbuf_new_from_file(icon_path, NULL); 1125 pixbuf = pidgin_pixbuf_new_from_file(icon_path);
1136 1126
1137 gtk_list_store_set(store, &iter, 1127 gtk_list_store_set(store, &iter,
1138 0, purple_request_field_list_get_data(field, text), 1128 0, purple_request_field_list_get_data(field, text),
1139 1, text, 1129 1, text,
1140 2, pixbuf, 1130 2, pixbuf,