rendered paste bodydiff --git a/include/compiz.h b/include/compiz.h
index 5e52c8c..03d6005 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -26,7 +26,7 @@
#ifndef _COMPIZ_H
#define _COMPIZ_H
-#define ABIVERSION 20070506
+#define ABIVERSION 20070507
#include <stdio.h>
#include <sys/time.h>
@@ -1193,6 +1193,11 @@ typedef void (*ApplyScreenTransformProc) (CompScreen *screen,
int output,
CompTransform *transform);
+typedef CompWindow* (*StackFirstProc) (CompScreen *screen);
+typedef CompWindow* (*StackLastProc) (CompScreen *screen);
+
+typedef CompWindow* (*StackNextProc) (CompWindow *window);
+typedef CompWindow* (*StackPrevProc) (CompWindow *window);
/*
window paint flags
@@ -1274,6 +1279,10 @@ 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);
@@ -1308,6 +1317,18 @@ applyScreenTransform (CompScreen *screen,
int output,
CompTransform *transform);
+CompWindow*
+stackFirst (CompScreen* screen);
+
+CompWindow*
+stackLast (CompScreen* screen);
+
+CompWindow*
+stackNext (CompWindow* window);
+
+CompWindow*
+stackPrev (CompWindow* window);
+
Bool
paintScreen (CompScreen *screen,
const ScreenPaintAttrib *sAttrib,
@@ -1362,6 +1383,10 @@ paintBackground (CompScreen *screen,
Region region,
unsigned int mask);
+void setClipPlanes (CompScreen *screen,
+ Region region,
+ int output);
+
/* texture.c */
@@ -1941,6 +1966,7 @@ struct _CompScreen {
PaintTransformedScreenProc paintTransformedScreen;
ApplyScreenTransformProc applyScreenTransform;
PaintBackgroundProc paintBackground;
+ SetClipPlanesProc setClipPlanes;
PaintWindowProc paintWindow;
DrawWindowProc drawWindow;
AddWindowGeometryProc addWindowGeometry;
@@ -1965,6 +1991,12 @@ struct _CompScreen {
WindowStateChangeNotifyProc windowStateChangeNotify;
OutputChangeNotifyProc outputChangeNotify;
+
+ StackFirstProc stackFirst;
+ StackLastProc stackLast;
+
+ StackNextProc stackNext;
+ StackPrevProc stackPrev;
CompPrivate *privates;
};
diff --git a/plugins/cube.c b/plugins/cube.c
index 833d33e..356955f 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -46,6 +46,13 @@
#include <compiz.h>
+typedef enum _RotationMode
+{
+ NoRotation = 0,
+ RotationChange,
+ RotationManual
+} RotationMode;
+
static CompMetadata cubeMetadata;
#define CUBE_DISPLAY_OPTION_UNFOLD 0
@@ -59,6 +66,8 @@ typedef struct _CubeDisplay {
int screenPrivateIndex;
CompOption opt[CUBE_DISPLAY_OPTION_NUM];
+
+ HandleCompizEventProc handleCompizEvent;
} CubeDisplay;
#define CUBE_SCREEN_OPTION_COLOR 0
@@ -78,6 +87,43 @@ typedef struct _CubeDisplay {
#define CUBE_SCREEN_OPTION_ADJUST_IMAGE 14
#define CUBE_SCREEN_OPTION_NUM 15
+#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 enum _PaintOrder
+{
+ BTF = 0,
+ FTB
+} PaintOrder;
+
typedef struct _CubeScreen {
PreparePaintScreenProc preparePaintScreen;
DonePaintScreenProc donePaintScreen;
@@ -87,15 +133,20 @@ typedef struct _CubeScreen {
ApplyScreenTransformProc applyScreenTransform;
SetScreenOptionProc setScreenOption;
OutputChangeNotifyProc outputChangeNotify;
+ SetClipPlanesProc setClipPlanes;
+ StackFirstProc stackFirst;
+ StackLastProc stackLast;
+ StackNextProc stackNext;
+ StackPrevProc stackPrev;
CompOption opt[CUBE_SCREEN_OPTION_NUM];
- int invert;
- int xrotations;
- GLfloat distance;
- Bool paintTopBottom;
- GLushort color[3];
- GLfloat tc[12];
+ int invert;
+ int xrotations;
+ PaintOrder paintOrder;
+ GLfloat distance;
+ GLushort color[3];
+ GLfloat tc[12];
int grabIndex;
@@ -120,11 +171,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;
@@ -1061,6 +1116,8 @@ cubePaintScreen (CompScreen *s,
mask |= PAINT_SCREEN_TRANSFORMED_MASK;
}
+ cs->paintOrder = BTF; // Always use BTF painting on non-transformed screen.
+
UNWRAP (cs, s, paintScreen);
status = (*s->paintScreen) (s, sAttrib, transform, region, output, mask);
WRAP (cs, s, paintScreen, cubePaintScreen);
@@ -1081,16 +1138,78 @@ 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,
const CompTransform *transform,
int output,
unsigned int mask,
+ PaintOrder paintOrder,
int dx)
{
CUBE_SCREEN (s);
+
+ Bool ftb = cubeCheckFTB(s, sAttrib, transform, output);
+ if ((paintOrder == FTB && !ftb) ||
+ (paintOrder == BTF && ftb))
+ return;
+
+ cs->paintOrder = paintOrder;
+
if (cs->nOutput > 1)
{
int cubeOutput, dView;
@@ -1131,49 +1250,83 @@ cubeMoveViewportAndPaint (CompScreen *s,
}
static void
-cubePaintTransformedScreen (CompScreen *s,
- const ScreenPaintAttrib *sAttrib,
- const CompTransform *transform,
- Region region,
- int output,
- unsigned int mask)
+cubePaintAllViewports (CompScreen *s,
+ ScreenPaintAttrib *sAttrib,
+ const CompTransform *transform,
+ Region region,
+ int output,
+ unsigned int mask,
+ int xMove,
+ int size,
+ int hsize,
+ PaintOrder paintOrder)
{
- ScreenPaintAttrib sa = *sAttrib;
- int hsize, xMove = 0;
- float size;
- Bool clear;
-
- CUBE_SCREEN (s);
+ CUBE_SCREEN(s);
- hsize = s->hsize * cs->nOutput;
- size = hsize;
+ ScreenPaintAttrib sa = *sAttrib;
- if (!cs->fullscreenOutput)
+ int i;
+ int iFirstSign; // 1 if we do xMove += i first and -1 if we do xMove -= i first.
+
+ if (cs->invert == 1)
{
- cs->outputXScale = (float) s->width / s->outputDev[output].width;
- cs->outputYScale = (float) s->height / s->outputDev[output].height;
-
- cs->outputXOffset =
- (s->width / 2.0f -
- (s->outputDev[output].region.extents.x1 +
- s->outputDev[output].region.extents.x2) / 2.0f) /
- (float) s->outputDev[output].width;
-
- cs->outputYOffset =
- (s->height / 2.0f -
- (s->outputDev[output].region.extents.y1 +
- s->outputDev[output].region.extents.y2) / 2.0f) /
- (float) s->outputDev[output].height;
+ // 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
{
- cs->outputXScale = 1.0f;
- cs->outputYScale = 1.0f;
- cs->outputXOffset = 0.0f;
- cs->outputYOffset = 0.0f;
+ // 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,
+ paintOrder, xMove);
+ sa.yRotate += cs->invert * iFirstSign * i * 360.0f / size;
+ xMove -= iFirstSign * i;
+
+ if (i == 0 || i * 2 == hsize) // same viewport.
+ continue;
- clear = cs->cleared[output];
+ xMove -= iFirstSign * i;
+ sa.yRotate += cs->invert * iFirstSign * i * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ paintOrder, xMove);
+ sa.yRotate -= cs->invert * iFirstSign * i * 360.0f / size;
+ xMove += iFirstSign * i;
+ }
+}
+
+static void
+cubePaintSkydome (CompScreen *s,
+ ScreenPaintAttrib *sAttrib,
+ Bool clear)
+{
+ CUBE_SCREEN(s);
+
if (!clear)
{
if (cs->sky.name)
@@ -1200,77 +1353,25 @@ cubePaintTransformedScreen (CompScreen *s,
{
clearTargetOutput (s->display, GL_COLOR_BUFFER_BIT);
}
-
- cs->cleared[output] = TRUE;
}
+}
- mask &= ~PAINT_SCREEN_CLEAR_MASK;
-
- UNWRAP (cs, s, paintTransformedScreen);
-
- sa.xTranslate = sAttrib->xTranslate;
- sa.yTranslate = sAttrib->yTranslate;
-
- if (cs->grabIndex)
- {
- sa.vRotate = 0.0f;
-
- size += cs->unfold * 8.0f;
- size += powf (cs->unfold, 6) * 64.0;
- size += powf (cs->unfold, 16) * 8192.0;
-
- sa.zTranslate = -cs->invert * (0.5f / tanf (M_PI / size));
-
- /* 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
- {
- if (sAttrib->vRotate > 100.0f)
- sa.vRotate = 100.0f;
- else if (sAttrib->vRotate < -100.0f)
- sa.vRotate = -100.0f;
- else
- 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--;
- }
- }
+static void
+cubePaintCaps (CompScreen *s,
+ ScreenPaintAttrib *sAttrib,
+ const CompTransform *transform,
+ Bool clear,
+ int output,
+ int hsize,
+ int size)
+{
+ CUBE_SCREEN(s);
if (!clear && cs->grabIndex == 0 && hsize > 2 &&
- (cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f))
+ (cs->invert != 1 || sAttrib->vRotate != 0.0f || sAttrib->yTranslate != 0.0f))
{
CompTransform sTransform = *transform;
- float yRotate = (360.0f / size) * (cs->xrotations + 1);
+ float yRotate = 0.0f;
screenLighting (s, TRUE);
@@ -1279,155 +1380,242 @@ cubePaintTransformedScreen (CompScreen *s,
glPushMatrix ();
if (cs->opt[CUBE_SCREEN_OPTION_ADJUST_IMAGE].value.b)
- {
- if (sAttrib->xRotate > 0.0f)
- yRotate = 360.0f / size;
- else
- yRotate = 0.0f;
- }
+ yRotate = 360.0f / size;
- sa.yRotate += yRotate;
+ sAttrib->yRotate += yRotate;
- (*s->applyScreenTransform) (s, &sa, output, &sTransform);
+ (*s->applyScreenTransform) (s, sAttrib, output, &sTransform);
glLoadMatrixf (sTransform.m);
glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
- sa.yRotate -= yRotate;
+ sAttrib->yRotate -= yRotate;
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
+
+ int i;
+ for (i = 0; i < 2; i++)
{
- glDisableClientState (GL_TEXTURE_COORD_ARRAY);
- glDrawArrays (GL_TRIANGLE_FAN, 0, cs->nvertices >> 1);
+ if ((i == 0 && sAttrib->vRotate < 0.0f) ||
+ (i == 1 && sAttrib->vRotate > 0.0f))
+ {
+ 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
+ {
+ glNormal3f (0.0f, 1.0f, 0.0f);
+ glDrawArrays (GL_TRIANGLE_FAN, cs->nvertices >> 1,
+ 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;
+static void
+cubePaintTransformedScreen (CompScreen *s,
+ const ScreenPaintAttrib *sAttrib,
+ const CompTransform *transform,
+ Region region,
+ int output,
+ unsigned int mask)
+{
+ ScreenPaintAttrib sa = *sAttrib;
+ int hsize, xMove = 0;
+ float size;
+ GLenum filter = s->display->textureFilter;
+ PaintOrder paintOrder;
+ Bool clear;
+
+ CUBE_SCREEN (s);
+
+ clear = cs->cleared[output];
+ cs->cleared[output] = TRUE;
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
- xMove);
+ hsize = s->hsize * cs->nOutput;
+ size = hsize;
- xMove++;
- }
+ if (!cs->fullscreenOutput)
+ {
+ cs->outputXScale = (float) s->width / s->outputDev[output].width;
+ cs->outputYScale = (float) s->height / s->outputDev[output].height;
- sa.yRotate -= 360.0f / size;
+ cs->outputXOffset =
+ (s->width / 2.0f -
+ (s->outputDev[output].region.extents.x1 +
+ s->outputDev[output].region.extents.x2) / 2.0f) /
+ (float) s->outputDev[output].width;
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
- }
+ cs->outputYOffset =
+ (s->height / 2.0f -
+ (s->outputDev[output].region.extents.y1 +
+ s->outputDev[output].region.extents.y2) / 2.0f) /
+ (float) s->outputDev[output].height;
}
else
{
- if (sa.xRotate > 180.0f / size)
- {
- sa.yRotate -= 360.0f / size;
- cs->xrotations++;
- }
+ cs->outputXScale = 1.0f;
+ cs->outputYScale = 1.0f;
+ cs->outputXOffset = 0.0f;
+ cs->outputYOffset = 0.0f;
+ }
- sa.yRotate -= 360.0f / size;
- xMove = -1 - cs->xrotations;
+ cubePaintSkydome (s, &sa, clear); // Paint skydome first.
- if (cs->grabIndex)
- {
- GLenum filter;
- int i;
+ mask &= ~PAINT_SCREEN_CLEAR_MASK;
- filter = s->display->textureFilter;
- if (cs->opt[CUBE_SCREEN_OPTION_MIPMAP].value.b)
- s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
+ UNWRAP (cs, s, paintTransformedScreen);
- 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);
- }
+ sa.xTranslate = sAttrib->xTranslate;
+ sa.yTranslate = sAttrib->yTranslate;
- for (i = 0; i < hsize; i++)
- {
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
- xMove);
+ if (cs->grabIndex)
+ {
+ sa.vRotate = 0.0f;
- sa.yRotate += 360.0f / size;
- xMove++;
- }
+ size += cs->unfold * 8.0f;
+ size += powf (cs->unfold, 6) * 64.0;
+ size += powf (cs->unfold, 16) * 8192.0;
- s->display->textureFilter = filter;
- }
+ sa.zTranslate = -cs->invert * (0.5f / tanf (M_PI / size));
+
+ /* 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;
+ }
+ else
+ {
+ if (sAttrib->vRotate > 100.0f)
+ sa.vRotate = 100.0f;
+ else if (sAttrib->vRotate < -100.0f)
+ sa.vRotate = -100.0f;
else
- {
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
+ sa.vRotate = sAttrib->vRotate;
- sa.yRotate += 360.0f / size;
- xMove = -cs->xrotations;
+ sa.zTranslate = -cs->invert * cs->distance;
+ }
+
+ sa.xRotate = sAttrib->xRotate;
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
+ 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)
+ paintOrder = FTB; // Outside cube - start with FTB faces.
+ else
+ paintOrder = BTF; // Inside cube - start with BTF faces.
+
+ if (cs->paintAllViewports || cs->invert == -1)
+ cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize, paintOrder);
+
+ cubePaintCaps (s, &sa, transform, clear, output, hsize, size); // Paint caps between BTF faces and FTB faces.
+
+ if (cs->invert == 1)
+ paintOrder = BTF; // Outside cube - continue with BTF faces.
+ else
+ paintOrder = FTB; // Inside cube - continue with FTB faces.
+
+ if (cs->paintAllViewports || cs->invert == 1)
+ cubePaintAllViewports(s, &sa, transform, region, output, mask, xMove, size, hsize, paintOrder);
+
+ s->display->textureFilter = filter;
- sa.yRotate += 360.0f / size;
- xMove = 1 - cs->xrotations;
+ WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
+}
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
- }
- }
+static CompWindow*
+cubeStackFirst (CompScreen* screen)
+{
+ CompWindow* status;
+ CUBE_SCREEN (screen);
+
+ if (cs->paintOrder == FTB)
+ return screen->reverseWindows;
+
+ UNWRAP (cs, screen, stackFirst);
+ status = (*screen->stackFirst) (screen);
+ WRAP (cs, screen, stackFirst, cubeStackFirst);
+
+ return status;
+}
- WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
+static CompWindow*
+cubeStackLast (CompScreen* screen)
+{
+ CompWindow* status;
+ CUBE_SCREEN (screen);
+
+ if (cs->paintOrder == FTB)
+ return screen->windows;
+
+ UNWRAP (cs, screen, stackLast);
+ status = (*screen->stackLast) (screen);
+ WRAP (cs, screen, stackLast, cubeStackLast);
+
+ return status;
+}
+
+static CompWindow*
+cubeStackNext (CompWindow* window)
+{
+ CompWindow* status;
+ CompScreen *screen = window->screen;
+ CUBE_SCREEN (screen);
+
+ if (cs->paintOrder == FTB)
+ return window->prev;
+
+ UNWRAP (cs, screen, stackNext);
+ status = (*screen->stackNext) (window);
+ WRAP (cs, screen, stackNext, cubeStackNext);
+
+ return status;
+}
+
+static CompWindow*
+cubeStackPrev (CompWindow* window)
+{
+ CompWindow *status;
+ CompScreen *screen = window->screen;
+ CUBE_SCREEN (screen);
+
+ if (cs->paintOrder == FTB)
+ return window->next;
+
+ UNWRAP (cs, screen, stackPrev);
+ status = (*screen->stackPrev) (window);
+ WRAP (cs, screen, stackPrev, cubeStackPrev);
+
+ return status;
}
static void
@@ -1526,6 +1714,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,
@@ -1546,6 +1769,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,
@@ -1575,6 +1877,7 @@ cubeUnfold (CompDisplay *d,
if (cs->grabIndex)
{
cs->unfolded = TRUE;
+ cubeFoldEvent (s, TRUE);
damageScreen (s);
}
@@ -1610,6 +1913,7 @@ cubeFold (CompDisplay *d,
if (cs->grabIndex)
{
cs->unfolded = FALSE;
+ cubeFoldEvent (s, FALSE);
damageScreen (s);
}
}
@@ -1783,6 +2087,8 @@ cubeInitDisplay (CompPlugin *p,
}
d->privates[displayPrivateIndex].ptr = cd;
+
+ WRAP (cd, d, handleCompizEvent, cubeHandleCompizEvent);
return TRUE;
}
@@ -1794,6 +2100,8 @@ cubeFiniDisplay (CompPlugin *p,
CUBE_DISPLAY (d);
freeScreenPrivateIndex (d, cd->screenPrivateIndex);
+
+ UNWRAP (cd, d, handleCompizEvent);
compFiniDisplayOptions (d, cd->opt, CUBE_DISPLAY_OPTION_NUM);
@@ -1857,8 +2165,6 @@ cubeInitScreen (CompPlugin *p,
s->privates[cd->screenPrivateIndex].ptr = cs;
- cs->paintTopBottom = FALSE;
-
initTexture (s, &cs->texture);
initTexture (s, &cs->sky);
@@ -1875,6 +2181,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));
@@ -1901,6 +2211,11 @@ cubeInitScreen (CompPlugin *p,
WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform);
WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption);
WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify);
+ WRAP (cs, s, setClipPlanes, cubeSetClipPlanes);
+ WRAP (cs, s, stackFirst, cubeStackFirst);
+ WRAP (cs, s, stackLast, cubeStackLast);
+ WRAP (cs, s, stackNext, cubeStackNext);
+ WRAP (cs, s, stackPrev, cubeStackPrev);
return TRUE;
}
@@ -1922,6 +2237,11 @@ cubeFiniScreen (CompPlugin *p,
UNWRAP (cs, s, applyScreenTransform);
UNWRAP (cs, s, setScreenOption);
UNWRAP (cs, s, outputChangeNotify);
+ UNWRAP (cs, s, setClipPlanes);
+ UNWRAP (cs, s, stackFirst);
+ UNWRAP (cs, s, stackLast);
+ UNWRAP (cs, s, stackNext);
+ UNWRAP (cs, s, stackPrev);
finiTexture (s, &cs->texture);
finiTexture (s, &cs->sky);
diff --git a/plugins/rotate.c b/plugins/rotate.c
index eb337ca..c257790 100644
--- a/plugins/rotate.c
+++ b/plugins/rotate.c
@@ -251,6 +251,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)
@@ -337,6 +361,8 @@ 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);
@@ -491,6 +517,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)
{
diff --git a/src/paint.c b/src/paint.c
index 39bcacc..a4679e0 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -185,7 +185,7 @@ paintScreenRegion (CompScreen *screen,
XSubtractRegion (region, &emptyRegion, tmpRegion);
/* detect occlusions */
- for (w = screen->reverseWindows; w; w = w->prev)
+ for (w = (*screen->stackLast) (screen); w; w = (*screen->stackPrev) (w))
{
if (w->destroyed)
continue;
@@ -221,7 +221,7 @@ paintScreenRegion (CompScreen *screen,
(*screen->paintBackground) (screen, tmpRegion, backgroundMask);
/* paint all windows from bottom to top */
- for (w = screen->windows; w; w = w->next)
+ for (w = (*screen->stackFirst) (screen); w; w = (*screen->stackNext) (w))
{
if (w->destroyed)
continue;
@@ -266,29 +266,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);
@@ -378,6 +359,30 @@ paintScreen (CompScreen *screen,
return TRUE;
}
+CompWindow*
+stackFirst (CompScreen* screen)
+{
+ return screen->windows;
+}
+
+CompWindow*
+stackLast (CompScreen* screen)
+{
+ return screen->reverseWindows;
+}
+
+CompWindow*
+stackNext (CompWindow* window)
+{
+ return window->next;
+}
+
+CompWindow*
+stackPrev (CompWindow* window)
+{
+ return window->prev;
+}
+
#define ADD_RECT(data, m, n, x1, y1, x2, y2) \
for (it = 0; it < n; it++) \
{ \
@@ -1161,3 +1166,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 d73ceb4..0155bad 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1516,6 +1516,7 @@ addScreen (CompDisplay *display,
s->paintTransformedScreen = paintTransformedScreen;
s->applyScreenTransform = applyScreenTransform;
s->paintBackground = paintBackground;
+ s->setClipPlanes = setClipPlanes;
s->paintWindow = paintWindow;
s->drawWindow = drawWindow;
s->addWindowGeometry = addWindowGeometry;
@@ -1540,6 +1541,12 @@ addScreen (CompDisplay *display,
s->windowStateChangeNotify = windowStateChangeNotify;
s->outputChangeNotify = outputChangeNotify;
+
+ s->stackFirst = stackFirst;
+ s->stackLast = stackLast;
+
+ s->stackNext = stackNext;
+ s->stackPrev = stackPrev;
s->getProcAddress = 0;