[beryl-commits] compiz mirror: Changes to 'master' (50e3f8ec863a274f6740530a95992771a6734ec9)

compiz at server.beryl-project.org compiz at server.beryl-project.org
Thu Jun 21 18:18:10 CEST 2007


New commits:
commit 50e3f8ec863a274f6740530a95992771a6734ec9
Author: Danny Baumann <dannybaumann at web.de>
Date:   Thu Jun 21 18:17:22 2007 +0200

    Remove trailing whitespace.

commit ca8906f7fb8614513431896c6c383a5d18446ee9
Author: Roi Cohen <roico.beryl at gmail.com>
Date:   Tue Jun 12 14:25:06 2007 +0200

    Added option to enable cube transparency only on button binding initiated rotatation.

commit f0f5ebfaddc65130dd7821106eb9e223c4a342e2
Author: Roi Cohen <roico.beryl at gmail.com>
Date:   Tue Jun 12 14:46:10 2007 +0200

    Add cube transparency.

commit 54024dda4def77aa1d369253e4fb4d9be94aa449
Author: Danny Baumann <dannybaumann at web.de>
Date:   Thu Jun 21 18:15:46 2007 +0200

    Added rotation state.
    This variable should be set appropriately by plugins rotating the cube.

commit 6873aaeedb567995afcb460042ae9a2b909de050
Author: Roi Cohen <roico.beryl at gmail.com>
Date:   Tue Jun 12 14:45:30 2007 +0200

    Improve cube paint order calculations.


 include/cube.h       |   64 ++++--
 metadata/cube.xml.in |   29 +++
 plugins/cube.c       |  587 ++++++++++++++++++++++++++++++++++++++------------
 plugins/rotate.c     |   12 +
 4 files changed, 531 insertions(+), 161 deletions(-)


Modified: compiz/include/cube.h
===================================================================
--- compiz/include/cube.h
+++ compiz/include/cube.h
@@ -25,7 +25,7 @@
 
 #include <compiz.h>
 
-#define CUBE_ABIVERSION 20070611
+#define CUBE_ABIVERSION 20070612
 
 #define CUBE_DISPLAY_OPTION_ABI    0
 #define CUBE_DISPLAY_OPTION_INDEX  1
@@ -40,22 +40,26 @@ typedef struct _CubeDisplay {
     CompOption opt[CUBE_DISPLAY_OPTION_NUM];
 } CubeDisplay;
 
-#define CUBE_SCREEN_OPTION_COLOR	      0
-#define CUBE_SCREEN_OPTION_IN		      1
-#define CUBE_SCREEN_OPTION_SCALE_IMAGE	      2
-#define CUBE_SCREEN_OPTION_IMAGES	      3
-#define CUBE_SCREEN_OPTION_SKYDOME	      4
-#define CUBE_SCREEN_OPTION_SKYDOME_IMG	      5
-#define CUBE_SCREEN_OPTION_SKYDOME_ANIM	      6
-#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START 7
-#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END   8
-#define CUBE_SCREEN_OPTION_ACCELERATION	      9
-#define CUBE_SCREEN_OPTION_SPEED	      10
-#define CUBE_SCREEN_OPTION_TIMESTEP	      11
-#define CUBE_SCREEN_OPTION_MIPMAP	      12
-#define CUBE_SCREEN_OPTION_BACKGROUNDS	      13
-#define CUBE_SCREEN_OPTION_ADJUST_IMAGE	      14
-#define CUBE_SCREEN_OPTION_NUM                15
+#define CUBE_SCREEN_OPTION_COLOR	           0
+#define CUBE_SCREEN_OPTION_IN		           1
+#define CUBE_SCREEN_OPTION_SCALE_IMAGE	           2
+#define CUBE_SCREEN_OPTION_IMAGES	           3
+#define CUBE_SCREEN_OPTION_SKYDOME	           4
+#define CUBE_SCREEN_OPTION_SKYDOME_IMG	           5
+#define CUBE_SCREEN_OPTION_SKYDOME_ANIM	           6
+#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START      7
+#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END        8
+#define CUBE_SCREEN_OPTION_ACCELERATION	           9
+#define CUBE_SCREEN_OPTION_SPEED	           10
+#define CUBE_SCREEN_OPTION_TIMESTEP	           11
+#define CUBE_SCREEN_OPTION_MIPMAP	           12
+#define CUBE_SCREEN_OPTION_BACKGROUNDS	           13
+#define CUBE_SCREEN_OPTION_ADJUST_IMAGE	           14
+#define CUBE_SCREEN_OPTION_ACTIVE_OPACITY          15
+#define CUBE_SCREEN_OPTION_INACTIVE_OPACITY        16
+#define CUBE_SCREEN_OPTION_FADE_TIME               17
+#define CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY 18
+#define CUBE_SCREEN_OPTION_NUM                     19
 
 typedef void (*CubeGetRotationProc) (CompScreen *s,
 				     float      *x,
@@ -71,15 +75,30 @@ typedef void (*CubePaintTopBottomProc) (CompScreen		*s,
 					CompOutput		*output,
 					int			size);
 
+typedef enum _PaintOrder
+{
+    BTF = 0,
+    FTB
+} PaintOrder;
+
+typedef enum _RotationState
+{
+    RotationNone = 0,
+    RotationChange,
+    RotationManual
+} RotationState;
+
 typedef struct _CubeScreen {
     PreparePaintScreenProc     preparePaintScreen;
     DonePaintScreenProc	       donePaintScreen;
     PaintOutputProc	       paintOutput;
     PaintTransformedOutputProc paintTransformedOutput;
     PaintBackgroundProc        paintBackground;
+    PaintWindowProc            paintWindow;
     ApplyScreenTransformProc   applyScreenTransform;
     SetScreenOptionProc	       setScreenOption;
     OutputChangeNotifyProc     outputChangeNotify;
+    InitWindowWalkerProc       initWindowWalker;
 
     CubeGetRotationProc	      getRotation;
     CubeClearTargetOutputProc clearTargetOutput;
@@ -87,8 +106,12 @@ typedef struct _CubeScreen {
 
     CompOption opt[CUBE_SCREEN_OPTION_NUM];
 
-    int      invert;
-    int      xRotations;
+    int       invert;
+    int       xRotations;
+    PaintOrder paintOrder;
+
+    RotationState rotationState;
+
     GLfloat  distance;
     GLushort color[3];
     GLfloat  tc[12];
@@ -124,6 +147,9 @@ typedef struct _CubeScreen {
     float outputXOffset;
     float outputYOffset;
 
+    float desktopOpacity;
+    float toOpacity;
+
     CompTexture *bg;
     int		nBg;
 } CubeScreen;

Modified: compiz/metadata/cube.xml.in
===================================================================
--- compiz/metadata/cube.xml.in
+++ compiz/metadata/cube.xml.in
@@ -134,6 +134,35 @@
 		<_long>Adjust top face image to rotation</_long>
 		<default>false</default>
 	    </option>
+	    <option name="active_opacity" type="float">
+		<_short>Opacity During Rotation</_short>
+		<_long>Opacity of desktop window during rotation.</_long>
+		<default>30.0</default>
+		<min>0.0</min>
+		<max>100.0</max>
+		<precision>1.0</precision>
+	    </option>
+	    <option name="inactive_opacity" type="float">
+		<_short>Opacity When Not Rotating</_short>
+		<_long>Opacity of desktop window when not rotating.</_long>
+		<default>100.0</default>
+		<min>0.0</min>
+		<max>100.0</max>
+		<precision>1.0</precision>
+	    </option>
+	    <option name="fade_time" type="float">
+		<_short>Fade Time</_short>
+		<_long>Desktop Window Opacity Fade Time.</_long>
+		<default>1.0</default>
+		<min>0.0</min>
+		<max>10.0</max>
+		<precision>0.1</precision>
+	    </option>
+	    <option name="transparent_manual_only" type="bool">
+		<_short>Transparency Only on Mouse Rotate</_short>
+		<_long>Initiates Cube transparency only if rotation is mouse driven.</_long>
+		<default>true</default>
+	    </option>
 	</screen>
     </plugin>
 </compiz>

Modified: compiz/plugins/cube.c
===================================================================
--- compiz/plugins/cube.c
+++ compiz/plugins/cube.c
@@ -32,6 +32,37 @@
 
 #include <cube.h>
 
+#define MULTM(x, y, z) \
+z[0] = x[0] * y[0] + x[4] * y[1] + x[8] * y[2] + x[12] * y[3]; \
+z[1] = x[1] * y[0] + x[5] * y[1] + x[9] * y[2] + x[13] * y[3]; \
+z[2] = x[2] * y[0] + x[6] * y[1] + x[10] * y[2] + x[14] * y[3]; \
+z[3] = x[3] * y[0] + x[7] * y[1] + x[11] * y[2] + x[15] * y[3]; \
+z[4] = x[0] * y[4] + x[4] * y[5] + x[8] * y[6] + x[12] * y[7]; \
+z[5] = x[1] * y[4] + x[5] * y[5] + x[9] * y[6] + x[13] * y[7]; \
+z[6] = x[2] * y[4] + x[6] * y[5] + x[10] * y[6] + x[14] * y[7]; \
+z[7] = x[3] * y[4] + x[7] * y[5] + x[11] * y[6] + x[15] * y[7]; \
+z[8] = x[0] * y[8] + x[4] * y[9] + x[8] * y[10] + x[12] * y[11]; \
+z[9] = x[1] * y[8] + x[5] * y[9] + x[9] * y[10] + x[13] * y[11]; \
+z[10] = x[2] * y[8] + x[6] * y[9] + x[10] * y[10] + x[14] * y[11]; \
+z[11] = x[3] * y[8] + x[7] * y[9] + x[11] * y[10] + x[15] * y[11]; \
+z[12] = x[0] * y[12] + x[4] * y[13] + x[8] * y[14] + x[12] * y[15]; \
+z[13] = x[1] * y[12] + x[5] * y[13] + x[9] * y[14] + x[13] * y[15]; \
+z[14] = x[2] * y[12] + x[6] * y[13] + x[10] * y[14] + x[14] * y[15]; \
+z[15] = x[3] * y[12] + x[7] * y[13] + x[11] * y[14] + x[15] * y[15];
+
+#define MULTMV(m, v) { \
+float v0 = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3]; \
+float v1 = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3]; \
+float v2 = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3]; \
+float v3 = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3]; \
+v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3; }
+
+#define DIVV(v) \
+v[0] /= v[3]; \
+v[1] /= v[3]; \
+v[2] /= v[3]; \
+v[3] /= v[3];
+
 static CompMetadata cubeMetadata;
 
 static int cubeDisplayPrivateIndex;
@@ -767,6 +798,8 @@ static void
 cubePreparePaintScreen (CompScreen *s,
 			int	   msSinceLastPaint)
 {
+    int opt;
+
     CUBE_SCREEN (s);
 
     if (cs->grabIndex)
@@ -805,10 +838,44 @@ cubePreparePaintScreen (CompScreen *s,
 
     memset (cs->cleared, 0, sizeof (Bool) * s->nOutputDev);
 
+    /* Transparency handling */
+    if (cs->rotationState == RotationManual ||
+	(cs->rotationState == RotationChange &&
+	 cs->opt[CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY].value.b))
+    {
+	opt = CUBE_SCREEN_OPTION_ACTIVE_OPACITY;
+    }
+    else
+    {
+	opt = CUBE_SCREEN_OPTION_INACTIVE_OPACITY;
+    }
+
+    cs->toOpacity = (cs->opt[opt].value.f / 100.0f) * OPAQUE;
+
+    if (cs->opt[CUBE_SCREEN_OPTION_FADE_TIME].value.f == 0.0f)
+	cs->desktopOpacity = cs->toOpacity;
+    else if (cs->desktopOpacity != cs->toOpacity)
+    {
+	float steps = (msSinceLastPaint * OPAQUE / 1000.0) /
+	              cs->opt[CUBE_SCREEN_OPTION_FADE_TIME].value.f;
+	if (steps < 12)
+	    steps = 12;
+
+	if (cs->toOpacity > cs->desktopOpacity)
+	{
+	    cs->desktopOpacity += steps;
+	    cs->desktopOpacity = MIN (cs->toOpacity, cs->desktopOpacity);
+	}
+	if (cs->toOpacity < cs->desktopOpacity)
+	{
+	    cs->desktopOpacity -= steps;
+	    cs->desktopOpacity = MAX (cs->toOpacity, cs->desktopOpacity);
+	}
+    }
+
     UNWRAP (cs, s, preparePaintScreen);
     (*s->preparePaintScreen) (s, msSinceLastPaint);
     WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen);
-
 }
 
 static Bool
@@ -823,13 +890,15 @@ cubePaintOutput (CompScreen		 *s,
 
     CUBE_SCREEN (s);
 
-    if (cs->grabIndex)
+    if (cs->grabIndex || cs->desktopOpacity != OPAQUE)
     {
 	mask &= ~PAINT_SCREEN_REGION_MASK;
 	mask |= PAINT_SCREEN_TRANSFORMED_MASK;
     }
 
     cs->srcOutput = (output->id != ~0) ? output->id : 0;
+    /* Always use BTF painting on non-transformed screen */
+    cs->paintOrder = BTF;
 
     UNWRAP (cs, s, paintOutput);
     status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
@@ -843,7 +912,7 @@ cubeDonePaintScreen (CompScreen *s)
 {
     CUBE_SCREEN (s);
 
-    if (cs->grabIndex)
+    if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity)
 	damageScreen (s);
 
     UNWRAP (cs, s, donePaintScreen);
@@ -851,18 +920,92 @@ cubeDonePaintScreen (CompScreen *s)
     WRAP (cs, s, donePaintScreen, cubeDonePaintScreen);
 }
 
+static Bool
+cubeCheckFTB (CompScreen              *s,
+              const ScreenPaintAttrib *sAttrib,
+              const CompTransform     *transform,
+              CompOutput              *outputPtr)
+{
+    CompTransform sTransform = *transform;
+    float         mvp[16];
+    float         pntA[4], pntB[4], pntC[4];
+    float         vecA[3], vecB[3];
+    float         ortho[3];
+
+    (*s->applyScreenTransform) (s, sAttrib, outputPtr, &sTransform);
+    transformToScreenSpace (s, outputPtr, -sAttrib->zTranslate, &sTransform);
+
+    MULTM (s->projection, sTransform.m, mvp);
+
+    pntA[0] = outputPtr->region.extents.x1;
+    pntA[1] = outputPtr->region.extents.y1,
+    pntA[2] = 0.0f;
+    pntA[3] = 1.0f;
+
+    pntB[0] = outputPtr->region.extents.x2;
+    pntB[1] = outputPtr->region.extents.y1;
+    pntB[2] = 0.0f;
+    pntB[3] = 1.0f;
+
+    pntC[0] = outputPtr->region.extents.x1 + outputPtr->width / 2.0f;
+    pntC[1] = outputPtr->region.extents.y1 + outputPtr->height / 2.0f;
+    pntC[2] = 0.0f;
+    pntC[3] = 1.0f;
+
+    MULTMV (mvp, pntA);
+    DIVV (pntA);
+
+    MULTMV (mvp, pntB);
+    DIVV (pntB);
+
+    MULTMV (mvp, pntC);
+    DIVV (pntC);
+
+    vecA[0] = pntC[0] - pntA[0];
+    vecA[1] = pntC[1] - pntA[1];
+    vecA[2] = pntC[2] - pntA[2];
+
+    vecB[0] = pntC[0] - pntB[0];
+    vecB[1] = pntC[1] - pntB[1];
+    vecB[2] = pntC[2] - pntB[2];
+
+    ortho[0] = vecA[1] * vecB[2] - vecA[2] * vecB[1];
+    ortho[1] = vecA[2] * vecB[0] - vecA[0] * vecB[2];
+    ortho[2] = vecA[0] * vecB[1] - vecA[1] * vecB[0];
+
+    if (ortho[2] > 0.0f)
+    {
+	/* The viewport is reversed, should be painted front to back. */
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
 static void
 cubeMoveViewportAndPaint (CompScreen		  *s,
 			  const ScreenPaintAttrib *sAttrib,
 			  const CompTransform	  *transform,
 			  CompOutput		  *outputPtr,
 			  unsigned int		  mask,
+			  PaintOrder              paintOrder,
 			  int			  dx)
 {
-    int output = (outputPtr->id != ~0) ? outputPtr->id : 0;
+    Bool ftb;
+    int  output;
 
     CUBE_SCREEN (s);
 
+    ftb = cubeCheckFTB (s, sAttrib, transform, outputPtr);
+
+    if ((paintOrder == FTB && !ftb) ||
+        (paintOrder == BTF && ftb))
+	return;
+
+    output = (outputPtr->id != ~0) ? outputPtr->id : 0;
+
+    cs->paintOrder = paintOrder;
+
     if (cs->nOutput > 1)
     {
 	int cubeOutput, dView;
@@ -903,6 +1046,108 @@ cubeMoveViewportAndPaint (CompScreen		  *s,
 }
 
 static void
+cubePaintAllViewports (CompScreen          *s,
+                       ScreenPaintAttrib   *sAttrib,
+	               const CompTransform *transform,
+                       Region              region,
+                       CompOutput          *outputPtr,
+                       unsigned int        mask,
+                       int                 xMove,
+                       float               size,
+                       int                 hsize,
+                       PaintOrder          paintOrder)
+{
+    CUBE_SCREEN(s);
+
+    ScreenPaintAttrib sa = *sAttrib;
+
+    int i;
+    int xMoveAdd;
+    int origXMoveAdd = 0; /* dx for the viewport we start
+			     painting with (back-most). */
+    int iFirstSign;       /* 1 if we do xMove += i first and
+			     -1 if we do xMove -= i first. */
+
+    if (cs->invert == 1)
+    {
+	/* xMove ==> dx for the viewport which is the
+	   nearest to the viewer in z axis.
+	   xMove +/- hsize / 2 ==> dx for the viewport
+	   which is the farthest to the viewer in z axis. */
+
+	if ((sa.xRotate < 0.0f && hsize % 2 == 1) ||
+	    (sa.xRotate > 0.0f && hsize % 2 == 0))
+	{
+	    origXMoveAdd = hsize / 2;
+	    iFirstSign = 1;
+	}
+	else
+	{
+	    origXMoveAdd = -hsize / 2;
+	    iFirstSign = -1;
+	}
+    }
+    else
+    {
+	/* xMove is already the dx for farthest viewport. */
+	if (sa.xRotate > 0.0f)
+	    iFirstSign = -1;
+	else
+	    iFirstSign = 1;
+    }
+
+    for (i = 0; i <= hsize / 2; i++)
+    {
+	/* move to the correct viewport (back to front). */
+	xMoveAdd = origXMoveAdd;	/* move to farthest viewport. */
+	xMoveAdd += iFirstSign * i;	/* move i more viewports to
+					   the right / left. */
+
+	/* Needed especially for unfold.
+	   We paint the viewports around xMove viewport.
+	   Adding or subtracting hsize from xMove has no effect on
+	   what viewport we paint, but can make shorter paths. */
+	if (xMoveAdd < -hsize / 2)
+	    xMoveAdd += hsize;
+	else if (xMoveAdd > hsize / 2)
+	    xMoveAdd -= hsize;
+
+	/* Paint the viewport. */
+	xMove += xMoveAdd;
+
+	sa.yRotate -= cs->invert * xMoveAdd * 360.0f / size;
+	cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
+	                          paintOrder, xMove);
+	sa.yRotate += cs->invert * xMoveAdd * 360.0f / size;
+
+	xMove -= xMoveAdd;
+
+	/* do the same for an equally far viewport. */
+	if (i == 0 || i * 2 == hsize)
+	    continue;
+
+	xMoveAdd = origXMoveAdd;	/* move to farthest viewport. */
+	xMoveAdd -= iFirstSign * i;	/* move i more viewports to the
+					   left / right (opposite side
+					   from the one chosen first) */
+
+	if (xMoveAdd < -hsize / 2)
+	    xMoveAdd += hsize;
+	else if (xMoveAdd > hsize / 2)
+	    xMoveAdd -= hsize;
+
+	xMove += xMoveAdd;
+
+	sa.yRotate -= cs->invert * xMoveAdd * 360.0f / size;
+	cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
+	                          paintOrder, xMove);
+	sa.yRotate += cs->invert * xMoveAdd * 360.0f / size;
+
+	xMove -= xMoveAdd;
+    }
+}
+
+static void
 cubeGetRotation (CompScreen *s,
 		 float	    *x,
 		 float	    *v)
@@ -953,12 +1198,13 @@ cubePaintTopBottom (CompScreen		    *s,
 {
     ScreenPaintAttrib sa = *sAttrib;
     CompTransform     sTransform = *transform;
+    int               i;
 
     CUBE_SCREEN (s);
 
     screenLighting (s, TRUE);
 
-    glColor3usv (cs->color);
+    glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity);
 
     glPushMatrix ();
 
@@ -972,27 +1218,42 @@ cubePaintTopBottom (CompScreen		    *s,
     glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
     glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
 
-    glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
-
-    glNormal3f (0.0f, -1.0f, 0.0f);
-
-    if (cs->invert == 1 && size == 4 && cs->texture.name)
-    {
-	enableTexture (s, &cs->texture, COMP_TEXTURE_FILTER_GOOD);
-	glTexCoordPointer (2, GL_FLOAT, 0, cs->tc);
-	glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nVertices >> 1);
-	disableTexture (s, &cs->texture);
-	glDisableClientState (GL_TEXTURE_COORD_ARRAY);
-    }
-    else
+    if (cs->desktopOpacity != OPAQUE)
     {
-	glDisableClientState (GL_TEXTURE_COORD_ARRAY);
-	glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nVertices >> 1);
+	screenTexEnvMode (s, GL_MODULATE);
+	glEnable (GL_BLEND);
+	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     }
 
-    glNormal3f (0.0f, 1.0f, 0.0f);
+    glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
 
-    glDrawArrays (GL_TRIANGLE_FAN, cs->nVertices >> 1, cs->nVertices >> 1);
+    for (i = 0; i < 2; i++)
+    {
+	if ((i == 0 && sAttrib->vRotate <= 0.0f) ||
+	    (i == 1 && sAttrib->vRotate > 0.0f))
+	{
+	    glNormal3f (0.0f, -1.0f, 0.0f);
+	    if (cs->invert == 1 && size == 4 && cs->texture.name)
+	    {
+		enableTexture (s, &cs->texture, COMP_TEXTURE_FILTER_GOOD);
+		glTexCoordPointer (2, GL_FLOAT, 0, cs->tc);
+		glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nVertices >> 1);
+		disableTexture (s, &cs->texture);
+		glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+	    }
+	    else
+	    {
+		glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+		glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nVertices >> 1);
+	    }
+	}
+	else
+	{
+	    glNormal3f (0.0f, 1.0f, 0.0f);
+	    glDrawArrays (GL_TRIANGLE_FAN, cs->nVertices >> 1,
+			  cs->nVertices >> 1);
+	}
+    }
 
     glNormal3f (0.0f, 0.0f, -1.0f);
 
@@ -1000,6 +1261,10 @@ cubePaintTopBottom (CompScreen		    *s,
 
     glColor4usv (defaultColor);
     glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+
+    screenTexEnvMode (s, GL_REPLACE);
+    glDisable (GL_BLEND);
+    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 }
 
 static void
@@ -1014,7 +1279,10 @@ cubePaintTransformedOutput (CompScreen		    *s,
     float	      xRotate, vRotate;
     int		      hsize, xMove = 0;
     float	      size;
+    GLenum            filter = s->display->textureFilter;
+    PaintOrder        paintOrder;
     Bool	      clear;
+    Bool              wasCulled = FALSE;
     int output = 0;
 
     CUBE_SCREEN (s);
@@ -1024,6 +1292,13 @@ cubePaintTransformedOutput (CompScreen		    *s,
     hsize = s->hsize * cs->nOutput;
     size  = hsize;
 
+    if (cs->desktopOpacity != OPAQUE)
+    {
+	wasCulled = glIsEnabled (GL_CULL_FACE);
+	if (wasCulled)
+	    glDisable (GL_CULL_FACE);
+    }
+
     if (!cs->fullscreenOutput)
     {
 	cs->outputXScale = (float) s->width / s->outputDev[output].width;
@@ -1065,9 +1340,6 @@ cubePaintTransformedOutput (CompScreen		    *s,
 
     UNWRAP (cs, s, paintTransformedOutput);
 
-    sa.xTranslate = sAttrib->xTranslate;
-    sa.yTranslate = sAttrib->yTranslate;
-
     if (cs->grabIndex)
     {
 	sa.vRotate = 0.0f;
@@ -1081,22 +1353,6 @@ cubePaintTransformedOutput (CompScreen		    *s,
 	/* distance we move the camera back when unfolding the cube.
 	   currently hardcoded to 1.5 but it should probably be optional. */
 	sa.zCamera -= cs->unfold * 1.5f;
-
-	sa.xRotate = xRotate * cs->invert;
-	if (sa.xRotate > 0.0f)
-	{
-	    cs->xRotations = (int) (hsize * sa.xRotate) / 360;
-	    sa.xRotate = sa.xRotate - (360.0f * cs->xRotations) / hsize;
-	}
-	else
-	{
-	    cs->xRotations = (int) (hsize * sa.xRotate) / 360;
-	    sa.xRotate = sa.xRotate -
-		(360.0f * cs->xRotations) / hsize + 360.0f / hsize;
-	    cs->xRotations--;
-	}
-
-	sa.xRotate = sa.xRotate / size * hsize;
     }
     else
     {
@@ -1108,133 +1364,112 @@ cubePaintTransformedOutput (CompScreen		    *s,
 	    sa.vRotate = vRotate;
 
 	sa.zTranslate = -cs->invert * cs->distance;
-	sa.xRotate = xRotate * cs->invert;
-	if (sa.xRotate > 0.0f)
-	{
-	    cs->xRotations = (int) (size * sa.xRotate) / 360;
-	    sa.xRotate = sa.xRotate - (360.0f * cs->xRotations) / size;
-	}
-	else
-	{
-	    cs->xRotations = (int) (size * sa.xRotate) / 360;
-	    sa.xRotate = sa.xRotate -
-		(360.0f * cs->xRotations) / size + 360.0f / size;
-	    cs->xRotations--;
-	}
     }
 
+    if (sa.xRotate > 0.0f)
+	cs->xRotations = (int) (hsize * sa.xRotate + 180.0f) / 360.0f;
+    else
+	cs->xRotations = (int) (hsize * sa.xRotate - 180.0f) / 360.0f;
+
+    sa.xRotate -= (360.0f * cs->xRotations) / hsize;
+    sa.xRotate *= cs->invert;
+
+    sa.xRotate = sa.xRotate / size * hsize;
+
+    xMove = cs->xRotations;
+
+    if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
+	s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
+
+    if (cs->invert == 1)
+    {
+	/* Outside cube - start with FTB faces */
+	paintOrder = FTB;
+    }
+    else
+    {
+	/* Inside cube - start with BTF faces */
+	paintOrder = BTF;
+    }
+
+    if (cs->invert == -1 || cs->desktopOpacity != OPAQUE)
+	cubePaintAllViewports (s, &sa,transform, region,
+			       outputPtr, mask, xMove,
+			       size, hsize, paintOrder);
+
     if (cs->grabIndex == 0 && hsize > 2 &&
-	(cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f))
+	(cs->invert != 1 || cs->desktopOpacity != OPAQUE ||
+	 sa.vRotate != 0.0f || sa.yTranslate != 0.0f))
     {
 	(*cs->paintTopBottom) (s, &sa, transform, outputPtr, hsize);
     }
 
-    /* outside cube */
     if (cs->invert == 1)
     {
-	if (cs->grabIndex || hsize > 4)
-	{
-	    GLenum filter;
-	    int    i;
+	/* Outside cube - continue with BTF faces */
+	paintOrder = BTF;
+    }
+    else
+    {
+	/* Inside cube - continue with FTB faces */
+	paintOrder = FTB;
+    }
 
-	    xMove = cs->xRotations - ((hsize >> 1) - 1);
-	    sa.yRotate += (360.0f / size) * ((hsize >> 1) - 1);
+    if (cs->invert == 1 || cs->desktopOpacity != OPAQUE)
+	cubePaintAllViewports (s, &sa, transform, region,
+			       outputPtr, mask, xMove,
+			       size, hsize, paintOrder);
 
-	    filter = s->display->textureFilter;
-	    if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
-		s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
+    s->display->textureFilter = filter;
 
-	    for (i = 0; i < hsize; i++)
-	    {
-		cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-					  xMove);
+    if (wasCulled)
+	glEnable (GL_CULL_FACE);
 
-		sa.yRotate -= 360.0f / size;
-		xMove++;
-	    }
+    WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput);
+}
 
-	    s->display->textureFilter = filter;
+static void
+cubeSetBackgroundOpacity (CompScreen* s)
+{
+    CUBE_SCREEN (s);
+
+    if (cs->desktopOpacity != OPAQUE)
+    {
+	if (s->desktopWindowCount)
+	{
+	    glColor4us (0, 0, 0, 0);
+	    glEnable (GL_BLEND);
 	}
 	else
 	{
-	    if (xRotate != 0.0f)
-	    {
-		xMove = cs->xRotations;
-
-		cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-					  xMove);
-
-		xMove++;
-	    }
-
-	    sa.yRotate -= 360.0f / size;
-
-	    cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-				      xMove);
+	    glColor4us (0xffff, 0xffff, 0xffff, cs->desktopOpacity);
+	    glEnable (GL_BLEND);
+	    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 	}
     }
-    else
-    {
-	if (sa.xRotate > 180.0f / size)
-	{
-	    sa.yRotate -= 360.0f / size;
-	    cs->xRotations++;
-	}
+}
 
-	sa.yRotate -= 360.0f / size;
-	xMove = -1 - cs->xRotations;
+static void
+cubeUnSetBackgroundOpacity (CompScreen* s)
+{
+    CUBE_SCREEN (s);
 
-	if (cs->grabIndex)
+    if (cs->desktopOpacity != OPAQUE)
+    {
+	if (s->desktopWindowCount)
 	{
-	    GLenum filter;
-	    int    i;
-
-	    filter = s->display->textureFilter;
-	    if (cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
-		s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
-
-	    if (sa.xRotate > 180.0f / size)
-	    {
-		xMove -= ((hsize >> 1) - 2);
-		sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 2);
-	    }
-	    else
-	    {
-		xMove -= ((hsize >> 1) - 1);
-		sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 1);
-	    }
-
-	    for (i = 0; i < hsize; i++)
-	    {
-		cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-					  xMove);
-
-		sa.yRotate += 360.0f / size;
-		xMove++;
-	    }
-
-	    s->display->textureFilter = filter;
+	    glColor3usv (defaultColor);
+	    glDisable (GL_BLEND);
 	}
 	else
 	{
-	    cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-				      xMove);
-
-	    sa.yRotate += 360.0f / size;
-	    xMove = -cs->xRotations;
-
-	    cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-				      xMove);
-
-	    sa.yRotate += 360.0f / size;
-	    xMove = 1 - cs->xRotations;
-
-	    cubeMoveViewportAndPaint (s, &sa, transform, outputPtr, mask,
-				      xMove);
+	    glColor3usv (defaultColor);
+	    glDisable (GL_BLEND);
+	    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+	    screenTexEnvMode(s, GL_REPLACE);
 	}
     }
-
-    WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput);
 }
 
 static void
@@ -1246,6 +1481,8 @@ cubePaintBackground (CompScreen   *s,
 
     CUBE_SCREEN (s);
 
+    cubeSetBackgroundOpacity(s);
+
     n = cs->opt[CUBE_SCREEN_OPTION_BACKGROUNDS].value.list.nValue;
     if (n)
     {
@@ -1256,13 +1493,17 @@ cubePaintBackground (CompScreen   *s,
 	GLfloat     *d, *data;
 
 	if (!nBox)
+	{
+	    cubeUnSetBackgroundOpacity(s);
 	    return;
+	}
 
 	n = (s->x * cs->nOutput + cs->srcOutput) % n;
 
 	if (s->desktopWindowCount)
 	{
 	    cubeUnloadBackgrounds (s);
+	    cubeUnSetBackgroundOpacity(s);
 	    return;
 	}
 	else
@@ -1278,7 +1519,10 @@ cubePaintBackground (CompScreen   *s,
 
 	data = malloc (sizeof (GLfloat) * nBox * 16);
 	if (!data)
+	{
+	    cubeUnSetBackgroundOpacity(s);
 	    return;
+	}
 
 	d = data;
 	n = nBox;
@@ -1335,6 +1579,53 @@ cubePaintBackground (CompScreen   *s,
 	(*s->paintBackground) (s, region, mask);
 	WRAP (cs, s, paintBackground, cubePaintBackground);
     }
+
+    cubeUnSetBackgroundOpacity(s);
+}
+
+static Bool
+cubePaintWindow (CompWindow		  *w,
+		 const WindowPaintAttrib  *attrib,
+		 const CompTransform	  *transform,
+		 Region			  region,
+		 unsigned int		  mask)
+{
+    Bool status;
+    CompScreen* s = w->screen;
+    CUBE_SCREEN(s);
+
+    WindowPaintAttrib wa = *attrib;
+
+    if (w->type & CompWindowTypeDesktopMask)
+	wa.opacity = cs->desktopOpacity;
+
+    UNWRAP (cs, s, paintWindow);
+    status = (*s->paintWindow) (w, &wa, transform, region, mask);
+    WRAP (cs, s, paintWindow, cubePaintWindow);
+
+    return status;
+}
+
+static void
+cubeInitWindowWalker (CompScreen *s, CompWalker* walker)
+{
+    CUBE_SCREEN (s);
+
+    UNWRAP (cs, s, initWindowWalker);
+    (*s->initWindowWalker) (s, walker);
+    WRAP (cs, s, initWindowWalker, cubeInitWindowWalker);
+
+    if (cs->paintOrder == FTB)
+    {
+	WalkInitProc tmpInit = walker->first;
+	WalkStepProc tmpStep = walker->next;
+
+	walker->first = walker->last;
+	walker->last = tmpInit;
+
+	walker->next = walker->prev;
+	walker->prev = tmpStep;
+    }
 }
 
 static void
@@ -1640,7 +1931,11 @@ static const CompMetadataOptionInfo cubeScreenOptionInfo[] = {
     { "timestep", "float", "<min>0.1</min>", 0, 0 },
     { "mipmap", "bool", 0, 0, 0 },
     { "backgrounds", "list", "<type>string</type>", 0, 0 },
-    { "adjust_image", "bool", 0, 0, 0 }
+    { "adjust_image", "bool", 0, 0, 0 },
+    { "active_opacity", "float", "<min>0.0</min><max>100.0</max>", 0, 0 },
+    { "inactive_opacity", "float", "<min>0.0</min><max>100.0</max>", 0, 0 },
+    { "fade_time", "float", "<min>0.0</min>", 0, 0 },
+    { "transparent_manual_only", "bool", 0, 0, 0 }
 };
 
 static Bool
@@ -1711,6 +2006,10 @@ cubeInitScreen (CompPlugin *p,
     cs->outputXOffset = 0.0f;
     cs->outputYOffset = 0.0f;
 
+    cs->rotationState = RotationNone;
+
+    cs->desktopOpacity = OPAQUE;
+
     memset (cs->cleared, 0, sizeof (cs->cleared));
 
     cubeUpdateOutputs (s);
@@ -1733,9 +2032,11 @@ cubeInitScreen (CompPlugin *p,
     WRAP (cs, s, paintOutput, cubePaintOutput);
     WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput);
     WRAP (cs, s, paintBackground, cubePaintBackground);
+    WRAP (cs, s, paintWindow, cubePaintWindow);
     WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
     WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption);
     WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
+    WRAP (cs, s, initWindowWalker, cubeInitWindowWalker);
 
     return TRUE;
 }
@@ -1754,9 +2055,11 @@ cubeFiniScreen (CompPlugin *p,
     UNWRAP (cs, s, paintOutput);
     UNWRAP (cs, s, paintTransformedOutput);
     UNWRAP (cs, s, paintBackground);
+    UNWRAP (cs, s, paintWindow);
     UNWRAP (cs, s, applyScreenTransform);
     UNWRAP (cs, s, setScreenOption);
     UNWRAP (cs, s, outputChangeNotify);
+    UNWRAP (cs, s, initWindowWalker);
 
     finiTexture (s, &cs->texture);
     finiTexture (s, &cs->sky);

Modified: compiz/plugins/rotate.c
===================================================================
--- compiz/plugins/rotate.c
+++ compiz/plugins/rotate.c
@@ -346,6 +346,9 @@ rotatePreparePaintScreen (CompScreen *s,
 		    else
 			tx = (s->hsize * xrot / 360.0f) + 0.5f;
 
+		    /* flag end of rotation */
+		    cs->rotationState = RotationNone;
+
 		    moveScreenViewport (s, tx, 0, TRUE);
 
 		    rs->xrot = 0.0f;
@@ -559,6 +562,7 @@ rotateInitiate (CompDisplay     *d,
     if (s)
     {
 	ROTATE_SCREEN (s);
+	CUBE_SCREEN (s);
 
 	if (s->hsize < 2)
 	    return FALSE;
@@ -577,6 +581,14 @@ rotateInitiate (CompDisplay     *d,
 	rs->moving = FALSE;
 	rs->slow   = FALSE;
 
+	/* Set the rotation state for cube - if action is non-NULL,
+	   we set it to manual (as we were called from the 'Initiate
+	   Rotation' binding. Otherwise, we set to to Change. */
+	if (action)
+	    cs->rotationState = RotationManual;
+	else
+	    cs->rotationState = RotationChange;
+
 	if (!rs->grabIndex)
 	{
 	    rs->grabIndex = pushScreenGrab (s, s->invisibleCursor, "rotate");



More information about the commits mailing list