diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index da415d25..374720bb 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -58,7 +58,7 @@ #include #endif -GdkPixmap *channelwin_pix; +cairo_surface_t *channelwin_pix; #ifdef USE_LIBCANBERRA static ca_context *ca_con; diff --git a/src/fe-gtk/fe-gtk.h b/src/fe-gtk/fe-gtk.h index cfb74035..f8617517 100644 --- a/src/fe-gtk/fe-gtk.h +++ b/src/fe-gtk/fe-gtk.h @@ -30,6 +30,7 @@ #include #include +#include #ifdef HAVE_GTK_MAC #include @@ -178,8 +179,8 @@ typedef struct session_gui } session_gui; -extern GdkPixmap *channelwin_pix; -extern GdkPixmap *dialogwin_pix; +extern cairo_surface_t *channelwin_pix; +extern cairo_surface_t *dialogwin_pix; #define SPELL_ENTRY_GET_TEXT(e) ((char *)(gtk_entry_get_text (GTK_ENTRY(e)))) #define SPELL_ENTRY_SET_TEXT(e,txt) gtk_entry_set_text(GTK_ENTRY(e),txt) diff --git a/src/fe-gtk/pixmaps.c b/src/fe-gtk/pixmaps.c index 3e613684..132fc325 100644 --- a/src/fe-gtk/pixmaps.c +++ b/src/fe-gtk/pixmaps.c @@ -28,6 +28,7 @@ #include #include +#include GdkPixbuf *pix_ulist_voice; GdkPixbuf *pix_ulist_halfop; @@ -49,26 +50,89 @@ GdkPixbuf *pix_tree_util; GdkPixbuf *pix_book; GdkPixbuf *pix_zoitechat; -static GdkPixmap * +static cairo_surface_t * +pixbuf_to_cairo_surface (GdkPixbuf *pixbuf) +{ + cairo_surface_t *surface; + gboolean has_alpha; + int width; + int height; + int src_stride; + int dest_stride; + int n_channels; + const guchar *src_pixels; + unsigned char *dest_pixels; + int x; + int y; + + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) + { + cairo_surface_destroy (surface); + return NULL; + } + + src_stride = gdk_pixbuf_get_rowstride (pixbuf); + src_pixels = gdk_pixbuf_get_pixels (pixbuf); + dest_stride = cairo_image_surface_get_stride (surface); + dest_pixels = cairo_image_surface_get_data (surface); + + for (y = 0; y < height; y++) + { + const guchar *src_row = src_pixels + (y * src_stride); + guint32 *dest_row = (guint32 *)(dest_pixels + (y * dest_stride)); + + for (x = 0; x < width; x++) + { + const guchar *src = src_row + (x * n_channels); + guchar alpha = has_alpha ? src[3] : 0xff; + guchar red = src[0]; + guchar green = src[1]; + guchar blue = src[2]; + guchar premul_red = (guchar)((red * alpha + 127) / 255); + guchar premul_green = (guchar)((green * alpha + 127) / 255); + guchar premul_blue = (guchar)((blue * alpha + 127) / 255); + + dest_row[x] = ((guint32)alpha << 24) | + ((guint32)premul_red << 16) | + ((guint32)premul_green << 8) | + ((guint32)premul_blue); + } + } + + cairo_surface_mark_dirty (surface); + + return surface; +} + +static cairo_surface_t * pixmap_load_from_file_real (char *file) { GdkPixbuf *img; - GdkPixmap *pixmap; + cairo_surface_t *surface; img = gdk_pixbuf_new_from_file (file, 0); if (!img) return NULL; - gdk_pixbuf_render_pixmap_and_mask (img, &pixmap, NULL, 128); + + surface = pixbuf_to_cairo_surface (img); g_object_unref (img); - return pixmap; + return surface; } -GdkPixmap * +cairo_surface_t * pixmap_load_from_file (char *filename) { char buf[256]; - GdkPixmap *pix; + cairo_surface_t *pix; if (filename[0] == '\0') return NULL; diff --git a/src/fe-gtk/pixmaps.h b/src/fe-gtk/pixmaps.h index a8ef6009..b97fe946 100644 --- a/src/fe-gtk/pixmaps.h +++ b/src/fe-gtk/pixmaps.h @@ -20,6 +20,8 @@ #ifndef HEXCHAT_PIXMAPS_H #define HEXCHAT_PIXMAPS_H +#include + extern GdkPixbuf *pix_ulist_voice; extern GdkPixbuf *pix_ulist_halfop; extern GdkPixbuf *pix_ulist_op; @@ -40,7 +42,7 @@ extern GdkPixbuf *pix_tree_util; extern GdkPixbuf *pix_book; extern GdkPixbuf *pix_zoitechat; -extern GdkPixmap *pixmap_load_from_file (char *file); +extern cairo_surface_t *pixmap_load_from_file (char *file); extern void pixmaps_init (void); #endif diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c index 91f1a486..91948674 100644 --- a/src/fe-gtk/setup.c +++ b/src/fe-gtk/setup.c @@ -2449,7 +2449,7 @@ setup_apply_real (int new_pix, int do_ulist, int do_layout, int do_identd) if (new_pix) { if (channelwin_pix) - g_object_unref (channelwin_pix); + cairo_surface_destroy (channelwin_pix); channelwin_pix = pixmap_load_from_file (prefs.hex_text_background); } diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index 64b6a5b7..62a7ad7d 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -780,7 +780,6 @@ gtk_xtext_realize (GtkWidget * widget) xtext->resize_cursor = gdk_cursor_new_for_display (gdk_window_get_display (widget->window), GDK_LEFT_SIDE); gdk_window_set_back_pixmap (widget->window, NULL, FALSE); - widget->style = gtk_style_attach (widget->style, widget->window); backend_init (xtext); } @@ -3571,7 +3570,7 @@ gtk_xtext_set_font (GtkXText *xtext, char *name) } void -gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap) +gtk_xtext_set_background (GtkXText * xtext, cairo_surface_t *surface) { if (xtext->background_surface) { @@ -3580,14 +3579,12 @@ gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap) } dontscroll (xtext->buffer); - if (pixmap != 0) + if (surface) { - cairo_t *cr = gdk_cairo_create (pixmap); - xtext->background_surface = cairo_surface_reference (cairo_get_target (cr)); - cairo_destroy (cr); + xtext->background_surface = cairo_surface_reference (surface); } - if (pixmap != 0 && gtk_widget_get_realized (GTK_WIDGET(xtext))) + if (surface && gtk_widget_get_realized (GTK_WIDGET(xtext))) { xtext->ts_x = xtext->ts_y = 0; } diff --git a/src/fe-gtk/xtext.h b/src/fe-gtk/xtext.h index 789aabe8..3663413c 100644 --- a/src/fe-gtk/xtext.h +++ b/src/fe-gtk/xtext.h @@ -21,6 +21,7 @@ #define HEXCHAT_XTEXT_H #include +#include #define GTK_TYPE_XTEXT (gtk_xtext_get_type ()) #define GTK_XTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_XTEXT, GtkXText)) @@ -268,7 +269,7 @@ void gtk_xtext_append_indent (xtext_buffer *buf, unsigned char *right_text, int right_len, time_t stamp); int gtk_xtext_set_font (GtkXText *xtext, char *name); -void gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap); +void gtk_xtext_set_background (GtkXText * xtext, cairo_surface_t *surface); void gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]); void gtk_xtext_clear (xtext_buffer *buf, int lines); void gtk_xtext_save (GtkXText * xtext, int fh);