comparison pidgin/gtkutils.c @ 30909:25e200cb3532

propagate from branch 'im.pidgin.pidgin' (head dca20e09164518b0f7a773edd7e9649f41d8873d) to branch 'im.pidgin.cpw.malu.xmpp.google_refactor' (head 7823c556f2d1bbca43f5ef9f0fea30cabc5d313f)
author Marcus Lundblad <ml@update.uu.se>
date Tue, 31 Aug 2010 18:28:10 +0000
parents 351d07aefb09
children c5ba7dd399fa 695b6e57e255
comparison
equal deleted inserted replaced
30908:c44ec533a48c 30909:25e200cb3532
678 678
679 static AopMenu * 679 static AopMenu *
680 create_protocols_menu(const char *default_proto_id) 680 create_protocols_menu(const char *default_proto_id)
681 { 681 {
682 AopMenu *aop_menu = NULL; 682 AopMenu *aop_menu = NULL;
683 PurplePluginProtocolInfo *prpl_info;
684 PurplePlugin *plugin; 683 PurplePlugin *plugin;
685 GdkPixbuf *pixbuf = NULL; 684 GdkPixbuf *pixbuf = NULL;
686 GtkSizeGroup *sg; 685 GtkSizeGroup *sg;
687 GList *p; 686 GList *p;
688 const char *gtalk_name = NULL; 687 const char *gtalk_name = NULL;
700 for (p = purple_plugins_get_protocols(), i = 0; 699 for (p = purple_plugins_get_protocols(), i = 0;
701 p != NULL; 700 p != NULL;
702 p = p->next, i++) { 701 p = p->next, i++) {
703 702
704 plugin = (PurplePlugin *)p->data; 703 plugin = (PurplePlugin *)p->data;
705 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(plugin);
706 704
707 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) { 705 if (gtalk_name && strcmp(gtalk_name, plugin->info->name) < 0) {
708 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", 706 char *filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols",
709 "16", "google-talk.png", NULL); 707 "16", "google-talk.png", NULL);
710 GtkWidget *item; 708 GtkWidget *item;
782 aop_menu->menu = gtk_menu_new(); 780 aop_menu->menu = gtk_menu_new();
783 gtk_widget_show(aop_menu->menu); 781 gtk_widget_show(aop_menu->menu);
784 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 782 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
785 783
786 for (p = list, i = 0; p != NULL; p = p->next, i++) { 784 for (p = list, i = 0; p != NULL; p = p->next, i++) {
787 PurplePlugin *plugin;
788
789 if (show_all) 785 if (show_all)
790 account = (PurpleAccount *)p->data; 786 account = (PurpleAccount *)p->data;
791 else { 787 else {
792 PurpleConnection *gc = (PurpleConnection *)p->data; 788 PurpleConnection *gc = (PurpleConnection *)p->data;
793 789
796 792
797 if (filter_func && !filter_func(account)) { 793 if (filter_func && !filter_func(account)) {
798 i--; 794 i--;
799 continue; 795 continue;
800 } 796 }
801
802 plugin = purple_find_prpl(purple_account_get_protocol_id(account));
803 797
804 pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); 798 pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
805 799
806 if (pixbuf) { 800 if (pixbuf) {
807 if (purple_account_is_disconnected(account) && show_all && 801 if (purple_account_is_disconnected(account) && show_all &&
1034 { 1028 {
1035 char *protocol = NULL; 1029 char *protocol = NULL;
1036 char *username = NULL; 1030 char *username = NULL;
1037 char *alias = NULL; 1031 char *alias = NULL;
1038 char *str; 1032 char *str;
1039 char *c, *s; 1033 char *s;
1040 gboolean valid; 1034 gboolean valid;
1041 1035
1042 g_return_val_if_fail(msg != NULL, FALSE); 1036 g_return_val_if_fail(msg != NULL, FALSE);
1043 g_return_val_if_fail(ret_protocol != NULL, FALSE); 1037 g_return_val_if_fail(ret_protocol != NULL, FALSE);
1044 g_return_val_if_fail(ret_username != NULL, FALSE); 1038 g_return_val_if_fail(ret_username != NULL, FALSE);
1076 s++; 1070 s++;
1077 1071
1078 if (*s == '\r') *s++ = '\0'; 1072 if (*s == '\r') *s++ = '\0';
1079 if (*s == '\n') *s++ = '\0'; 1073 if (*s == '\n') *s++ = '\0';
1080 1074
1081 if ((c = strchr(key, ':')) != NULL) 1075 if (strchr(key, ':') != NULL)
1082 { 1076 {
1083 if (!g_ascii_strcasecmp(key, "X-IM-Username:")) 1077 if (!g_ascii_strcasecmp(key, "X-IM-Username:"))
1084 username = g_strdup(value); 1078 username = g_strdup(value);
1085 else if (!g_ascii_strcasecmp(key, "X-IM-Protocol:")) 1079 else if (!g_ascii_strcasecmp(key, "X-IM-Protocol:"))
1086 protocol = g_strdup(value); 1080 protocol = g_strdup(value);
2467 /* We couldn't convert to this image type. Try the next 2461 /* We couldn't convert to this image type. Try the next
2468 image type. */ 2462 image type. */
2469 break; 2463 break;
2470 } 2464 }
2471 2465
2472 if (spec->max_filesize == 0 || length < spec->max_filesize) { 2466 if (spec->max_filesize == 0 || length <= spec->max_filesize) {
2473 /* We were able to save the image as this image type and 2467 /* We were able to save the image as this image type and
2474 have it be within the size constraints. Great! Return 2468 have it be within the size constraints. Great! Return
2475 the image. */ 2469 the image. */
2476 purple_debug_info("buddyicon", "Converted image from " 2470 purple_debug_info("buddyicon", "Converted image from "
2477 "%dx%d to %dx%d, format=%s, quality=%u, " 2471 "%dx%d to %dx%d, format=%s, quality=%u, "
2505 scale_factor *= 0.8; 2499 scale_factor *= 0.8;
2506 new_width = orig_width * scale_factor; 2500 new_width = orig_width * scale_factor;
2507 new_height = orig_height * scale_factor; 2501 new_height = orig_height * scale_factor;
2508 g_object_unref(G_OBJECT(pixbuf)); 2502 g_object_unref(G_OBJECT(pixbuf));
2509 pixbuf = gdk_pixbuf_scale_simple(original, new_width, new_height, GDK_INTERP_HYPER); 2503 pixbuf = gdk_pixbuf_scale_simple(original, new_width, new_height, GDK_INTERP_HYPER);
2510 } while (new_width > 10 || new_height > 10); 2504 } while ((new_width > 10 || new_height > 10) && new_width > spec->min_width && new_height > spec->min_height);
2511 g_strfreev(prpl_formats); 2505 g_strfreev(prpl_formats);
2512 g_object_unref(G_OBJECT(pixbuf)); 2506 g_object_unref(G_OBJECT(pixbuf));
2513 g_object_unref(G_OBJECT(original)); 2507 g_object_unref(G_OBJECT(original));
2514 2508
2515 tmp = g_strdup_printf(_("The file '%s' is too large for %s. Please try a smaller image.\n"), 2509 tmp = g_strdup_printf(_("The file '%s' is too large for %s. Please try a smaller image.\n"),
2608 { 2602 {
2609 g_free(cb_datas->data); 2603 g_free(cb_datas->data);
2610 cb_datas = g_list_delete_link(cb_datas, cb_datas); 2604 cb_datas = g_list_delete_link(cb_datas, cb_datas);
2611 } 2605 }
2612 } 2606 }
2607
2608 static void
2609 mini_dialog_init(PidginMiniDialog *mini_dialog, PurpleConnection *gc, void *user_data, va_list args)
2610 {
2611 const char *button_text;
2612 GList *cb_datas = NULL;
2613 static gboolean first_call = TRUE;
2614
2615 if (first_call) {
2616 first_call = FALSE;
2617 purple_signal_connect(purple_connections_get_handle(), "signed-off",
2618 pidgin_utils_get_handle(),
2619 PURPLE_CALLBACK(connection_signed_off_cb), NULL);
2620 }
2621
2622 g_object_set_data(G_OBJECT(mini_dialog), "gc" ,gc);
2623 g_signal_connect(G_OBJECT(mini_dialog), "destroy",
2624 G_CALLBACK(alert_killed_cb), NULL);
2625
2626 while ((button_text = va_arg(args, char*))) {
2627 struct _old_button_clicked_cb_data *data = NULL;
2628 PidginMiniDialogCallback wrapper_cb = NULL;
2629 PidginUtilMiniDialogCallback callback =
2630 va_arg(args, PidginUtilMiniDialogCallback);
2631
2632 if (callback != NULL) {
2633 data = g_new0(struct _old_button_clicked_cb_data, 1);
2634 data->cb = callback;
2635 data->data = user_data;
2636 wrapper_cb = old_mini_dialog_button_clicked_cb;
2637 }
2638 pidgin_mini_dialog_add_button(mini_dialog, button_text,
2639 wrapper_cb, data);
2640 cb_datas = g_list_append(cb_datas, data);
2641 }
2642
2643 g_signal_connect(G_OBJECT(mini_dialog), "destroy",
2644 G_CALLBACK(old_mini_dialog_destroy_cb), cb_datas);
2645 }
2646
2647 #define INIT_AND_RETURN_MINI_DIALOG(mini_dialog) \
2648 va_list args; \
2649 va_start(args, user_data); \
2650 mini_dialog_init(mini_dialog, gc, user_data, args); \
2651 va_end(args); \
2652 return GTK_WIDGET(mini_dialog);
2613 2653
2614 GtkWidget * 2654 GtkWidget *
2615 pidgin_make_mini_dialog(PurpleConnection *gc, 2655 pidgin_make_mini_dialog(PurpleConnection *gc,
2616 const char *icon_name, 2656 const char *icon_name,
2617 const char *primary, 2657 const char *primary,
2618 const char *secondary, 2658 const char *secondary,
2619 void *user_data, 2659 void *user_data,
2620 ...) 2660 ...)
2621 { 2661 {
2622 PidginMiniDialog *mini_dialog; 2662 PidginMiniDialog *mini_dialog = pidgin_mini_dialog_new(primary, secondary, icon_name);
2623 const char *button_text; 2663 INIT_AND_RETURN_MINI_DIALOG(mini_dialog);
2624 GList *cb_datas = NULL; 2664 }
2625 va_list args; 2665
2626 static gboolean first_call = TRUE; 2666 GtkWidget *
2627 2667 pidgin_make_mini_dialog_with_custom_icon(PurpleConnection *gc,
2628 if (first_call) { 2668 GdkPixbuf *custom_icon,
2629 first_call = FALSE; 2669 const char *primary,
2630 purple_signal_connect(purple_connections_get_handle(), "signed-off", 2670 const char *secondary,
2631 pidgin_utils_get_handle(), 2671 void *user_data,
2632 PURPLE_CALLBACK(connection_signed_off_cb), NULL); 2672 ...)
2633 } 2673 {
2634 2674 PidginMiniDialog *mini_dialog = pidgin_mini_dialog_new_with_custom_icon(primary, secondary, custom_icon);
2635 mini_dialog = pidgin_mini_dialog_new(primary, secondary, icon_name); 2675 INIT_AND_RETURN_MINI_DIALOG(mini_dialog);
2636 g_object_set_data(G_OBJECT(mini_dialog), "gc" ,gc);
2637 g_signal_connect(G_OBJECT(mini_dialog), "destroy",
2638 G_CALLBACK(alert_killed_cb), NULL);
2639
2640 va_start(args, user_data);
2641 while ((button_text = va_arg(args, char*))) {
2642 struct _old_button_clicked_cb_data *data = NULL;
2643 PidginMiniDialogCallback wrapper_cb = NULL;
2644 PidginUtilMiniDialogCallback callback =
2645 va_arg(args, PidginUtilMiniDialogCallback);
2646
2647 if (callback != NULL) {
2648 data = g_new0(struct _old_button_clicked_cb_data, 1);
2649 data->cb = callback;
2650 data->data = user_data;
2651 wrapper_cb = old_mini_dialog_button_clicked_cb;
2652 }
2653 pidgin_mini_dialog_add_button(mini_dialog, button_text,
2654 wrapper_cb, data);
2655 cb_datas = g_list_append(cb_datas, data);
2656 }
2657 va_end(args);
2658
2659 g_signal_connect(G_OBJECT(mini_dialog), "destroy",
2660 G_CALLBACK(old_mini_dialog_destroy_cb), cb_datas);
2661
2662 return GTK_WIDGET(mini_dialog);
2663 } 2676 }
2664 2677
2665 /* 2678 /*
2666 * "This is so dead sexy." 2679 * "This is so dead sexy."
2667 * "Two thumbs up." 2680 * "Two thumbs up."
2769 return result; 2782 return result;
2770 } 2783 }
2771 2784
2772 2785
2773 gboolean pidgin_gdk_pixbuf_is_opaque(GdkPixbuf *pixbuf) { 2786 gboolean pidgin_gdk_pixbuf_is_opaque(GdkPixbuf *pixbuf) {
2774 int width, height, rowstride, i; 2787 int height, rowstride, i;
2775 unsigned char *pixels; 2788 unsigned char *pixels;
2776 unsigned char *row; 2789 unsigned char *row;
2777 2790
2778 if (!gdk_pixbuf_get_has_alpha(pixbuf)) 2791 if (!gdk_pixbuf_get_has_alpha(pixbuf))
2779 return TRUE; 2792 return TRUE;
2780 2793
2781 width = gdk_pixbuf_get_width (pixbuf); 2794 height = gdk_pixbuf_get_height (pixbuf);
2782 height = gdk_pixbuf_get_height (pixbuf); 2795 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2783 rowstride = gdk_pixbuf_get_rowstride (pixbuf); 2796 pixels = gdk_pixbuf_get_pixels (pixbuf);
2784 pixels = gdk_pixbuf_get_pixels (pixbuf); 2797
2785 2798 row = pixels;
2786 row = pixels; 2799 for (i = 3; i < rowstride; i+=4) {
2787 for (i = 3; i < rowstride; i+=4) { 2800 if (row[i] < 0xfe)
2788 if (row[i] < 0xfe) 2801 return FALSE;
2789 return FALSE; 2802 }
2790 } 2803
2791 2804 for (i = 1; i < height - 1; i++) {
2792 for (i = 1; i < height - 1; i++) { 2805 row = pixels + (i * rowstride);
2793 row = pixels + (i*rowstride); 2806 if (row[3] < 0xfe || row[rowstride - 1] < 0xfe) {
2794 if (row[3] < 0xfe || row[rowstride-1] < 0xfe) { 2807 return FALSE;
2795 return FALSE; 2808 }
2796 } 2809 }
2797 } 2810
2798 2811 row = pixels + ((height - 1) * rowstride);
2799 row = pixels + ((height-1) * rowstride); 2812 for (i = 3; i < rowstride; i += 4) {
2800 for (i = 3; i < rowstride; i+=4) { 2813 if (row[i] < 0xfe)
2801 if (row[i] < 0xfe) 2814 return FALSE;
2802 return FALSE; 2815 }
2803 } 2816
2804 2817 return TRUE;
2805 return TRUE;
2806 } 2818 }
2807 2819
2808 void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf) { 2820 void pidgin_gdk_pixbuf_make_round(GdkPixbuf *pixbuf) {
2809 int width, height, rowstride; 2821 int width, height, rowstride;
2810 guchar *pixels; 2822 guchar *pixels;
2811 if (!gdk_pixbuf_get_has_alpha(pixbuf)) 2823 if (!gdk_pixbuf_get_has_alpha(pixbuf))
2812 return; 2824 return;
2813 width = gdk_pixbuf_get_width(pixbuf); 2825 width = gdk_pixbuf_get_width(pixbuf);
2814 height = gdk_pixbuf_get_height(pixbuf); 2826 height = gdk_pixbuf_get_height(pixbuf);
2815 rowstride = gdk_pixbuf_get_rowstride(pixbuf); 2827 rowstride = gdk_pixbuf_get_rowstride(pixbuf);
2816 pixels = gdk_pixbuf_get_pixels(pixbuf); 2828 pixels = gdk_pixbuf_get_pixels(pixbuf);
2817 2829
2818 if (width < 6 || height < 6) 2830 if (width < 6 || height < 6)
2819 return; 2831 return;
2820 /* Top left */ 2832 /* Top left */
2821 pixels[3] = 0; 2833 pixels[3] = 0;
2822 pixels[7] = 0x80; 2834 pixels[7] = 0x80;
2823 pixels[11] = 0xC0; 2835 pixels[11] = 0xC0;
2824 pixels[rowstride + 3] = 0x80; 2836 pixels[rowstride + 3] = 0x80;
2825 pixels[rowstride * 2 + 3] = 0xC0; 2837 pixels[rowstride * 2 + 3] = 0xC0;
2826 2838
2827 /* Top right */ 2839 /* Top right */
2828 pixels[width * 4 - 1] = 0; 2840 pixels[width * 4 - 1] = 0;
2829 pixels[width * 4 - 5] = 0x80; 2841 pixels[width * 4 - 5] = 0x80;
2830 pixels[width * 4 - 9] = 0xC0; 2842 pixels[width * 4 - 9] = 0xC0;
2831 pixels[rowstride + (width * 4) - 1] = 0x80; 2843 pixels[rowstride + (width * 4) - 1] = 0x80;
2832 pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0; 2844 pixels[(2 * rowstride) + (width * 4) - 1] = 0xC0;
2833 2845
2834 /* Bottom left */ 2846 /* Bottom left */
2835 pixels[(height - 1) * rowstride + 3] = 0; 2847 pixels[(height - 1) * rowstride + 3] = 0;
2836 pixels[(height - 1) * rowstride + 7] = 0x80; 2848 pixels[(height - 1) * rowstride + 7] = 0x80;
2837 pixels[(height - 1) * rowstride + 11] = 0xC0; 2849 pixels[(height - 1) * rowstride + 11] = 0xC0;
2838 pixels[(height - 2) * rowstride + 3] = 0x80; 2850 pixels[(height - 2) * rowstride + 3] = 0x80;
2839 pixels[(height - 3) * rowstride + 3] = 0xC0; 2851 pixels[(height - 3) * rowstride + 3] = 0xC0;
2840 2852
2841 /* Bottom right */ 2853 /* Bottom right */
2842 pixels[height * rowstride - 1] = 0; 2854 pixels[height * rowstride - 1] = 0;
2843 pixels[(height - 1) * rowstride - 1] = 0x80; 2855 pixels[(height - 1) * rowstride - 1] = 0x80;
2844 pixels[(height - 2) * rowstride - 1] = 0xC0; 2856 pixels[(height - 2) * rowstride - 1] = 0xC0;
2845 pixels[height * rowstride - 5] = 0x80; 2857 pixels[height * rowstride - 5] = 0x80;
2846 pixels[height * rowstride - 9] = 0xC0; 2858 pixels[height * rowstride - 9] = 0xC0;
2847 } 2859 }
2848 2860
2849 const char *pidgin_get_dim_grey_string(GtkWidget *widget) { 2861 const char *pidgin_get_dim_grey_string(GtkWidget *widget) {
2850 static char dim_grey_string[8] = ""; 2862 static char dim_grey_string[8] = "";
2851 GtkStyle *style; 2863 GtkStyle *style;
3482 "{\n" 3494 "{\n"
3483 "GtkWidget::focus-padding = 0\n" 3495 "GtkWidget::focus-padding = 0\n"
3484 "GtkWidget::focus-line-width = 0\n" 3496 "GtkWidget::focus-line-width = 0\n"
3485 "xthickness = 0\n" 3497 "xthickness = 0\n"
3486 "ythickness = 0\n" 3498 "ythickness = 0\n"
3499 "GtkContainer::border-width = 0\n"
3500 "GtkButton::inner-border = {0, 0, 0, 0}\n"
3501 "GtkButton::default-border = {0, 0, 0, 0}\n"
3487 "}\n" 3502 "}\n"
3488 "widget \"*.pidgin-small-close-button\" style \"pidgin-small-close-button\""); 3503 "widget \"*.pidgin-small-close-button\" style \"pidgin-small-close-button\"");
3489 3504
3490 #ifdef _WIN32 3505 #ifdef _WIN32
3491 winpidgin_register_win32_url_handlers(); 3506 winpidgin_register_win32_url_handlers();