Mercurial > pidgin.yaz
comparison pidgin/gtkimhtml.c @ 32692:0f94ec89f0bc
merged from im.pidgin.pidgin
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 26 Sep 2011 14:57:21 +0900 |
parents | ac6353ffa129 02a2e8183b1d |
children | 4a34689eeb33 |
comparison
equal
deleted
inserted
replaced
32438:55e678325bda | 32692:0f94ec89f0bc |
---|---|
88 GtkIMHtml *imhtml; | 88 GtkIMHtml *imhtml; |
89 gchar *url; | 89 gchar *url; |
90 GtkTextTag *tag; | 90 GtkTextTag *tag; |
91 }; | 91 }; |
92 | 92 |
93 typedef struct _GtkIMHtmlProtocol | 93 typedef struct { |
94 { | |
95 char *name; | 94 char *name; |
96 int length; | 95 int length; |
97 | 96 |
98 gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link); | 97 gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link); |
99 gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu); | 98 gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu); |
100 } GtkIMHtmlProtocol; | 99 } GtkIMHtmlProtocol; |
101 | 100 |
102 typedef struct _GtkIMHtmlFontDetail { | 101 /* The five elements contained in a FONT tag */ |
102 typedef struct { | |
103 gushort size; | 103 gushort size; |
104 gchar *face; | 104 gchar *face; |
105 gchar *fore; | 105 gchar *fore; |
106 gchar *back; | 106 gchar *back; |
107 gchar *bg; | 107 gchar *bg; |
3607 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | 3607 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, |
3608 rect.y + rect.height); | 3608 rect.y + rect.height); |
3609 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | 3609 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); |
3610 } | 3610 } |
3611 | 3611 |
3612 /* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */ | 3612 /** |
3613 GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id) | 3613 * Destroys and frees a GTK+ IM/HTML scalable image. |
3614 { | 3614 * |
3615 GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); | 3615 * @param scale The GTK+ IM/HTML scalable. |
3616 | 3616 */ |
3617 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; | 3617 static void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) |
3618 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | 3618 { |
3619 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free; | 3619 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; |
3620 | 3620 |
3621 im_image->pixbuf = img; | 3621 g_object_unref(image->pixbuf); |
3622 im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf)); | 3622 g_free(image->filename); |
3623 im_image->width = gdk_pixbuf_get_width(img); | 3623 if (image->filesel) |
3624 im_image->height = gdk_pixbuf_get_height(img); | 3624 gtk_widget_destroy(image->filesel); |
3625 im_image->mark = NULL; | 3625 g_free(scale); |
3626 im_image->filename = g_strdup(filename); | 3626 } |
3627 im_image->id = id; | 3627 |
3628 im_image->filesel = NULL; | 3628 /** |
3629 | 3629 * Destroys and frees a GTK+ IM/HTML scalable animation. |
3630 g_object_ref(img); | 3630 * |
3631 return GTK_IMHTML_SCALABLE(im_image); | 3631 * @param scale The GTK+ IM/HTML scalable. |
3632 } | 3632 */ |
3633 | 3633 static void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale) |
3634 static gboolean | 3634 { |
3635 animate_image_cb(gpointer data) | 3635 GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale; |
3636 { | 3636 |
3637 GtkIMHtmlImage *im_image; | 3637 if (animation->timer > 0) |
3638 int width, height; | 3638 g_source_remove(animation->timer); |
3639 int delay; | 3639 if (animation->iter != NULL) |
3640 | 3640 g_object_unref(animation->iter); |
3641 im_image = data; | 3641 g_object_unref(animation->anim); |
3642 | 3642 |
3643 /* Update the pointer to this GdkPixbuf frame of the animation */ | 3643 gtk_imhtml_image_free(scale); |
3644 if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) { | |
3645 GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter); | |
3646 g_object_unref(G_OBJECT(im_image->pixbuf)); | |
3647 im_image->pixbuf = gdk_pixbuf_copy(pb); | |
3648 | |
3649 /* Update the displayed GtkImage */ | |
3650 width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)); | |
3651 height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image)); | |
3652 if (width > 0 && height > 0) | |
3653 { | |
3654 /* Need to scale the new frame to the same size as the old frame */ | |
3655 GdkPixbuf *tmp; | |
3656 tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR); | |
3657 gtk_image_set_from_pixbuf(im_image->image, tmp); | |
3658 g_object_unref(G_OBJECT(tmp)); | |
3659 } else { | |
3660 /* Display at full-size */ | |
3661 gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf); | |
3662 } | |
3663 } | |
3664 | |
3665 delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100); | |
3666 GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image); | |
3667 | |
3668 return FALSE; | |
3669 } | |
3670 | |
3671 GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id) | |
3672 { | |
3673 GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1); | |
3674 | |
3675 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; | |
3676 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | |
3677 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free; | |
3678 | |
3679 GTK_IMHTML_ANIMATION(im_image)->anim = anim; | |
3680 if (gdk_pixbuf_animation_is_static_image(anim)) { | |
3681 im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim); | |
3682 g_object_ref(im_image->pixbuf); | |
3683 } else { | |
3684 int delay; | |
3685 GdkPixbuf *pb; | |
3686 GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL); | |
3687 pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter); | |
3688 im_image->pixbuf = gdk_pixbuf_copy(pb); | |
3689 delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100); | |
3690 GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image); | |
3691 } | |
3692 im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf)); | |
3693 im_image->width = gdk_pixbuf_animation_get_width(anim); | |
3694 im_image->height = gdk_pixbuf_animation_get_height(anim); | |
3695 im_image->filename = g_strdup(filename); | |
3696 im_image->id = id; | |
3697 | |
3698 g_object_ref(anim); | |
3699 | |
3700 return GTK_IMHTML_SCALABLE(im_image); | |
3701 } | |
3702 | |
3703 void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height) | |
3704 { | |
3705 GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale; | |
3706 | |
3707 if (im_image->width > width || im_image->height > height) { | |
3708 double ratio_w, ratio_h, ratio; | |
3709 int new_h, new_w; | |
3710 GdkPixbuf *new_image = NULL; | |
3711 | |
3712 ratio_w = ((double)width - 2) / im_image->width; | |
3713 ratio_h = ((double)height - 2) / im_image->height; | |
3714 | |
3715 ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h; | |
3716 | |
3717 new_w = (int)(im_image->width * ratio); | |
3718 new_h = (int)(im_image->height * ratio); | |
3719 | |
3720 new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR); | |
3721 gtk_image_set_from_pixbuf(im_image->image, new_image); | |
3722 g_object_unref(G_OBJECT(new_image)); | |
3723 } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) { | |
3724 /* Enough space to show the full-size of the image. */ | |
3725 GdkPixbuf *new_image; | |
3726 | |
3727 new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR); | |
3728 gtk_image_set_from_pixbuf(im_image->image, new_image); | |
3729 g_object_unref(G_OBJECT(new_image)); | |
3730 } | |
3731 } | 3644 } |
3732 | 3645 |
3733 static void | 3646 static void |
3734 image_save_yes_cb(GtkIMHtmlImageSave *save, const char *filename) | 3647 image_save_yes_cb(GtkIMHtmlImageSave *save, const char *filename) |
3735 { | 3648 { |
3932 else | 3845 else |
3933 return FALSE; /* Let clicks go through if we didn't catch anything */ | 3846 return FALSE; /* Let clicks go through if we didn't catch anything */ |
3934 | 3847 |
3935 } | 3848 } |
3936 | 3849 |
3937 static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley) | 3850 /** |
3938 { | 3851 * Rescales a GTK+ IM/HTML scalable image to a given size. |
3939 GdkPixbufAnimation *anim = NULL; | 3852 * |
3940 GtkIMHtmlImageSave *save = NULL; | 3853 * @param scale The GTK+ IM/HTML scalable. |
3941 gboolean ret; | 3854 * @param width The new width. |
3942 | 3855 * @param height The new height. |
3943 if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3) | 3856 */ |
3944 return FALSE; | 3857 static void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height) |
3945 | 3858 { |
3946 anim = gtk_smiley_get_image(smiley); | 3859 GtkIMHtmlImage *im_image = (GtkIMHtmlImage *)scale; |
3947 if (!anim) | 3860 |
3948 return FALSE; | 3861 if (im_image->width > width || im_image->height > height) { |
3949 | 3862 double ratio_w, ratio_h, ratio; |
3950 save = g_new0(GtkIMHtmlImageSave, 1); | 3863 int new_h, new_w; |
3951 save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0); | 3864 GdkPixbuf *new_image = NULL; |
3952 save->data = smiley->data; /* Do not need to memdup here, since the smiley is not | 3865 |
3953 destroyed before this GtkIMHtmlImageSave */ | 3866 ratio_w = ((double)width - 2) / im_image->width; |
3954 save->datasize = smiley->datasize; | 3867 ratio_h = ((double)height - 2) / im_image->height; |
3955 ret = gtk_imhtml_image_clicked(w, event, save); | 3868 |
3956 g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free); | 3869 ratio = (ratio_w < ratio_h) ? ratio_w : ratio_h; |
3957 g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free); | 3870 |
3958 return ret; | 3871 new_w = (int)(im_image->width * ratio); |
3959 } | 3872 new_h = (int)(im_image->height * ratio); |
3960 | 3873 |
3961 void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) | 3874 new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, new_w, new_h, GDK_INTERP_BILINEAR); |
3962 { | 3875 gtk_image_set_from_pixbuf(im_image->image, new_image); |
3963 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | 3876 g_object_unref(G_OBJECT(new_image)); |
3964 | 3877 } else if (gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)) != im_image->width) { |
3965 g_object_unref(image->pixbuf); | 3878 /* Enough space to show the full-size of the image. */ |
3966 g_free(image->filename); | 3879 GdkPixbuf *new_image; |
3967 if (image->filesel) | 3880 |
3968 gtk_widget_destroy(image->filesel); | 3881 new_image = gdk_pixbuf_scale_simple(im_image->pixbuf, im_image->width, im_image->height, GDK_INTERP_BILINEAR); |
3969 g_free(scale); | 3882 gtk_image_set_from_pixbuf(im_image->image, new_image); |
3970 } | 3883 g_object_unref(G_OBJECT(new_image)); |
3971 | 3884 } |
3972 void gtk_imhtml_animation_free(GtkIMHtmlScalable *scale) | 3885 } |
3973 { | 3886 |
3974 GtkIMHtmlAnimation *animation = (GtkIMHtmlAnimation *)scale; | 3887 /** |
3975 | 3888 * Adds a GTK+ IM/HTML scalable image to a given GTK+ IM/HTML at a given iter. |
3976 if (animation->timer > 0) | 3889 * |
3977 g_source_remove(animation->timer); | 3890 * @param scale The GTK+ IM/HTML scalable. |
3978 if (animation->iter != NULL) | 3891 * @param imhtml The GTK+ IM/HTML. |
3979 g_object_unref(animation->iter); | 3892 * @param iter The GtkTextIter at which to add the scalable. |
3980 g_object_unref(animation->anim); | 3893 */ |
3981 | 3894 static void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) |
3982 gtk_imhtml_image_free(scale); | |
3983 } | |
3984 | |
3985 void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
3986 { | 3895 { |
3987 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | 3896 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; |
3988 GtkWidget *box = gtk_event_box_new(); | 3897 GtkWidget *box = gtk_event_box_new(); |
3989 char *tag; | 3898 char *tag; |
3990 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | 3899 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); |
4006 | 3915 |
4007 save = g_new0(GtkIMHtmlImageSave, 1); | 3916 save = g_new0(GtkIMHtmlImageSave, 1); |
4008 save->image = scale; | 3917 save->image = scale; |
4009 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), save); | 3918 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), save); |
4010 g_object_set_data_full(G_OBJECT(box), "image-save-data", save, (GDestroyNotify)g_free); | 3919 g_object_set_data_full(G_OBJECT(box), "image-save-data", save, (GDestroyNotify)g_free); |
3920 } | |
3921 | |
3922 /** | |
3923 * Creates and returns a new GTK+ IM/HTML scalable object with an image. | |
3924 * | |
3925 * @param img A GdkPixbuf of the image to add. | |
3926 * @param filename The filename to associate with the image. | |
3927 * @param id The id to associate with the image. | |
3928 * | |
3929 * @return A new IM/HTML Scalable object with an image. | |
3930 */ | |
3931 static GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename, int id) | |
3932 { | |
3933 GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); | |
3934 | |
3935 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; | |
3936 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | |
3937 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free; | |
3938 | |
3939 im_image->pixbuf = img; | |
3940 im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf)); | |
3941 im_image->width = gdk_pixbuf_get_width(img); | |
3942 im_image->height = gdk_pixbuf_get_height(img); | |
3943 im_image->mark = NULL; | |
3944 im_image->filename = g_strdup(filename); | |
3945 im_image->id = id; | |
3946 im_image->filesel = NULL; | |
3947 | |
3948 g_object_ref(img); | |
3949 return GTK_IMHTML_SCALABLE(im_image); | |
3950 } | |
3951 | |
3952 static gboolean | |
3953 animate_image_cb(gpointer data) | |
3954 { | |
3955 GtkIMHtmlImage *im_image; | |
3956 int width, height; | |
3957 int delay; | |
3958 | |
3959 im_image = data; | |
3960 | |
3961 /* Update the pointer to this GdkPixbuf frame of the animation */ | |
3962 if (gdk_pixbuf_animation_iter_advance(GTK_IMHTML_ANIMATION(im_image)->iter, NULL)) { | |
3963 GdkPixbuf *pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter); | |
3964 g_object_unref(G_OBJECT(im_image->pixbuf)); | |
3965 im_image->pixbuf = gdk_pixbuf_copy(pb); | |
3966 | |
3967 /* Update the displayed GtkImage */ | |
3968 width = gdk_pixbuf_get_width(gtk_image_get_pixbuf(im_image->image)); | |
3969 height = gdk_pixbuf_get_height(gtk_image_get_pixbuf(im_image->image)); | |
3970 if (width > 0 && height > 0) | |
3971 { | |
3972 /* Need to scale the new frame to the same size as the old frame */ | |
3973 GdkPixbuf *tmp; | |
3974 tmp = gdk_pixbuf_scale_simple(im_image->pixbuf, width, height, GDK_INTERP_BILINEAR); | |
3975 gtk_image_set_from_pixbuf(im_image->image, tmp); | |
3976 g_object_unref(G_OBJECT(tmp)); | |
3977 } else { | |
3978 /* Display at full-size */ | |
3979 gtk_image_set_from_pixbuf(im_image->image, im_image->pixbuf); | |
3980 } | |
3981 } | |
3982 | |
3983 delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100); | |
3984 GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image); | |
3985 | |
3986 return FALSE; | |
3987 } | |
3988 | |
3989 /** | |
3990 * Creates and returns a new GTK+ IM/HTML scalable object with an | |
3991 * animated image. | |
3992 * | |
3993 * @param img A GdkPixbufAnimation of the image to add. | |
3994 * @param filename The filename to associate with the image. | |
3995 * @param id The id to associate with the image. | |
3996 * | |
3997 * @return A new IM/HTML Scalable object with an image. | |
3998 */ | |
3999 /* | |
4000 * TODO: All this animation code could be combined much better with | |
4001 * the image code. It couldn't be done when it was written | |
4002 * because it requires breaking backward compatibility. It | |
4003 * would be good to do it for 3.0.0. | |
4004 */ | |
4005 static GtkIMHtmlScalable *gtk_imhtml_animation_new(GdkPixbufAnimation *anim, const gchar *filename, int id) | |
4006 { | |
4007 GtkIMHtmlImage *im_image = (GtkIMHtmlImage *) g_new0(GtkIMHtmlAnimation, 1); | |
4008 | |
4009 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; | |
4010 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | |
4011 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_animation_free; | |
4012 | |
4013 GTK_IMHTML_ANIMATION(im_image)->anim = anim; | |
4014 if (gdk_pixbuf_animation_is_static_image(anim)) { | |
4015 im_image->pixbuf = gdk_pixbuf_animation_get_static_image(anim); | |
4016 g_object_ref(im_image->pixbuf); | |
4017 } else { | |
4018 int delay; | |
4019 GdkPixbuf *pb; | |
4020 GTK_IMHTML_ANIMATION(im_image)->iter = gdk_pixbuf_animation_get_iter(anim, NULL); | |
4021 pb = gdk_pixbuf_animation_iter_get_pixbuf(GTK_IMHTML_ANIMATION(im_image)->iter); | |
4022 im_image->pixbuf = gdk_pixbuf_copy(pb); | |
4023 delay = MIN(gdk_pixbuf_animation_iter_get_delay_time(GTK_IMHTML_ANIMATION(im_image)->iter), 100); | |
4024 GTK_IMHTML_ANIMATION(im_image)->timer = g_timeout_add(delay, animate_image_cb, im_image); | |
4025 } | |
4026 im_image->image = GTK_IMAGE(gtk_image_new_from_pixbuf(im_image->pixbuf)); | |
4027 im_image->width = gdk_pixbuf_animation_get_width(anim); | |
4028 im_image->height = gdk_pixbuf_animation_get_height(anim); | |
4029 im_image->filename = g_strdup(filename); | |
4030 im_image->id = id; | |
4031 | |
4032 g_object_ref(anim); | |
4033 | |
4034 return GTK_IMHTML_SCALABLE(im_image); | |
4011 } | 4035 } |
4012 | 4036 |
4013 GtkIMHtmlScalable *gtk_imhtml_hr_new() | 4037 GtkIMHtmlScalable *gtk_imhtml_hr_new() |
4014 { | 4038 { |
4015 GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr)); | 4039 GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr)); |
4930 imhtml->animations->head = g_list_delete_link(imhtml->animations->head, l); | 4954 imhtml->animations->head = g_list_delete_link(imhtml->animations->head, l); |
4931 imhtml->num_animations--; | 4955 imhtml->num_animations--; |
4932 } | 4956 } |
4933 l = next; | 4957 l = next; |
4934 } | 4958 } |
4959 } | |
4960 | |
4961 static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley) | |
4962 { | |
4963 GdkPixbufAnimation *anim = NULL; | |
4964 GtkIMHtmlImageSave *save = NULL; | |
4965 gboolean ret; | |
4966 | |
4967 if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3) | |
4968 return FALSE; | |
4969 | |
4970 anim = gtk_smiley_get_image(smiley); | |
4971 if (!anim) | |
4972 return FALSE; | |
4973 | |
4974 save = g_new0(GtkIMHtmlImageSave, 1); | |
4975 save->image = (GtkIMHtmlScalable *)gtk_imhtml_animation_new(anim, smiley->smile, 0); | |
4976 save->data = smiley->data; /* Do not need to memdup here, since the smiley is not | |
4977 destroyed before this GtkIMHtmlImageSave */ | |
4978 save->datasize = smiley->datasize; | |
4979 ret = gtk_imhtml_image_clicked(w, event, save); | |
4980 g_object_set_data_full(G_OBJECT(w), "image-data", save->image, (GDestroyNotify)gtk_imhtml_animation_free); | |
4981 g_object_set_data_full(G_OBJECT(w), "image-save-data", save, (GDestroyNotify)g_free); | |
4982 return ret; | |
4935 } | 4983 } |
4936 | 4984 |
4937 void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char *smiley, GtkTextIter *iter) | 4985 void gtk_imhtml_insert_smiley_at_iter(GtkIMHtml *imhtml, const char *sml, char *smiley, GtkTextIter *iter) |
4938 { | 4986 { |
4939 GdkPixbuf *pixbuf = NULL; | 4987 GdkPixbuf *pixbuf = NULL; |