[xchat-gnome] bug 392860 - X Composite-friendly RGBA transparency



commit 66b64dd59644f218096cf3508d45ac0b61497abc
Author: Maia Kozheva <sikon ubuntu com>
Date:   Sun Sep 12 08:53:07 2010 +0530

    bug 392860 - X Composite-friendly RGBA transparency

 src/fe-gnome/conversation-panel.c |   13 ++++-
 src/fe-gnome/main-window.c        |    8 ++-
 src/fe-gnome/xtext.c              |  111 +++++++++++++++++-------------------
 src/fe-gnome/xtext.h              |    2 +
 4 files changed, 72 insertions(+), 62 deletions(-)
---
diff --git a/src/fe-gnome/conversation-panel.c b/src/fe-gnome/conversation-panel.c
index e6feba4..fb013c7 100644
--- a/src/fe-gnome/conversation-panel.c
+++ b/src/fe-gnome/conversation-panel.c
@@ -573,10 +573,12 @@ conversation_panel_set_background (ConversationPanel *panel)
 	if (background_type == 0) {
 		gtk_xtext_set_tint (GTK_XTEXT (panel->priv->xtext), 0, 0, 0);
 		gtk_xtext_set_background (GTK_XTEXT (panel->priv->xtext), NULL, FALSE);
+		gtk_xtext_set_alpha (GTK_XTEXT (panel->priv->xtext), 1.0);
 	} else if (background_type == 1) {
 		gchar *filename = gconf_client_get_string (client, "/apps/xchat/main_window/background_image", NULL);
 		gtk_xtext_set_tint (GTK_XTEXT (panel->priv->xtext), 0, 0, 0);
 		gtk_xtext_set_background (GTK_XTEXT (panel->priv->xtext), NULL, FALSE);
+		gtk_xtext_set_alpha (GTK_XTEXT (panel->priv->xtext), 1.0);
 		if (filename) {
 			GdkPixbuf *pixbuf;
 			pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
@@ -599,8 +601,15 @@ conversation_panel_set_background (ConversationPanel *panel)
 	} else {
 		float transparency = gconf_client_get_float (client, "/apps/xchat/main_window/background_transparency", NULL);
 		int value = 255 - ((int) (transparency * 255));
-		gtk_xtext_set_tint (GTK_XTEXT (panel->priv->xtext), value, value, value);
-		gtk_xtext_set_background (GTK_XTEXT (panel->priv->xtext), NULL, TRUE);
+
+		if (gdk_drawable_get_visual (gui.main_window->window)->depth == 32) {
+			gtk_xtext_set_tint (GTK_XTEXT (panel->priv->xtext), 0, 0, 0);
+			gtk_xtext_set_background (GTK_XTEXT (panel->priv->xtext), NULL, FALSE);
+			gtk_xtext_set_alpha (GTK_XTEXT (panel->priv->xtext), transparency);
+		} else {
+			gtk_xtext_set_tint (GTK_XTEXT (panel->priv->xtext), value, value, value);
+			gtk_xtext_set_background (GTK_XTEXT (panel->priv->xtext), NULL, TRUE);
+		}
 	}
 	g_object_unref (client);
 }
diff --git a/src/fe-gnome/main-window.c b/src/fe-gnome/main-window.c
index b1c50f9..3ec7b56 100644
--- a/src/fe-gnome/main-window.c
+++ b/src/fe-gnome/main-window.c
@@ -150,9 +150,15 @@ initialize_main_window (void)
 	GtkWidget *close, *menu_vbox, *widget;
 	GtkSizeGroup *group;
 	GtkAction *action;
-    GConfClient *client;
+	GConfClient *client;
+	GdkColormap *colormap;
 
 	gui.main_window = glade_xml_get_widget (gui.xml, "xchat-gnome");
+
+	colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (gui.main_window));
+	if (colormap != NULL)
+		gtk_widget_set_colormap (gui.main_window, colormap);
+
 	g_signal_connect (G_OBJECT (gui.main_window), "delete-event",    G_CALLBACK (on_main_window_close),     NULL);
 	g_signal_connect (G_OBJECT (gui.main_window), "focus-in-event",  G_CALLBACK (on_main_window_focus_in),  NULL);
 	g_signal_connect (G_OBJECT (gui.main_window), "configure-event", G_CALLBACK (on_main_window_configure), NULL);
diff --git a/src/fe-gnome/xtext.c b/src/fe-gnome/xtext.c
index 51503f8..a7e2caf 100644
--- a/src/fe-gnome/xtext.c
+++ b/src/fe-gnome/xtext.c
@@ -180,50 +180,48 @@ gtk_xtext_text_width_8bit (GtkXText *xtext, unsigned char *str, int len)
 	return width;
 }
 
-#ifdef WIN32
-
 static void
-win32_draw_bg (GtkXText *xtext, int x, int y, int width, int height)
+xtext_color_to_cairo(GtkXText *xtext, gulong pixel, double *rgb)
 {
-	HDC hdc;
-	HWND hwnd;
-	HRGN rgn;
+	GdkColor color;
+	GdkColormap * colormap = gtk_widget_get_colormap (&xtext->widget);
+	gdk_colormap_query_color (colormap, pixel, &color);
+	rgb[0] = color.red / 65535.0;
+	rgb[1] = color.green / 65535.0;
+	rgb[2] = color.blue / 65535.0;
+}
 
-	if (xtext->shaded)
-	{
-		/* xtext->pixmap is really a GdkImage, created in win32_tint() */
-		gdk_draw_image (xtext->draw_buf, xtext->bgc, (GdkImage*)xtext->pixmap,
-							 x, y, x, y, width, height);
-	} else
-	{
-		hwnd = GDK_WINDOW_HWND (xtext->draw_buf);
-		hdc = GetDC (hwnd);
+static void
+xtext_draw_rectangle (GtkXText *xtext, cairo_t *cr, gulong pixel, int x, int y, int width, int height)
+{
+	GdkRectangle rect = { x, y, width, height };
+	double color[3];
 
-		rgn = CreateRectRgn (x, y, x + width, y + height);
-		SelectClipRgn (hdc, rgn);
+	xtext_color_to_cairo (xtext, pixel, color);
 
-		PaintDesktop (hdc);
+	cairo_save (cr);
+	cairo_set_source_rgba (cr, color[0], color[1], color[2], xtext->alpha);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+	gdk_cairo_rectangle (cr, &rect);
+	cairo_fill (cr);
+	cairo_restore (cr);
 
-		ReleaseDC (hwnd, hdc);
-		DeleteObject (rgn);
-	}
 }
 
 static void
 xtext_draw_bg (GtkXText *xtext, int x, int y, int width, int height)
 {
-	if (xtext->transparent)
-		win32_draw_bg (xtext, x, y, width, height);
-	else
-		gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1, x, y, width, height);
+	cairo_t *cr;
+	cr = gdk_cairo_create (xtext->widget.window);
+	xtext_draw_rectangle(xtext, cr, xtext->palette[XTEXT_BG], x, y, width, height);
+	cairo_destroy (cr);
 }
 
-#else
-
-#define xtext_draw_bg(xt,x,y,w,h) gdk_draw_rectangle(xt->draw_buf, xt->bgc, \
-																	  1,x,y,w,h);
-
-#endif
+void
+gtk_xtext_set_alpha (GtkXText *xtext, double alpha)
+{
+	xtext->alpha = alpha;
+}
 
 /* ========================================= */
 /* ========== XFT 1 and 2 BACKEND ========== */
@@ -555,29 +553,15 @@ backend_get_char_width (GtkXText *xtext, unsigned char *str, int *mbl_ret)
 /* simplified version of gdk_draw_layout_line_with_colors() */
 
 static void 
-xtext_draw_layout_line (GdkDrawable      *drawable,
-								GdkGC            *gc,
+xtext_draw_layout_line (cairo_t          *cr,
 								gint              x, 
 								gint              y,
 								PangoLayoutLine  *line)
 {
-	GSList *tmp_list = line->runs;
-	PangoRectangle logical_rect;
-	gint x_off = 0;
-
-	while (tmp_list)
-	{
-		PangoLayoutRun *run = tmp_list->data;
-
-		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
-											 NULL, &logical_rect);
-
-		gdk_draw_glyphs (drawable, gc, run->item->analysis.font,
-							  x + x_off / PANGO_SCALE, y, run->glyphs);
-
-		x_off += logical_rect.width;
-		tmp_list = tmp_list->next;
-	}
+	cairo_save (cr);
+	cairo_move_to (cr, x, y);
+	pango_cairo_show_layout_line (cr, line);
+	cairo_restore (cr);
 }
 
 static void
@@ -587,6 +571,10 @@ backend_draw_text (GtkXText *xtext, int dofill, GdkGC *gc, int x, int y,
 	GdkGCValues val;
 	GdkColor col;
 	PangoLayoutLine *line;
+	cairo_t *cr;
+	double colors[3];
+
+	cr = gdk_cairo_create (xtext->draw_buf);
 
 #ifdef ITALIC
 	if (xtext->italics)
@@ -594,6 +582,7 @@ backend_draw_text (GtkXText *xtext, int dofill, GdkGC *gc, int x, int y,
 #endif
 
 	pango_layout_set_text (xtext->layout, str, len);
+	gdk_gc_get_values (gc, &val);
 
 	if (dofill)
 	{
@@ -604,30 +593,33 @@ backend_draw_text (GtkXText *xtext, int dofill, GdkGC *gc, int x, int y,
 		else
 #endif
 		{
-			gdk_gc_get_values (gc, &val);
 			col.pixel = val.background.pixel;
-			gdk_gc_set_foreground (gc, &col);
-			gdk_draw_rectangle (xtext->draw_buf, gc, 1, x, y -
-									  xtext->font->ascent, str_width, xtext->fontsize);
-			col.pixel = val.foreground.pixel;
-			gdk_gc_set_foreground (gc, &col);
+
+			xtext_draw_rectangle (xtext, cr, col.pixel, x, y -
+								  xtext->font->ascent, str_width, xtext->fontsize);
+
 		}
 	}
 
+	col.pixel = val.foreground.pixel;
+	xtext_color_to_cairo (xtext, col.pixel, colors);
+	cairo_set_source_rgb (cr, colors[0], colors[1], colors[2]);
 	line = pango_layout_get_lines (xtext->layout)->data;
 
-	xtext_draw_layout_line (xtext->draw_buf, gc, x, y, line);
+	xtext_draw_layout_line (cr, x, y, line);
 
 	if (xtext->overdraw)
-		xtext_draw_layout_line (xtext->draw_buf, gc, x, y, line);
+		xtext_draw_layout_line (cr, x, y, line);
 
 	if (xtext->bold)
-		xtext_draw_layout_line (xtext->draw_buf, gc, x + 1, y, line);
+		xtext_draw_layout_line (cr, x + 1, y, line);
 
 #ifdef ITALIC
 	if (xtext->italics)
 		pango_layout_set_font_description (xtext->layout, xtext->font->font);
 #endif
+
+	cairo_destroy (cr);
 }
 
 /*static void
@@ -828,6 +820,7 @@ gtk_xtext_new (GdkColor palette[], int separator)
 	xtext->wordwrap = TRUE;
 	xtext->buffer = gtk_xtext_buffer_new (xtext);
 	xtext->orig_buffer = xtext->buffer;
+	xtext->alpha = 1.0;
 
 	gtk_widget_set_double_buffered (GTK_WIDGET (xtext), FALSE);
 	gtk_xtext_set_palette (xtext, palette);
diff --git a/src/fe-gnome/xtext.h b/src/fe-gnome/xtext.h
index 83e7c8d..7aa6722 100644
--- a/src/fe-gnome/xtext.h
+++ b/src/fe-gnome/xtext.h
@@ -231,6 +231,7 @@ struct _GtkXText
 	unsigned int wordwrap:1;
 	unsigned int overdraw:1;
 	unsigned int ignore_hidden:1;	/* rawlog uses this */
+	double alpha;
 
 	gchar *current_word;
 };
@@ -250,6 +251,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_alpha (GtkXText *xtext, double alpha);
 void gtk_xtext_set_background (GtkXText * xtext, GdkPixmap * pixmap, gboolean trans);
 void gtk_xtext_set_palette (GtkXText * xtext, GdkColor palette[]);
 void gtk_xtext_clear (xtext_buffer *buf);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]