[compiz] Re: [PATCH] Transparent cube

Roi Cohen roico.beryl at gmail.com
Sun Apr 22 04:22:09 PDT 2007


Hi,
I re-generated the patches, so it will work now against latest git.
Please note that the vertical rotation bug is now fixed, due to this commit:
http://gitweb.freedesktop.org/?p=xorg/app/compiz.git;a=commit;h=36ca8bf259d79ef5ee3630e1741a213163ebbfb6

David, what do you think of these patches?
Some feedback is still appreciated.

Btw, I already have a working 3d version for compiz, which is using
these patches.
You can find it here:
http://gitweb.opencompositing.org/?p=compcomm/plugins/beryl-premerge;a=tree;f=src/3d;h=e87e7f5383c944f6a31e589a52122bd33cd4e61e;hb=HEAD

Thanks,
Roi.

On 4/16/07, Roi Cohen <roico.beryl at gmail.com> wrote:
> hi,
>
> about the vRotate bug, i found a fix for it which makes a lot of sense
> to me, it will actually make all rotations more accurate, even with
> the old cube's calculations, and will fix the bug with my calculations
> as a side-effect... ;-)
>
> in paint.c lines 59-63 (applyScreenTransform) you do:
> matrixRotate (transform,
>                        sAttrib->vRotate,
>                        1.0f - sAttrib->xRotate / 90.0f,
>                        0.0f,
>                        sAttrib->xRotate / 90.0f);
>
> you use this rotation axis and not just x axis because you need to use
> the "old" x axis - the axis that was before the x-rotation changed it.
> the formula you use, however, isn't accurate, and with negative
> xRotate values the rotation become wrong (hence the bugs with my
> patches).
>
> after doing some simple calculations, the correct way to do this
> rotation is to use this line instead:
> matrixRotate (transform, sAttrib->vRotate,
>                   cos(sAttrib->xRotate * DEG2RAD),
>                   0.0f,
>                   sin(sAttrib->xRotate * DEG2RAD));
>
> (where DEG2RAD is #define DEG2RAD (M_PI / 180.0f) and copied from matrix.c)
>
> with this formula, all xRotate values are "supported" (negative,
> positive, >90 etc), and the axis itself is always more accurate, so i
> think it'd make sense to change it, even without the new cube's
> calculations.
>
> thanks,
> Roi
>
> On 4/12/07, Roi Cohen <roico.beryl at gmail.com> wrote:
> > Hi,
> > Recently i have worked on re-writing beryl's transparent cube, and
> > ported 3d plugin to compiz.
> > I'm attaching a patchset here that includes the transparent cube
> > patches (i'll post the 3d plugin when i fix some problems that didn't
> > happen in beryl).
> > Patching order: btf-ftb.patch, clip-planes.patch, plugin-events.patch,
> > cube-paint-order.patch, transparent-cube.patch.
> >
> > Special thanks to Dennis Kasprzyk (who originally wrote some of these
> > patches to compiz, and helped me now with various things), Quinn Storm
> > (who helped me with the options), and Danny Baumann (who did most of
> > the events stuff).
> >
> > This is what my patch includes:
> >
> > Core Changes:
> >
> > - BTF / FTB masks.
> > FTB mask allows compiz to paint the windows in reversed order, front
> > to back. This is needed when we paint a a cube face which is reversed.
> > BTF mask alone doesn't do anything, but when combined with FTB mask,
> > core will first paint the screen with regular order and after that in
> > reversed order; the plugin that set BTF and FTB mask together is
> > responsible for preventing core from painting the window twice. This
> > allows plugins to make more complicated drawing orders. This feature
> > isn't needed for transparent cube, but it is needed for 3d plugin.
> > This patch was originally written by Dennis Kasprzyk for beryl (who
> > also gave the idea), and now re-written for compiz by me.
> >
> > -  Wrappable SetClippingPlanes
> > Just a new wrappable function for setting clipping planes. This is
> > needed for correct clipping of the cube together with 3d plugin.
> > This patch was written by Dennis Kasprzyk again, and ported to compiz.
> >
> > Plugin changes:
> >
> > - Some new events code
> > Specifically: Rotate sending event to cube / 3d to notify about
> > rotations. This is needed for 3d to initiate, and for setting
> > transparent cube on rotate only. Also, 3d sending an event to cube to
> > request to paint all viewports, this is needed for handling some
> > disappearing windows in 3d (the cube face becomes invisible, but the
> > windows that come out 3d are still visible in small parts, but
> > disappear if cube doesn't paint that viewport).
> > Last, cube is sending unfold event to 3d, needed for preventing 3d to
> > transform the windows in z axis when a window is between 2 viewports.
> >
> > - Transparent cube
> > The calculations / painting code done by cube are now changed to make
> > cube to paint the faces in correct drawing order, back faces first,
> > front faces last.
> > Of course, i disable culling and set the desktop-window opacity to
> > actually make the cube transparent, and make sure cube draws all
> > viewports when the cube is transparent (when the cube isn't
> > transparent, only the front faces are painted).
> >
> >
> > This screenshot of beryl shows what happens with 3d and a window that
> > is on 2 different viewports. It shows why we need to change the
> > clipping planes for cube. Also, it shows when setting both FTB and BTF
> > is needed (notice how the 3 top-most windows of the right viewport
> > should be painted FTB, and the 2 bottom-most windows should be painted
> > BTF).
> > http://img454.imageshack.us/my.php?image=screenshotgy4.png
> > Another screeshot of the transparent-cube with 3d plugin (in beryl
> > again): http://img74.imageshack.us/my.php?image=cube3dyi6.jpg
> >
> >
> > There are some things that I'm not really sure if they work fine with
> > my patch, or they have bugs:
> >
> > - Currently, i'm painting all the faces of the cube when using inside
> > cube (only when transparent), while some faces are never visible.
> > This is needed when zooming out the cube, so i think this is a good
> > idea anyway, but i'd like to know what you think about it.
> >
> > - Unredirecting fullscreen windows is done by paintScreenRegion which
> > finds the top-fullscreen window. When doing FTB drawing, it will find
> > the bottom-fullscreen window, and when doing both BTF / FTB drawing,
> > it'll find the top and the bottom fullscreen windows. I'm not sure
> > weather this is really wrong, so again I'd like to hear your opinion
> > if my patch makes bugs on this area.
> >
> > - The cubeCheckFTB function (checks if the next-painted face should be
> > drawn with FTB flag) seems to not work in some occasions with inside
> > cube (works perfectly with outside cube). I don't know why this
> > happens though.
> >
> > - Because of the calculations-changes i made for making transparent
> > cube to work, xRotate has different values now from what it used to
> > have (it has the rotation of the top-most face, which means between
> > -45 and 45 for 4 sided cube, between -30 and 30 for 3 sided cube etc),
> > and this change results in some weird bugs when rotating the cube with
> > vertical rotations.
> > I looked at applyScreenTransform, and it looks like the rotation axis
> > that is used for vertical rotating expects the old values of xRotate.
> > This should be fixed, but i'm not sure what is the correct way to do
> > vertical rotations with the "new" values. Do you have any idea how to
> > properly do that?
> >
> > - Unfold cube doesn't work any more at all. It got broken by my new
> > calculations, and i couldn't find any way to fix it. Could anyone of
> > you help in fixing it?
> >
> > Any help is really appreciated :-)
> >
> > Thanks,
> > Roi.
> >
> >
>
-------------- next part --------------
From 0cc3399c7f9f2b91aaca007792269daea674ba3c Mon Sep 17 00:00:00 2001
From: Roi Cohen <roico at roico-desktop.(none)>
Date: Sun, 22 Apr 2007 14:08:47 +0300
Subject: [PATCH] btf-ftb

---
 include/compiz.h |   13 ++++++++++++
 src/paint.c      |   55 ++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/include/compiz.h b/include/compiz.h
index eb3f142..2f49bec 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -1171,6 +1171,12 @@ typedef void (*DonePaintScreenProc) (CompScreen *screen);
 #define PAINT_SCREEN_TRANSFORMED_MASK		   (1 << 2)
 #define PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK (1 << 3)
 #define PAINT_SCREEN_CLEAR_MASK			   (1 << 4)
+#define PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK	   (1 << 5)
+#define PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK	   (1 << 6)
+/* A plugin that sets PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK will get reversed painting.
+   A plugin that sets  both PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK and PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK
+   will get both normal and reversed painting one after the other,
+   and will check paint window mask to avoid painting the window twice. This allows more complex drawing order.*/
 
 typedef Bool (*PaintScreenProc) (CompScreen		 *screen,
 				 const ScreenPaintAttrib *sAttrib,
@@ -1216,6 +1222,13 @@ typedef void (*ApplyScreenTransformProc) (CompScreen		  *screen,
 #define PAINT_WINDOW_OCCLUSION_DETECTION_MASK   (1 << 1)
 
 /*
+ flags that indicate the painting order which is used
+ in paintScreen when drawing the window.
+*/
+#define PAINT_WINDOW_BACK_TO_FRONT_MASK		(1 << 2)
+#define PAINT_WINDOW_FRONT_TO_BACK_MASK		(1 << 3)
+
+/*
   flag indicate that window is translucent.
 */
 #define PAINT_WINDOW_TRANSLUCENT_MASK           (1 << 16)
diff --git a/src/paint.c b/src/paint.c
index a486672..bd0d7ad 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -159,7 +159,9 @@ paintScreenRegion (CompScreen	       *screen,
     static Region tmpRegion = NULL;
     CompWindow    *w;
     CompCursor	  *c;
-    int		  count, windowMask, backgroundMask;
+    int		  count, windowMask, backgroundMask, occlusionMask;
+    Bool ftb = (mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK) && 
+               !(mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK);	// Do FTB drawing only if FTB flag is set and BTF flag isn't
 
     if (!tmpRegion)
     {
@@ -180,11 +182,30 @@ paintScreenRegion (CompScreen	       *screen,
 	windowMask     = 0;
 	count	       = 0;
     }
+    
+    
+    if (ftb)
+    {
+	windowMask |= PAINT_WINDOW_FRONT_TO_BACK_MASK;
+	occlusionMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK | 
+	               PAINT_WINDOW_FRONT_TO_BACK_MASK;
+    }
+    else
+    {
+	windowMask |= PAINT_WINDOW_BACK_TO_FRONT_MASK;
+	occlusionMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK | 
+	               PAINT_WINDOW_BACK_TO_FRONT_MASK;
+    }
 
     XSubtractRegion (region, &emptyRegion, tmpRegion);
 
-    /* detect occlusions */
-    for (w = screen->reverseWindows; w; w = w->prev)
+    /* detect occlusions (order is reversed from true painting order). */
+    if (ftb)
+	w = screen->windows;
+    else
+	w = screen->reverseWindows;
+
+    for (; w; w = (ftb)? w->next: w->prev)
     {
 	if (w->destroyed)
 	    continue;
@@ -218,8 +239,13 @@ paintScreenRegion (CompScreen	       *screen,
 
     (*screen->paintBackground) (screen, tmpRegion, backgroundMask);
 
-    /* paint all windows from bottom to top */
-    for (w = screen->windows; w; w = w->next)
+    /* paint all windows with the order specified by the masks. */
+    if (ftb)
+	w = screen->reverseWindows;
+    else
+	w = screen->windows;
+
+    for (; w; w = (ftb)? w->prev: w->next)
     {
 	if (w->destroyed)
 	    continue;
@@ -233,9 +259,22 @@ paintScreenRegion (CompScreen	       *screen,
 	(*screen->paintWindow) (w, &w->paint, transform, w->clip, windowMask);
     }
 
-    /* paint cursors */
-    for (c = screen->cursors; c; c = c->next)
-	(*screen->paintCursor) (c, transform, tmpRegion, 0);
+    if ((mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK) &&
+        (mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK))
+    {
+	/* when both modes are set, we first paint in Back-To-Front mode (already done), 
+	   and after that we paint the screen in Front-To-Back mode, by removing the 
+	   Back-To-Front mask. 
+	   Painting the cursors will be done after the Front-To-Back drawing*/
+	paintScreenRegion (screen, transform, region, output, 
+	                   mask & (~PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK));	
+    }
+    else
+    {
+	/* paint cursors */
+	for (c = screen->cursors; c; c = c->next)
+	    (*screen->paintCursor) (c, transform, tmpRegion, 0);
+    }
 }
 
 
-- 
1.4.4.2
-------------- next part --------------
From 3ae75c44dc574844223c46fc5e20f341ab4e1be1 Mon Sep 17 00:00:00 2001
From: Roi Cohen <roico at roico-desktop.(none)>
Date: Sun, 22 Apr 2007 14:09:09 +0300
Subject: [PATCH] clip-planes

---
 include/compiz.h |   12 +++++++++++-
 plugins/cube.c   |   38 ++++++++++++++++++++++++++++++++++++++
 src/paint.c      |   45 +++++++++++++++++++++++++--------------------
 src/screen.c     |    1 +
 4 files changed, 75 insertions(+), 21 deletions(-)

diff --git a/include/compiz.h b/include/compiz.h
index 2f49bec..ee974f0 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -26,7 +26,7 @@
 #ifndef _COMPIZ_H
 #define _COMPIZ_H
 
-#define ABIVERSION 20070420
+#define ABIVERSION 20070421
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -1286,6 +1286,11 @@ typedef void (*PaintBackgroundProc) (CompScreen   *screen,
 				     Region	  region,
 				     unsigned int mask);
 
+typedef void (*SetClipPlanesProc) (CompScreen *screen,
+                                   Region region,
+                                   int output);
+
+
 void
 preparePaintScreen (CompScreen *screen,
 		    int	       msSinceLastPaint);
@@ -1374,6 +1379,10 @@ paintBackground (CompScreen   *screen,
 		 Region	      region,
 		 unsigned int mask);
 
+void setClipPlanes (CompScreen *screen, 
+                   Region region,
+                   int output);
+
 
 /* texture.c */
 
@@ -1964,6 +1973,7 @@ struct _CompScreen {
     GetAllowedActionsForWindowProc getAllowedActionsForWindow;
     FocusWindowProc		   focusWindow;
     PlaceWindowProc                placeWindow;
+    SetClipPlanesProc		   setClipPlanes;
 
     PaintCursorProc      paintCursor;
     DamageCursorRectProc damageCursorRect;
diff --git a/plugins/cube.c b/plugins/cube.c
index ba14493..7d7135a 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -135,6 +135,7 @@ typedef struct _CubeScreen {
     ApplyScreenTransformProc   applyScreenTransform;
     SetScreenOptionProc	       setScreenOption;
     OutputChangeNotifyProc     outputChangeNotify;
+    SetClipPlanesProc          setClipPlanes;
 
     CompOption opt[CUBE_SCREEN_OPTION_NUM];
 
@@ -1740,6 +1741,41 @@ cubePaintBackground (CompScreen   *s,
     }
 }
 
+static void cubeSetClipPlanes (CompScreen *s, Region region, int output)
+{
+    CUBE_SCREEN(s);
+
+    glTranslatef(cs->outputXOffset, -cs->outputYOffset, 0.0f);
+    glScalef( cs->outputXScale, cs->outputYScale, 1.0f);
+
+    UNWRAP(cs, s, setClipPlanes);
+    (*s->setClipPlanes) (s, region, output);
+    WRAP(cs, s, setClipPlanes, cubeSetClipPlanes);
+
+    if (cs->invert == 1)
+    {
+	GLdouble clipPlane0[] = { 1.0, 0.0, 0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane1[] = { -1.0,  0.0, 0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane2[] = { 0.0,  -1.0, 0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane3[] = { 0.0,  1.0, 0.5 / cs->distance, 0.0 };
+	glClipPlane (GL_CLIP_PLANE0, clipPlane0);
+	glClipPlane (GL_CLIP_PLANE1, clipPlane1);
+	glClipPlane (GL_CLIP_PLANE2, clipPlane2);
+	glClipPlane (GL_CLIP_PLANE3, clipPlane3);
+    }
+    else
+    {
+	GLdouble clipPlane0[] = { -1.0, 0.0, -0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane1[] = { 1.0,  0.0, -0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane2[] = { 0.0,  1.0, -0.5 / cs->distance, 0.0 };
+	GLdouble clipPlane3[] = { 0.0,  -1.0, -0.5 / cs->distance, 0.0 };
+	glClipPlane (GL_CLIP_PLANE0, clipPlane0);
+	glClipPlane (GL_CLIP_PLANE1, clipPlane1);
+	glClipPlane (GL_CLIP_PLANE2, clipPlane2);
+	glClipPlane (GL_CLIP_PLANE3, clipPlane3);
+    }
+}
+
 static void
 cubeApplyScreenTransform (CompScreen		  *s,
 			  const ScreenPaintAttrib *sAttrib,
@@ -2143,6 +2179,7 @@ cubeInitScreen (CompPlugin *p,
     WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
     WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption);
     WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
+    WRAP (cs, s, setClipPlanes, cubeSetClipPlanes);
 
     cubeUpdateOutputs (s);
 
@@ -2178,6 +2215,7 @@ cubeFiniScreen (CompPlugin *p,
     UNWRAP (cs, s, applyScreenTransform);
     UNWRAP (cs, s, setScreenOption);
     UNWRAP (cs, s, outputChangeNotify);
+    UNWRAP (cs, s, setClipPlanes);
 
     finiTexture (s, &cs->texture);
     finiTexture (s, &cs->sky);
diff --git a/src/paint.c b/src/paint.c
index bd0d7ad..906a1f7 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -300,29 +300,10 @@ paintTransformedScreen (CompScreen		*screen,
 
     if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK)
     {
-	GLdouble h = screen->height;
-
-	GLdouble p1[2] = { region->extents.x1, h - region->extents.y2 };
-	GLdouble p2[2] = { region->extents.x2, h - region->extents.y1 };
-
-	GLdouble halfW = screen->outputDev[output].width / 2.0;
-	GLdouble halfH = screen->outputDev[output].height / 2.0;
-
-	GLdouble cx = screen->outputDev[output].region.extents.x1 + halfW;
-	GLdouble cy = (h - screen->outputDev[output].region.extents.y2) + halfH;
-
-	GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
-	GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
-	GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
-	GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
-
 	glPushMatrix ();
 	glLoadMatrixf (sTransform.m);
 
-	glClipPlane (GL_CLIP_PLANE0, top);
-	glClipPlane (GL_CLIP_PLANE1, bottom);
-	glClipPlane (GL_CLIP_PLANE2, left);
-	glClipPlane (GL_CLIP_PLANE3, right);
+	(*screen->setClipPlanes) (screen, region, output);
 
 	glEnable (GL_CLIP_PLANE0);
 	glEnable (GL_CLIP_PLANE1);
@@ -1195,3 +1176,27 @@ paintBackground (CompScreen   *s,
 
     free (data);
 }
+
+void setClipPlanes (CompScreen *screen, Region region, int output)
+{
+    GLdouble h = screen->height;
+
+    GLdouble p1[2] = { region->extents.x1, h - region->extents.y2 };
+    GLdouble p2[2] = { region->extents.x2, h - region->extents.y1 };
+
+    GLdouble halfW = screen->outputDev[output].width / 2.0;
+    GLdouble halfH = screen->outputDev[output].height / 2.0;
+
+    GLdouble cx = screen->outputDev[output].region.extents.x1 + halfW;
+    GLdouble cy = (h - screen->outputDev[output].region.extents.y2) + halfH;
+
+    GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
+    GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
+    GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
+    GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
+
+    glClipPlane (GL_CLIP_PLANE0, top);
+    glClipPlane (GL_CLIP_PLANE1, bottom);
+    glClipPlane (GL_CLIP_PLANE2, left);
+    glClipPlane (GL_CLIP_PLANE3, right);
+}
diff --git a/src/screen.c b/src/screen.c
index 68e8f41..314503a 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1566,6 +1566,7 @@ addScreen (CompDisplay *display,
     s->getAllowedActionsForWindow = getAllowedActionsForWindow;
     s->focusWindow		  = focusWindow;
     s->placeWindow                = placeWindow;
+    s->setClipPlanes		  = setClipPlanes;
 
     s->paintCursor      = paintCursor;
     s->damageCursorRect	= damageCursorRect;
-- 
1.4.4.2
-------------- next part --------------
From 86b78d904a877ad5360a32a03be124c75a658b8c Mon Sep 17 00:00:00 2001
From: Roi Cohen <roico at roico-desktop.(none)>
Date: Sun, 22 Apr 2007 14:09:31 +0300
Subject: [PATCH] plugin-events

---
 plugins/cube.c   |  102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 plugins/rotate.c |   32 ++++++++++++++++-
 2 files changed, 133 insertions(+), 1 deletions(-)

diff --git a/plugins/cube.c b/plugins/cube.c
index 7d7135a..826e389 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -46,6 +46,13 @@
 
 #include <compiz.h>
 
+typedef enum _RotationMode
+{
+    NoRotation = 0,
+    RotationChange,
+    RotationManual
+} RotationMode;
+
 #define CUBE_COLOR_RED_DEFAULT   0xefef
 #define CUBE_COLOR_GREEN_DEFAULT 0xebeb
 #define CUBE_COLOR_BLUE_DEFAULT  0xe7e7
@@ -108,6 +115,8 @@ typedef struct _CubeDisplay {
     int		    screenPrivateIndex;
 
     CompOption opt[CUBE_DISPLAY_OPTION_NUM];
+    
+    HandleCompizEventProc handleCompizEvent;
 } CubeDisplay;
 
 #define CUBE_SCREEN_OPTION_COLOR	      0
@@ -176,11 +185,15 @@ typedef struct _CubeScreen {
     Bool cleared[64];
 
     Bool fullscreenOutput;
+    RotationMode rotationMode;
 
     float outputXScale;
     float outputYScale;
     float outputXOffset;
     float outputYOffset;
+    
+    Bool disableCaps;
+    Bool paintAllViewports;
 
     CompTexture *bg;
     int		nBg;
@@ -1796,6 +1809,85 @@ cubeApplyScreenTransform (CompScreen		  *s,
     matrixTranslate (transform, -cs->outputXOffset, cs->outputYOffset, 0.0f);
 }
 
+static void cubeHandleCompizEvent(CompDisplay * d, char *pluginName,
+				 char *eventName, CompOption * option, int nOption)
+{
+    CUBE_DISPLAY(d);
+
+    UNWRAP (cd, d, handleCompizEvent);
+    (*d->handleCompizEvent) (d, pluginName, eventName, option, nOption);
+    WRAP (cd, d, handleCompizEvent, cubeHandleCompizEvent);
+	
+    if (strcmp(pluginName, "3d") == 0)
+    {
+	if (strcmp(eventName, "disableCapsEvent") == 0)
+	{
+	    Window xid = getIntOptionNamed(option, nOption, "root", 0);
+	    CompScreen *s = findScreenAtDisplay(d, xid);
+
+	    if (s)
+	    {
+		CUBE_SCREEN(s);
+		cs->disableCaps = getBoolOptionNamed(option, nOption, "disableCaps", FALSE);
+	    }
+	}
+	
+	else if (strcmp(eventName, "paintAllViewportsEvent") == 0)
+	{
+	    Window xid = getIntOptionNamed(option, nOption, "root", 0);
+	    CompScreen *s = findScreenAtDisplay(d, xid);
+
+	    if (s)
+	    {
+		CUBE_SCREEN(s);
+		cs->paintAllViewports = getBoolOptionNamed(option, nOption, "paintAllViewports", FALSE);
+	    }
+	}
+    }
+    if (strcmp(pluginName, "rotate") == 0)
+    {
+	if (strcmp(eventName, "rotateEvent") == 0)
+	{
+	    Window xid = getIntOptionNamed(option, nOption, "root", 0);
+	    CompScreen *s = findScreenAtDisplay(d, xid);
+
+	    if (s)
+	    {
+		CUBE_SCREEN(s);
+		Bool rotate = getBoolOptionNamed(option, nOption, "rotating", FALSE);
+		Bool manual = getBoolOptionNamed(option, nOption, "manual", FALSE);
+
+		if (rotate && manual)
+		    cs->rotationMode = RotationManual;
+		else if (rotate)
+		    cs->rotationMode = RotationChange;
+		else
+		    cs->rotationMode = NoRotation;
+		damageScreen(s);
+	    }
+	}
+    }
+}
+
+static void
+cubeFoldEvent(CompScreen *s, Bool unfolded)
+{
+    CompOption o[2];
+    
+    o[0].type = CompOptionTypeInt;
+    o[0].name = "root";
+    o[0].value.i = s->root;
+
+    o[1].type = CompOptionTypeBool;
+    o[1].name = "unfolded";
+    o[1].value.b = unfolded;
+
+    (*s->display->handleCompizEvent) (s->display, 
+                                      "cube", 
+                                      "unfoldEvent", 
+                                      o, 2);
+}
+
 static Bool
 cubeUnfold (CompDisplay     *d,
 	    CompAction      *action,
@@ -1825,6 +1917,7 @@ cubeUnfold (CompDisplay     *d,
 	if (cs->grabIndex)
 	{
 	    cs->unfolded = TRUE;
+	    cubeFoldEvent (s, TRUE);
 	    damageScreen (s);
 	}
 
@@ -1860,6 +1953,7 @@ cubeFold (CompDisplay     *d,
 	if (cs->grabIndex)
 	{
 	    cs->unfolded = FALSE;
+	    cubeFoldEvent (s, FALSE);
 	    damageScreen (s);
 	}
     }
@@ -2086,6 +2180,8 @@ cubeInitDisplay (CompPlugin  *p,
     cubeDisplayInitOptions (cd, d->display);
 
     d->privates[displayPrivateIndex].ptr = cd;
+    
+    WRAP (cd, d, handleCompizEvent, cubeHandleCompizEvent);
 
     return TRUE;
 }
@@ -2102,6 +2198,8 @@ cubeFiniDisplay (CompPlugin  *p,
     CUBE_DISPLAY (d);
 
     freeScreenPrivateIndex (d, cd->screenPrivateIndex);
+    
+    UNWRAP (cd, d, handleCompizEvent);
 
     free (cd);
 }
@@ -2162,6 +2260,10 @@ cubeInitScreen (CompPlugin *p,
     cs->bg  = NULL;
     cs->nBg = 0;
 
+    cs->disableCaps = FALSE;
+    cs->paintAllViewports = FALSE;
+    cs->rotationMode = NoRotation;
+
     memset (cs->cleared, 0, sizeof (cs->cleared));
 
     cubeScreenInitOptions (cs, s->display->display);
diff --git a/plugins/rotate.c b/plugins/rotate.c
index bf6bb95..f4179db 100644
--- a/plugins/rotate.c
+++ b/plugins/rotate.c
@@ -400,6 +400,30 @@ rotateReleaseMoveWindow (CompScreen *s)
     rs->moveWindow = None;
 }
 
+static void rotateEvent(CompScreen *s, 
+			Bool       rotating, 
+			Bool       manual)
+{
+    CompOption o[3];
+
+    o[0].type = CompOptionTypeInt;
+    o[0].name = "root";
+    o[0].value.i = s->root;
+
+    o[1].type = CompOptionTypeBool;
+    o[1].name = "rotating";
+    o[1].value.b = rotating;
+
+    o[2].type = CompOptionTypeBool;
+    o[2].name = "manual";
+    o[2].value.b = manual;
+
+    (*s->display->handleCompizEvent)(s->display, 
+				     "rotate", 
+				     "rotateEvent", 
+				     o, 3);
+}
+
 static void
 rotatePreparePaintScreen (CompScreen *s,
 			  int	     msSinceLastPaint)
@@ -484,7 +508,9 @@ rotatePreparePaintScreen (CompScreen *s,
 			tx = (s->hsize * xrot / 360.0f) - 0.5f;
 		    else
 			tx = (s->hsize * xrot / 360.0f) + 0.5f;
-
+		    
+		    rotateEvent (s, FALSE, FALSE);
+		    
 		    moveScreenViewport (s, tx, 0, TRUE);
 
 		    rs->xrot = 0.0f;
@@ -637,6 +663,10 @@ rotateInitiate (CompDisplay     *d,
 
 	rs->moving = FALSE;
 	rs->slow   = FALSE;
+	
+	/* notify other plugins that rotation starts - if action is
+	   non-NULL, we are called from the 'Initiate rotate' binding */
+	rotateEvent (s, TRUE, (action != NULL));
 
 	if (!rs->grabIndex)
 	{
-- 
1.4.4.2
-------------- next part --------------
From 6e8e79864c5096a03c743ff0a50287abba9678c0 Mon Sep 17 00:00:00 2001
From: Roi Cohen <roico at roico-desktop.(none)>
Date: Sun, 22 Apr 2007 14:09:54 +0300
Subject: [PATCH] cube paint order

---
 plugins/cube.c |  396 ++++++++++++++++++++++++++++++++------------------------
 1 files changed, 229 insertions(+), 167 deletions(-)

diff --git a/plugins/cube.c b/plugins/cube.c
index 826e389..78583a9 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -135,6 +135,37 @@ typedef struct _CubeDisplay {
 #define CUBE_SCREEN_OPTION_BACKGROUNDS	      13
 #define CUBE_SCREEN_OPTION_NUM                14
 
+#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];
+
 typedef struct _CubeScreen {
     PreparePaintScreenProc     preparePaintScreen;
     DonePaintScreenProc	       donePaintScreen;
@@ -1311,6 +1342,59 @@ cubeDonePaintScreen (CompScreen *s)
     WRAP (cs, s, donePaintScreen, cubeDonePaintScreen);
 }
 
+static Bool
+cubeCheckFTB (CompScreen *s, 
+              const ScreenPaintAttrib *sAttrib, 
+              const CompTransform  *transform,
+              int output)
+{
+    float mvp[16];
+    CompTransform sTransform = *transform;
+    
+    (*s->applyScreenTransform) (s, sAttrib, output, &sTransform);
+    transformToScreenSpace (s, output, -sAttrib->zTranslate, &sTransform);
+
+    MULTM(s->projection, sTransform.m, mvp);
+
+    float pntA[4] = { s->outputDev[output].region.extents.x1,
+                      s->outputDev[output].region.extents.y1,
+                      0, 1};
+
+    float pntB[4] = { s->outputDev[output].region.extents.x2,
+                      s->outputDev[output].region.extents.y1,
+                      0, 1};
+
+    float pntC[4] = { s->outputDev[output].region.extents.x1 + s->outputDev[output].width / 2.0f,
+                      s->outputDev[output].region.extents.y1 + s->outputDev[output].height / 2.0f,
+                      0, 1};
+
+    MULTMV(mvp, pntA);
+    DIVV(pntA);
+
+    MULTMV(mvp, pntB);
+    DIVV(pntB);
+
+    MULTMV(mvp, pntC);
+    DIVV(pntC);
+
+    float vecA[3] = { pntC[0] - pntA[0],
+                      pntC[1] - pntA[1],
+                      pntC[2] - pntA[2]};
+    
+    float vecB[3] = { pntC[0] - pntB[0], 
+                      pntC[1] - pntB[1],
+                      pntC[2] - pntB[2]};
+
+    float ortho[3] = { vecA[1] * vecB[2] - vecA[2] * vecB[1],
+	               vecA[2] * vecB[0] - vecA[0] * vecB[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,
@@ -1320,6 +1404,13 @@ cubeMoveViewportAndPaint (CompScreen		  *s,
 			  int			  dx)
 {
     CUBE_SCREEN (s);
+    
+    Bool ftb = cubeCheckFTB(s, sAttrib, transform, output);
+
+    if (ftb && !(mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK))
+	return;
+    if (!ftb && (mask & PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK))
+	return;
 
     if (cs->nOutput > 1)
     {
@@ -1361,6 +1452,76 @@ cubeMoveViewportAndPaint (CompScreen		  *s,
 }
 
 static void
+cubePaintAllViewports (CompScreen              *s,
+                       ScreenPaintAttrib       *sAttrib,
+	               const CompTransform     *transform,
+                       Region		       region,
+                       int                     output,
+                       unsigned int            mask,
+                       int                     xMove,
+                       int                     size, 
+                       int                     hsize)
+{
+    CUBE_SCREEN(s);
+
+    ScreenPaintAttrib sa = *sAttrib;
+
+    int i;
+    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 farest to the viewer in z axis.
+    
+	if ((sa.xRotate < 0.0f && hsize % 2 == 1) ||
+	    (sa.xRotate > 0.0f && hsize % 2 == 0))
+	{
+	    xMove += hsize / 2;
+	    sa.yRotate -= (hsize / 2) * 360.0f / size;
+	    iFirstSign = 1;
+	}
+        
+	else
+	{
+	    xMove -= hsize / 2;
+	    sa.yRotate += (hsize / 2) * 360.0f / size;
+	    iFirstSign = -1;
+	}
+    }
+    
+    else
+    {
+    	// xMove is already the dx for farest viewport.
+    
+	if (sa.xRotate > 0.0f)
+	    iFirstSign = -1;
+	else
+	    iFirstSign = 1;
+    }
+    
+    for (i = 0; i <= hsize / 2; i++)
+    {
+	xMove += iFirstSign * i;
+	sa.yRotate -= cs->invert * iFirstSign * i * 360.0f / size;
+	cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+	                          xMove);
+	sa.yRotate += cs->invert * iFirstSign * i * 360.0f / size;
+	xMove -= iFirstSign * i;
+
+	if (i == 0 || i * 2 == hsize)	// same viewport.
+	    continue;
+
+	xMove -= iFirstSign * i;
+	sa.yRotate += cs->invert * iFirstSign * i * 360.0f / size;
+	cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+	                          xMove);
+	sa.yRotate -= cs->invert * iFirstSign * i * 360.0f / size;
+	xMove += iFirstSign * i;
+    }
+}
+
+static void
 cubePaintTransformedScreen (CompScreen		    *s,
 			    const ScreenPaintAttrib *sAttrib,
 			    const CompTransform	    *transform,
@@ -1372,6 +1533,7 @@ cubePaintTransformedScreen (CompScreen		    *s,
     int		      hsize, xMove = 0;
     float	      size;
     Bool	      clear;
+    GLenum filter = s->display->textureFilter;
 
     CUBE_SCREEN (s);
 
@@ -1453,22 +1615,6 @@ cubePaintTransformedScreen (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 = sAttrib->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
     {
@@ -1480,21 +1626,35 @@ cubePaintTransformedScreen (CompScreen		    *s,
 	    sa.vRotate = sAttrib->vRotate;
 
 	sa.zTranslate = -cs->invert * cs->distance;
-	sa.xRotate = sAttrib->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--;
-	}
     }
 
+    sa.xRotate = sAttrib->xRotate;
+	
+    if (sa.xRotate > 0.0f)
+	cs->xrotations = (int) (hsize * sa.xRotate + 180) / 360;
+    else
+	cs->xrotations = (int) (hsize * sa.xRotate - 180) / 360;
+    
+    sa.xRotate -= (360.0f * cs->xrotations) / size;
+    sa.xRotate *= cs->invert;
+   
+    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)
+	mask |= PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK;	// Outside cube - start with FTB faces.
+	                                              	// Inside cube - start with BTF faces.
+    
+    if (cs->paintAllViewports || cs->invert == -1)
+	cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize);
+    
+    if (cs->invert == 1)
+	mask &= ~PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK;	// Outside cube - continue with caps and then BTF faces.
+    else
+	mask |= PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK;	// Inside cube - continue with caps and then FTB faces.
+
     if (!clear && cs->grabIndex == 0 && hsize > 2 &&
 	(cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f))
     {
@@ -1506,155 +1666,57 @@ cubePaintTransformedScreen (CompScreen		    *s,
 
 	glPushMatrix ();
 
-	if (sAttrib->xRotate > 0.0f)
-	{
-	    sa.yRotate += 360.0f / size;
-	    (*s->applyScreenTransform) (s, &sa, output, &sTransform);
-	    glLoadMatrixf (sTransform.m);
-	    glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
-	    glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
-	    sa.yRotate -= 360.0f / size;
-	}
-	else
-	{
-	    (*s->applyScreenTransform) (s, &sa, output, &sTransform);
-	    glLoadMatrixf (sTransform.m);
-	    glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
-	    glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
-	}
+	sa.yRotate += 360.0f / size;
+	(*s->applyScreenTransform) (s, &sa, output, &sTransform);
+	glLoadMatrixf (sTransform.m);
+	glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
+	glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
+	sa.yRotate -= 360.0f / size;
 
 	glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
 
-	glNormal3f (0.0f, -1.0f, 0.0f);
-
-	if (cs->invert == 1 && hsize == 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);
-	}
-
-	glNormal3f (0.0f, 1.0f, 0.0f);
-
-	glDrawArrays (GL_TRIANGLE_FAN, cs->nvertices >> 1,
-		      cs->nvertices >> 1);
-
-	glNormal3f (0.0f, 0.0f, -1.0f);
-
-	glPopMatrix ();
-
-	glColor4usv (defaultColor);
-	glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-    }
-
-    /* outside cube */
-    if (cs->invert == 1)
-    {
-	if (cs->grabIndex || hsize > 4)
-	{
-	    GLenum filter;
-	    int    i;
-
-	    xMove = cs->xrotations - ((hsize >> 1) - 1);
-	    sa.yRotate += (360.0f / size) * ((hsize >> 1) - 1);
-
-	    filter = s->display->textureFilter;
-	    if (cs->grabIndex && cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
-		s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
-
-	    for (i = 0; i < hsize; i++)
-	    {
-		cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
-					  xMove);
-
-		sa.yRotate -= 360.0f / size;
-		xMove++;
-	    }
-
-	    s->display->textureFilter = filter;
-	}
-	else
-	{
-	    if (sAttrib->xRotate != 0.0f)
-	    {
-		xMove = cs->xrotations;
-
-		cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
-					  xMove);
-
-		xMove++;
-	    }
-
-	    sa.yRotate -= 360.0f / size;
-
-	    cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
-	}
-    }
-    else
-    {
-	if (sa.xRotate > 180.0f / size)
-	{
-	    sa.yRotate -= 360.0f / size;
-	    cs->xrotations++;
-	}
-
-	sa.yRotate -= 360.0f / size;
-	xMove = -1 - cs->xrotations;
-
-	if (cs->grabIndex)
+	int i;
+	for (i = 0; i < 2; i++)
 	{
-	    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)
+	    if ((i == 0 && sAttrib->vRotate < 0.0f) ||
+	        (i == 1 && sAttrib->vRotate > 0.0f))
 	    {
-		xMove -= ((hsize >> 1) - 2);
-		sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 2);
+		glNormal3f (0.0f, -1.0f, 0.0f);
+		if (cs->invert == 1 && hsize == 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
 	    {
-		xMove -= ((hsize >> 1) - 1);
-		sa.yRotate -= (360.0f / size) * ((hsize >> 1) - 1);
-	    }
-
-	    for (i = 0; i < hsize; i++)
-	    {
-		cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
-					  xMove);
-
-		sa.yRotate += 360.0f / size;
-		xMove++;
+		glNormal3f (0.0f, 1.0f, 0.0f);
+	        glDrawArrays (GL_TRIANGLE_FAN, cs->nvertices >> 1,
+		              cs->nvertices >> 1);
 	    }
-
-	    s->display->textureFilter = filter;
-	}
-	else
-	{
-	    cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
-
-	    sa.yRotate += 360.0f / size;
-	    xMove = -cs->xrotations;
-
-	    cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
-
-	    sa.yRotate += 360.0f / size;
-	    xMove = 1 - cs->xrotations;
-
-	    cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
 	}
+	
+	glNormal3f (0.0f, 0.0f, -1.0f);
+	
+	glPopMatrix ();
+	
+	glColor4usv (defaultColor);
+	glEnableClientState (GL_TEXTURE_COORD_ARRAY);
     }
-
+    
+    if (cs->paintAllViewports || cs->invert == 1)
+	cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize);
+    
+    s->display->textureFilter = filter;
+    
     WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
 }
 
-- 
1.4.4.2
-------------- next part --------------
From 238f71e2b777c5332f03c63ccb5f5650fc05d78d Mon Sep 17 00:00:00 2001
From: Roi Cohen <roico at roico-desktop.(none)>
Date: Sun, 22 Apr 2007 14:10:14 +0300
Subject: [PATCH] transparent cube

---
 plugins/cube.c |  244 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 223 insertions(+), 21 deletions(-)

diff --git a/plugins/cube.c b/plugins/cube.c
index 78583a9..f12b99b 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -92,6 +92,21 @@ static char *cubeImages[] = {
 #define CUBE_ACCELERATION_MAX       20.0f
 #define CUBE_ACCELERATION_PRECISION 0.1f
 
+#define CUBE_FADE_TIME_DEFAULT			1.0
+#define CUBE_FADE_TIME_MAX			10.0
+#define CUBE_FADE_TIME_MIN			0.0
+#define CUBE_FADE_TIME_PRECISION		0.1
+
+#define CUBE_OPACITY_MIN 0.0
+#define CUBE_OPACITY_MAX 100.0
+#define CUBE_OPACITY_PRECISION 1.0
+
+#define CUBE_TRANSPARENT_MANUAL_ONLY_DEFAULT FALSE
+
+#define CUBE_ACTIVE_OPACITY_DEFAULT	30
+
+#define CUBE_INACTIVE_OPACITY_DEFAULT	100
+
 #define CUBE_SPEED_DEFAULT   1.5f
 #define CUBE_SPEED_MIN       0.1f
 #define CUBE_SPEED_MAX       50.0f
@@ -119,21 +134,25 @@ typedef struct _CubeDisplay {
     HandleCompizEventProc handleCompizEvent;
 } 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_NUM                14
+#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_ACTIVE_OPACITY          13
+#define CUBE_SCREEN_OPTION_INACTIVE_OPACITY        14
+#define CUBE_SCREEN_OPTION_FADE_TIME               15
+#define CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY 16
+#define CUBE_SCREEN_OPTION_BACKGROUNDS	           17
+#define CUBE_SCREEN_OPTION_NUM                     18
 
 #define MULTM(x,y,z) \
 z[0] = x[0] * y[0] + x[4] * y[1] + x[8] * y[2] + x[12] * y[3]; \
@@ -172,6 +191,7 @@ typedef struct _CubeScreen {
     PaintScreenProc	       paintScreen;
     PaintTransformedScreenProc paintTransformedScreen;
     PaintBackgroundProc        paintBackground;
+    PaintWindowProc            paintWindow;
     ApplyScreenTransformProc   applyScreenTransform;
     SetScreenOptionProc	       setScreenOption;
     OutputChangeNotifyProc     outputChangeNotify;
@@ -225,6 +245,9 @@ typedef struct _CubeScreen {
     
     Bool disableCaps;
     Bool paintAllViewports;
+    
+    float desktopOpacity;
+    float toOpacity;
 
     CompTexture *bg;
     int		nBg;
@@ -1088,6 +1111,12 @@ cubeSetScreenOption (CompPlugin      *plugin,
 	    damageScreen (screen);
 	    return TRUE;
 	}
+	break;
+    case CUBE_SCREEN_OPTION_FADE_TIME:
+    case CUBE_SCREEN_OPTION_ACTIVE_OPACITY:
+    case CUBE_SCREEN_OPTION_INACTIVE_OPACITY:
+	if (compSetFloatOption (o,value))
+	    return TRUE;
     default:
 	break;
     }
@@ -1222,6 +1251,45 @@ cubeScreenInitOptions (CubeScreen *cs,
     o->type	  = CompOptionTypeBool;
     o->value.b    = CUBE_MIPMAP_DEFAULT;
 
+    o = &cs->opt[CUBE_SCREEN_OPTION_FADE_TIME];
+    o->name = "fade_time";
+    o->shortDesc = N_("Fade Time");
+    o->longDesc = N_("Desktop Window Opacity Fade Time.");
+    o->type = CompOptionTypeFloat;
+    o->value.f = CUBE_FADE_TIME_DEFAULT;
+    o->rest.f.min = CUBE_FADE_TIME_MIN;
+    o->rest.f.max = CUBE_FADE_TIME_MAX;
+    o->rest.f.precision = CUBE_FADE_TIME_PRECISION;
+
+    o = &cs->opt[CUBE_SCREEN_OPTION_ACTIVE_OPACITY];
+    o->name = "active_opacity";
+    o->shortDesc = N_("Opacity During Rotation");
+    o->longDesc = N_("Opacity of desktop window during rotation.");
+    o->type = CompOptionTypeFloat;
+    o->value.f = CUBE_ACTIVE_OPACITY_DEFAULT;
+    o->rest.f.min = CUBE_OPACITY_MIN;
+    o->rest.f.max = CUBE_OPACITY_MAX;
+    o->rest.f.precision = CUBE_OPACITY_PRECISION;
+
+    o = &cs->opt[CUBE_SCREEN_OPTION_INACTIVE_OPACITY];
+    o->name = "inactive_opacity";
+    o->shortDesc = N_("Opacity When Not Rotating");
+    o->longDesc = N_("Opacity of desktop window when not rotating.");
+    o->type = CompOptionTypeFloat;
+    o->value.f = CUBE_INACTIVE_OPACITY_DEFAULT;
+    o->rest.f.min = CUBE_OPACITY_MIN;
+    o->rest.f.max = CUBE_OPACITY_MAX;
+    o->rest.f.precision = CUBE_OPACITY_PRECISION;
+
+    o = &cs->opt[CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY];
+    o->name = "transparent_manual_only";
+    o->shortDesc = N_("Transparency Only\non Mouse Rotate");
+    o->longDesc =
+	N_
+	("Initiates Cube transparency only if rotation is mouse driven.");
+    o->type = CompOptionTypeBool;
+    o->value.b = CUBE_TRANSPARENT_MANUAL_ONLY_DEFAULT;
+
     o = &cs->opt[CUBE_SCREEN_OPTION_BACKGROUNDS];
     o->name	         = "backgrounds";
     o->shortDesc         = N_("Background Images");
@@ -1297,6 +1365,39 @@ cubePreparePaintScreen (CompScreen *s,
     }
 
     memset (cs->cleared, 0, sizeof (Bool) * s->nOutputDev);
+    
+    //transparency, mostly copied/ported from beryl's cube.c, orig. by onestone
+    if (cs->rotationMode != NoRotation && ((cs->rotationMode == RotationManual) || 
+		!(cs->opt[CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY].value.b)))
+    {
+	cs->toOpacity = 
+	      (cs->opt[CUBE_SCREEN_OPTION_ACTIVE_OPACITY].value.f / 100.0f) * OPAQUE;
+    }
+    else
+	cs->toOpacity =
+	    (cs->opt[CUBE_SCREEN_OPTION_INACTIVE_OPACITY].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);
@@ -1316,7 +1417,7 @@ cubePaintScreen (CompScreen		 *s,
 
     CUBE_SCREEN (s);
 
-    if (cs->grabIndex)
+    if (cs->grabIndex || cs->desktopOpacity != OPAQUE)
     {
 	mask &= ~PAINT_SCREEN_REGION_MASK;
 	mask |= PAINT_SCREEN_TRANSFORMED_MASK;
@@ -1334,7 +1435,7 @@ cubeDonePaintScreen (CompScreen *s)
 {
     CUBE_SCREEN (s);
 
-    if (cs->grabIndex)
+    if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity)
 	damageScreen (s);
 
     UNWRAP (cs, s, donePaintScreen);
@@ -1533,12 +1634,20 @@ cubePaintTransformedScreen (CompScreen		    *s,
     int		      hsize, xMove = 0;
     float	      size;
     Bool	      clear;
+    Bool wasCulled = FALSE;
     GLenum filter = s->display->textureFilter;
 
     CUBE_SCREEN (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)
     {
@@ -1647,7 +1756,7 @@ cubePaintTransformedScreen (CompScreen		    *s,
 	mask |= PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK;	// Outside cube - start with FTB faces.
 	                                              	// Inside cube - start with BTF faces.
     
-    if (cs->paintAllViewports || cs->invert == -1)
+    if (cs->paintAllViewports || cs->desktopOpacity != OPAQUE || cs->invert == -1)
 	cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize);
     
     if (cs->invert == 1)
@@ -1662,7 +1771,7 @@ cubePaintTransformedScreen (CompScreen		    *s,
 
 	screenLighting (s, TRUE);
 
-	glColor3usv (cs->color);
+	glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity);
 
 	glPushMatrix ();
 
@@ -1672,6 +1781,13 @@ cubePaintTransformedScreen (CompScreen		    *s,
 	glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
 	glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
 	sa.yRotate -= 360.0f / size;
+	
+	if (cs->desktopOpacity != OPAQUE)
+	{
+	    screenTexEnvMode (s, GL_MODULATE);
+	    glEnable(GL_BLEND);
+	    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	}
 
 	glVertexPointer (3, GL_FLOAT, 0, cs->vertices);
 
@@ -1710,17 +1826,68 @@ cubePaintTransformedScreen (CompScreen		    *s,
 	
 	glColor4usv (defaultColor);
 	glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+	
+	screenTexEnvMode(s, GL_REPLACE);
+	glDisable(GL_BLEND);
+	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
     }
     
-    if (cs->paintAllViewports || cs->invert == 1)
+    if (cs->paintAllViewports || cs->desktopOpacity != OPAQUE || cs->invert == 1)
 	cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize);
     
     s->display->textureFilter = filter;
     
+    if (cs->desktopOpacity != OPAQUE && wasCulled)
+	glEnable(GL_CULL_FACE);
+    
     WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
 }
 
 static void
+cubeSetBackgroundOpacity(CompScreen* s)
+{
+    CUBE_SCREEN(s);
+
+    if (cs->desktopOpacity != OPAQUE)
+    {
+	if (s->desktopWindowCount)
+	{
+	    glColor4us(0, 0, 0, 0);
+	    glEnable(GL_BLEND);
+	}
+	else
+	{
+	    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);
+	}
+    }
+}
+
+static void
+cubeUnSetBackgroundOpacity(CompScreen* s)
+{
+    CUBE_SCREEN(s);
+
+    if (cs->desktopOpacity != OPAQUE)
+    {
+	if (s->desktopWindowCount)
+	{
+	    glColor3usv(defaultColor);
+	    glDisable(GL_BLEND);
+	}
+	else
+	{
+	    glColor3usv(defaultColor);
+	    glDisable(GL_BLEND);
+	    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+	    screenTexEnvMode(s, GL_REPLACE);
+	}
+    }
+}
+
+static void
 cubePaintBackground (CompScreen   *s,
 		     Region	  region,
 		     unsigned int mask)
@@ -1728,6 +1895,8 @@ cubePaintBackground (CompScreen   *s,
     int n;
 
     CUBE_SCREEN (s);
+    
+    cubeSetBackgroundOpacity(s);
 
     n = cs->opt[CUBE_SCREEN_OPTION_BACKGROUNDS].value.list.nValue;
     if (n)
@@ -1745,6 +1914,7 @@ cubePaintBackground (CompScreen   *s,
 	if (s->desktopWindowCount)
 	{
 	    cubeUnloadBackgrounds (s);
+	    cubeUnSetBackgroundOpacity(s);
 	    return;
 	}
 	else
@@ -1757,8 +1927,11 @@ cubePaintBackground (CompScreen   *s,
 
 	data = malloc (sizeof (GLfloat) * nBox * 16);
 	if (!data)
+	{
+	    cubeUnSetBackgroundOpacity(s);
 	    return;
-
+	}
+	
 	d = data;
 	n = nBox;
 	while (n--)
@@ -1814,6 +1987,31 @@ 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 cubeSetClipPlanes (CompScreen *s, Region region, int output)
@@ -2325,6 +2523,8 @@ cubeInitScreen (CompPlugin *p,
     cs->disableCaps = FALSE;
     cs->paintAllViewports = FALSE;
     cs->rotationMode = NoRotation;
+    
+    cs->desktopOpacity = (CUBE_INACTIVE_OPACITY_DEFAULT / 100.0f) * OPAQUE;
 
     memset (cs->cleared, 0, sizeof (cs->cleared));
 
@@ -2340,6 +2540,7 @@ cubeInitScreen (CompPlugin *p,
     WRAP (cs, s, paintScreen, cubePaintScreen);
     WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
     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);
@@ -2376,6 +2577,7 @@ cubeFiniScreen (CompPlugin *p,
     UNWRAP (cs, s, paintScreen);
     UNWRAP (cs, s, paintTransformedScreen);
     UNWRAP (cs, s, paintBackground);
+    UNWRAP (cs, s, paintWindow);
     UNWRAP (cs, s, applyScreenTransform);
     UNWRAP (cs, s, setScreenOption);
     UNWRAP (cs, s, outputChangeNotify);
-- 
1.4.4.2



More information about the compiz mailing list