Jamie McCracken wrote: > I have attached a patch to > http://bugzilla.openedhand.com/show_bug.cgi?id=412 > > This should give you a transparent stage free of any defects if you have > nvidia graphics by simply setting the alpha component of the stage > colour to a value less than 255. > > Patch also solves the annoying blending, masking and painting issues > that plagued previous attempts at this > > Patch is ready to be applied so it would be nice to get this into > Clutter 1.0 if practical
That's great. Since I like to have this feature accessable from the Perl bindings I backported your patch to the current stable version 0.8.8. Your patch applied fine besides references to cogl_color_get_alpha_float(), which could be easily resolved by copying the code inline. BTW: I think on this call is a small C syntax error in the gles/cogl.c file (an odd closed bracked). Attached you find the patch file which applies cleanly to the current 0.8.8 release. To get the feature from Perl I hacked a new method into Clutter.xs (which is indeed a hack, because it wraps the call to clutter-x11 at the wrong position; this was easier because clutter-x11 isn't bound to Perl yet). But with this patch I could get a transparent stage on my desktop. Great! It's just important to load the Clutter module this way: use Clutter; Clutter->enable_transparent_stage; Clutter->init; because the transparency enabling stuff needs to be done before init(). The Perl binding patch is attached as well. I don't know if this stuff is worth adding to Bugzilla. If yes, just tell me. Regards, Jörn -- LINUX - Linux Is Not gnU linuX
diff -urN Clutter-0.820/t/ClutterStage.t Clutter-0.820.patched/t/ClutterStage.t
--- Clutter-0.820/t/ClutterStage.t 2007-08-08 15:38:01.000000000 +0200
+++ Clutter-0.820.patched/t/ClutterStage.t 2009-03-07 12:42:32.000000000
+0100
@@ -5,7 +5,7 @@
isa_ok($stage, 'Clutter::Group', 'is a plane');
isa_ok($stage, 'Clutter::Stage', 'no, is a Clutter::Stage');
-my $color = Clutter::Color->new(255, 0, 0, 0);
+my $color = Clutter::Color->new(255, 0, 0, 255);
$stage->set_color($color);
is($stage->get_color->red, 255, 'check set color (red)');
isnt($stage->get_color->green, 255, 'check set color (green)');
diff -urN Clutter-0.820/t/ClutterStageTrans.t
Clutter-0.820.patched/t/ClutterStageTrans.t
--- Clutter-0.820/t/ClutterStageTrans.t 1970-01-01 01:00:00.000000000 +0100
+++ Clutter-0.820.patched/t/ClutterStageTrans.t 2009-03-07 12:42:58.000000000
+0100
@@ -0,0 +1,29 @@
+use Clutter;
+Clutter->enable_transparent_stage();
+Clutter->init;
+
+use Clutter::TestHelper tests => 9;
+
+my $stage = Clutter::Stage->get_default;
+isa_ok($stage, 'Clutter::Actor', 'is a bird');
+isa_ok($stage, 'Clutter::Group', 'is a plane');
+isa_ok($stage, 'Clutter::Stage', 'no, is a Clutter::Stage');
+
+my $color = Clutter::Color->new(255, 0, 0, 255);
+is($color->red, 255, 'check color (red)');
+$stage->set_color($color);
+is($stage->get_color->red, 255, 'check set color (red)');
+isnt($stage->get_color->green, 255, 'check set color (green)');
+
+my $trans = Clutter::Color->new(128, 0, 0, 128);
+$stage->set_color($trans);
+is($stage->get_color->red, 64, 'check set color (red trans)');
+
+$stage->set_size(800, 600);
+is($stage->get_width, 800, 'check width');
+isnt($stage->get_height, 800, 'check height');
+
+__END__
+
+Copyright (C) 2006 OpenedHand Ltd. See the file AUTHORS for the full list.
+See LICENSE for more information.
diff -urN Clutter-0.820/xs/Clutter.xs Clutter-0.820.patched/xs/Clutter.xs
--- Clutter-0.820/xs/Clutter.xs 2008-07-17 19:19:57.000000000 +0200
+++ Clutter-0.820.patched/xs/Clutter.xs 2009-03-07 11:55:22.000000000 +0100
@@ -361,3 +361,7 @@
C_ARGS:
/* void */
+void
+clutter_enable_transparent_stage(class=NULL)
+ CODE:
+ clutter_x11_enable_transparent_stage();
diff -ru clutter-0.8.8/clutter/clutter-stage.c
clutter-0.8.8.patched/clutter/clutter-stage.c
--- clutter-0.8.8/clutter/clutter-stage.c 2009-02-20 16:41:39.000000000
+0100
+++ clutter-0.8.8.patched/clutter/clutter-stage.c 2009-03-07
11:02:03.000000000 +0100
@@ -789,13 +789,19 @@
const ClutterColor *color)
{
ClutterStagePrivate *priv;
-
+ gfloat mul;
+
g_return_if_fail (CLUTTER_IS_STAGE (stage));
g_return_if_fail (color != NULL);
+ mul = color->alpha / 255.0;
+
priv = stage->priv;
- priv->color = *color;
+ priv->color.red = mul * color->red;
+ priv->color.green = mul * color->green;
+ priv->color.blue = mul * color->blue;
+ priv->color.alpha = color->alpha;
if (CLUTTER_ACTOR_IS_VISIBLE (stage))
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
diff -ru clutter-0.8.8/clutter/cogl/gl/cogl.c
clutter-0.8.8.patched/clutter/cogl/gl/cogl.c
--- clutter-0.8.8/clutter/cogl/gl/cogl.c 2009-02-20 16:41:39.000000000
+0100
+++ clutter-0.8.8.patched/clutter/cogl/gl/cogl.c 2009-03-07
11:38:29.000000000 +0100
@@ -174,7 +174,7 @@
GE( glClearColor (((float) color->red / 0xff * 1.0),
((float) color->green / 0xff * 1.0),
((float) color->blue / 0xff * 1.0),
- 0.0) );
+ ((float) color->alpha / 0xff * 1.0)));
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable (GL_LIGHTING);
diff -ru clutter-0.8.8/clutter/cogl/gl/cogl-context.c
clutter-0.8.8.patched/clutter/cogl/gl/cogl-context.c
--- clutter-0.8.8/clutter/cogl/gl/cogl-context.c 2009-02-20
16:41:39.000000000 +0100
+++ clutter-0.8.8.patched/clutter/cogl/gl/cogl-context.c 2009-03-07
11:02:03.000000000 +0100
@@ -102,7 +102,6 @@
/* Init OpenGL state */
GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
- GE( glColorMask (TRUE, TRUE, TRUE, FALSE) );
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
cogl_enable (0);
diff -ru clutter-0.8.8/clutter/cogl/gles/cogl.c
clutter-0.8.8.patched/clutter/cogl/gles/cogl.c
--- clutter-0.8.8/clutter/cogl/gles/cogl.c 2009-02-20 16:41:39.000000000
+0100
+++ clutter-0.8.8.patched/clutter/cogl/gles/cogl.c 2009-03-07
11:28:22.000000000 +0100
@@ -95,7 +95,7 @@
cogl_wrap_glClearColorx ((color->red << 16) / 0xff,
(color->green << 16) / 0xff,
(color->blue << 16) / 0xff,
- 0xff);
+ (float) color->alpha / 255.0));
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
cogl_wrap_glDisable (GL_LIGHTING);
diff -ru clutter-0.8.8/clutter/cogl/gles/cogl-context.c
clutter-0.8.8.patched/clutter/cogl/gles/cogl-context.c
--- clutter-0.8.8/clutter/cogl/gles/cogl-context.c 2009-02-20
16:41:39.000000000 +0100
+++ clutter-0.8.8.patched/clutter/cogl/gles/cogl-context.c 2009-03-07
11:02:03.000000000 +0100
@@ -80,7 +80,6 @@
/* Init OpenGL state */
GE( cogl_wrap_glTexEnvx (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
- GE( glColorMask (TRUE, TRUE, TRUE, FALSE) );
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
cogl_enable (0);
diff -ru clutter-0.8.8/clutter/glx/clutter-stage-glx.c
clutter-0.8.8.patched/clutter/glx/clutter-stage-glx.c
--- clutter-0.8.8/clutter/glx/clutter-stage-glx.c 2009-02-20
16:41:39.000000000 +0100
+++ clutter-0.8.8.patched/clutter/glx/clutter-stage-glx.c 2009-03-07
11:02:03.000000000 +0100
@@ -47,6 +47,9 @@
#include <GL/glx.h>
#include <GL/gl.h>
+#include <X11/extensions/Xrender.h>
+
+
static void clutter_stage_window_iface_init (ClutterStageWindowIface *iface);
G_DEFINE_TYPE_WITH_CODE (ClutterStageGLX,
@@ -106,6 +109,69 @@
CLUTTER_MARK ();
}
+static XVisualInfo *
+get_argb_visual_info (ClutterStageX11 *stage_x11)
+{
+
+ GLXFBConfig *fbconfigs;
+ int numfbconfigs, render_event_base, render_error_base, i;
+ XVisualInfo *visinfo = NULL;
+ XRenderPictFormat *pictFormat = NULL;
+
+ /* Make sure we have the RENDER extension */
+ if(!XRenderQueryExtension(stage_x11->xdpy,
+ &render_event_base, &render_error_base))
+ return None;
+
+
+ int attrib[] =
+ {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
+ GLX_RED_SIZE, 8,
+ GLX_GREEN_SIZE, 8,
+ GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DOUBLEBUFFER, True,
+ GLX_DEPTH_SIZE, 1,
+ None
+ };
+
+
+ fbconfigs = glXChooseFBConfig(stage_x11->xdpy, stage_x11->xscreen,
+ attrib, &numfbconfigs);
+ if (!fbconfigs)
+ return None;
+
+ /* Find an FBConfig with a visual that has a RENDER picture format that
+ has alpha */
+ for (i = 0; i < numfbconfigs; i++)
+ {
+ visinfo = glXGetVisualFromFBConfig (stage_x11->xdpy, fbconfigs[i]);
+ if (!visinfo)
+ continue;
+
+ pictFormat = XRenderFindVisualFormat (stage_x11->xdpy,
+ visinfo->visual);
+ if (!pictFormat)
+ continue;
+
+ if (pictFormat->direct.alphaMask > 0)
+ break;
+
+ XFree (visinfo);
+ }
+
+ XFree (fbconfigs);
+
+ if (i == numfbconfigs)
+ return None;
+
+ return visinfo;
+}
+
+
static void
clutter_stage_glx_realize (ClutterActor *actor)
{
@@ -140,12 +206,16 @@
XFree (stage_x11->xvisinfo);
stage_x11->xvisinfo = None;
}
-
- /* The following check seems strange */
+
+
+ if (backend_x11->transparent_stage)
+ stage_x11->xvisinfo = get_argb_visual_info (stage_x11);
+
if (stage_x11->xvisinfo == None)
stage_x11->xvisinfo = glXChooseVisual (stage_x11->xdpy,
stage_x11->xscreen,
gl_attributes);
+
if (!stage_x11->xvisinfo)
{
g_critical ("Unable to find suitable GL visual.");
diff -ru clutter-0.8.8/clutter/x11/clutter-backend-x11.c
clutter-0.8.8.patched/clutter/x11/clutter-backend-x11.c
--- clutter-0.8.8/clutter/x11/clutter-backend-x11.c 2009-02-20
16:41:39.000000000 +0100
+++ clutter-0.8.8.patched/clutter/x11/clutter-backend-x11.c 2009-03-07
11:02:03.000000000 +0100
@@ -95,6 +95,7 @@
static gchar *clutter_display_name = NULL;
static gint clutter_screen = 0;
static gboolean clutter_synchronise = FALSE;
+static gboolean _transparent_stage = FALSE;
/* X error trap */
static int TrappedErrorCode = 0;
@@ -127,6 +128,9 @@
if (_foreign_dpy)
backend_x11->xdpy = _foreign_dpy;
+
+ backend_x11->transparent_stage = _transparent_stage;
+
/*
* Only open connection if not already set by prior call to
* clutter_x11_set_display()
@@ -446,6 +450,21 @@
}
/**
+ * clutter_x11_enable_transparent_stage:
+ *
+ * Attempts to make stage transparent if ARGB visuals is supported; should be
called
+ * before clutter_init(), clutter_init_with_args() or other functions
+ * pertaining Clutter's initialization process.
+ *
+ * Since: 0.9
+ */
+void
+clutter_x11_enable_transparent_stage ()
+{
+ _transparent_stage = TRUE;
+}
+
+/**
* clutter_x11_enable_xinput:
*
* Enables the use of the XInput extension if present on connected
diff -ru clutter-0.8.8/clutter/x11/clutter-backend-x11.h
clutter-0.8.8.patched/clutter/x11/clutter-backend-x11.h
--- clutter-0.8.8/clutter/x11/clutter-backend-x11.h 2009-02-20
16:41:39.000000000 +0100
+++ clutter-0.8.8.patched/clutter/x11/clutter-backend-x11.h 2009-03-07
11:02:03.000000000 +0100
@@ -62,7 +62,8 @@
Screen *xscreen;
int xscreen_num;
gchar *display_name;
-
+ gboolean transparent_stage;
+
/* event source */
GSource *event_source;
GSList *event_filters;
diff -ru clutter-0.8.8/clutter/x11/clutter-stage-x11.c
clutter-0.8.8.patched/clutter/x11/clutter-stage-x11.c
--- clutter-0.8.8/clutter/x11/clutter-stage-x11.c 2009-02-20
16:41:39.000000000 +0100
+++ clutter-0.8.8.patched/clutter/x11/clutter-stage-x11.c 2009-03-07
11:02:03.000000000 +0100
@@ -576,7 +576,7 @@
stage->fullscreen_on_map = FALSE;
stage->handling_configure = FALSE;
stage->is_cursor_visible = TRUE;
-
+
stage->title = NULL;
stage->wrapper = NULL;
@@ -677,6 +677,7 @@
return CLUTTER_STAGE_X11 (impl)->xvisinfo;
}
+
/**
* clutter_x11_set_stage_foreign:
* @stage: a #ClutterStage
diff -ru clutter-0.8.8/clutter/x11/clutter-x11.h
clutter-0.8.8.patched/clutter/x11/clutter-x11.h
--- clutter-0.8.8/clutter/x11/clutter-x11.h 2009-02-20 16:41:39.000000000
+0100
+++ clutter-0.8.8.patched/clutter/x11/clutter-x11.h 2009-03-07
11:02:03.000000000 +0100
@@ -134,6 +134,8 @@
gboolean clutter_x11_has_composite_extension (void);
+void clutter_x11_enable_transparent_stage ();
+
G_END_DECLS
#endif /* __CLUTTER_X11_H__ */
diff -ru clutter-0.8.8/config.h.in clutter-0.8.8.patched/config.h.in
--- clutter-0.8.8/config.h.in 2009-02-20 16:58:14.000000000 +0100
+++ clutter-0.8.8.patched/config.h.in 2009-03-07 11:11:12.000000000 +0100
@@ -127,6 +127,9 @@
/* Define to 1 if we have the XFIXES X extension */
#undef HAVE_XFIXES
+/* Define to 1 if we have the XRENDER X extension */
+#undef HAVE_XRENDER
+
/* Name of package */
#undef PACKAGE
diff -ru clutter-0.8.8/configure clutter-0.8.8.patched/configure
--- clutter-0.8.8/configure 2009-02-20 16:58:01.000000000 +0100
+++ clutter-0.8.8.patched/configure 2009-03-07 11:08:53.000000000 +0100
@@ -21670,6 +21670,32 @@
echo "${ECHO_T}found" >&6; }
fi
+{ echo "$as_me:$LINENO: checking for XRENDER extension" >&5
+echo $ECHO_N "checking for XRENDER extension... $ECHO_C" >&6; }
+if test -n "$PKG_CONFIG" && \
+ { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors
\"xrender\"") >&5
+ ($PKG_CONFIG --exists --print-errors "xrender") 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ have_xrender=yes
+else
+ have_xrender=no
+fi
+if test "x$have_xrender" = "xyes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_XRENDER 1
+_ACEOF
+
+ X11_LIBS="$X11_LIBS -lXrender"
+ { echo "$as_me:$LINENO: result: found" >&5
+echo "${ECHO_T}found" >&6; }
+else
+ { echo "$as_me:$LINENO: result: not found" >&5
+echo "${ECHO_T}not found" >&6; }
+fi
+
{ echo "$as_me:$LINENO: checking for XFIXES extension >= 3" >&5
echo $ECHO_N "checking for XFIXES extension >= 3... $ECHO_C" >&6; }
if test -n "$PKG_CONFIG" && \
diff -ru clutter-0.8.8/configure.ac clutter-0.8.8.patched/configure.ac
--- clutter-0.8.8/configure.ac 2009-02-20 16:57:24.000000000 +0100
+++ clutter-0.8.8.patched/configure.ac 2009-03-07 11:02:31.000000000 +0100
@@ -180,6 +180,16 @@
AC_MSG_RESULT([found])
fi
+AC_MSG_CHECKING([for XRENDER extension])
+PKG_CHECK_EXISTS([xrender], [have_xrender=yes], [have_xrender=no])
+if test "x$have_xrender" = "xyes"; then
+ AC_DEFINE(HAVE_XRENDER, 1, [Define to 1 if we have the XRENDER X extension])
+ X11_LIBS="$X11_LIBS -lXrender"
+ AC_MSG_RESULT([found])
+else
+ AC_MSG_RESULT([not found])
+fi
+
AC_MSG_CHECKING([for XFIXES extension >= 3])
PKG_CHECK_EXISTS([xfixes >= 3], [have_xfixes=yes], [have_xfixes=no])
if test "x$have_xfixes" = "xyes"; then
pgpaZgnwbvuAR.pgp
Description: PGP signature
