rendered paste bodydiff --git a/include/compiz.h b/include/compiz.h
index 027a0e3..8ed0668 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -26,7 +26,7 @@
#ifndef _COMPIZ_H
#define _COMPIZ_H
-#define ABIVERSION 20070403
+#define ABIVERSION 20070405
#include <stdio.h>
#include <sys/time.h>
@@ -1150,6 +1150,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,
@@ -1215,6 +1221,13 @@ typedef void (*ApplyScreenTransformProc) (CompScreen *screen,
*/
#define PAINT_WINDOW_BLEND_MASK (1 << 19)
+/*
+ flags that indicate the painting order which is used
+ in paintScreen when drawing the window.
+*/
+#define PAINT_WINDOW_BACK_TO_FRONT_MASK (1 << 20)
+#define PAINT_WINDOW_FRONT_TO_BACK_MASK (1 << 21)
+
typedef Bool (*PaintWindowProc) (CompWindow *window,
const WindowPaintAttrib *attrib,
@@ -1252,6 +1265,10 @@ typedef void (*PaintBackgroundProc) (CompScreen *screen,
Region region,
unsigned int mask);
+typedef void (*SetClipPlanesProc) (CompScreen *screen, Region region, int output);
+
+void setClipPlanes (CompScreen *screen, Region region, int output);
+
void
preparePaintScreen (CompScreen *screen,
int msSinceLastPaint);
@@ -1922,6 +1939,7 @@ struct _CompScreen {
GetOutputExtentsForWindowProc getOutputExtentsForWindow;
GetAllowedActionsForWindowProc getAllowedActionsForWindow;
FocusWindowProc focusWindow;
+ SetClipPlanesProc setClipPlanes;
PaintCursorProc paintCursor;
DamageCursorRectProc damageCursorRect;
diff --git a/plugins/cube.c b/plugins/cube.c
index 6784a45..999bc6d 100644
--- a/plugins/cube.c
+++ b/plugins/cube.c
@@ -52,6 +52,14 @@
#define CUBE_IN_DEFAULT FALSE
+typedef enum _RotationMode
+{
+ NoRotation = 0,
+ RotationChange,
+ RotationManual
+} RotationMode;
+
+
static char *cubeImages[] = {
"freedesktop"
};
@@ -85,6 +93,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
@@ -108,22 +131,28 @@ typedef struct _CubeDisplay {
int screenPrivateIndex;
CompOption opt[CUBE_DISPLAY_OPTION_NUM];
+
+ 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_NUM 13
+#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_NUM 17
typedef struct _CubeScreen {
PreparePaintScreenProc preparePaintScreen;
@@ -133,6 +162,9 @@ typedef struct _CubeScreen {
ApplyScreenTransformProc applyScreenTransform;
SetScreenOptionProc setScreenOption;
OutputChangeNotifyProc outputChangeNotify;
+ SetClipPlanesProc setClipPlanes;
+ PaintBackgroundProc paintBackground;
+ PaintWindowProc paintWindow;
CompOption opt[CUBE_SCREEN_OPTION_NUM];
@@ -173,11 +205,18 @@ typedef struct _CubeScreen {
Bool cleared[64];
Bool fullscreenOutput;
+ RotationMode rotationMode;
float outputXScale;
float outputYScale;
float outputXOffset;
float outputYOffset;
+
+ Bool disableCaps;
+ Bool paintAllViewports;
+
+ float desktopOpacity;
+ float toOpacity;
#ifdef USE_LIBRSVG
cairo_t *cr;
@@ -971,8 +1010,14 @@ cubeSetScreenOption (CompPlugin *plugin,
}
break;
case CUBE_SCREEN_OPTION_MIPMAP:
+ case CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY:
if (compSetBoolOption (o, value))
return TRUE;
+ 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;
}
@@ -1106,6 +1151,46 @@ cubeScreenInitOptions (CubeScreen *cs,
o->longDesc = N_("Generate mipmaps when possible for higher quality scaling");
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;
}
static int
@@ -1172,6 +1257,41 @@ 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.i / 100.0f) * OPAQUE;
+ }
+ else
+ cs->toOpacity =
+ (cs->opt[CUBE_SCREEN_OPTION_INACTIVE_OPACITY].value.i / 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);
+ }
+ }*/
+ cs->desktopOpacity = OPAQUE / 2;
+
UNWRAP (cs, s, preparePaintScreen);
(*s->preparePaintScreen) (s, msSinceLastPaint);
WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen);
@@ -1217,6 +1337,76 @@ cubeDonePaintScreen (CompScreen *s)
}
static void
+cubePaintBackground(CompScreen * s, Region region, unsigned int mask)
+{
+ 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);
+ }
+ }
+
+ UNWRAP (cs, s, paintBackground);
+ (*s->paintBackground) (s, region, mask);
+ WRAP (cs, s, paintBackground, cubePaintBackground);
+
+ 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 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)
+ {
+ if (cs->desktopOpacity == 0)
+ return TRUE;
+ 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
cubeMoveViewportAndPaint (CompScreen *s,
const ScreenPaintAttrib *sAttrib,
const CompTransform *transform,
@@ -1225,7 +1415,22 @@ cubeMoveViewportAndPaint (CompScreen *s,
int dx)
{
CUBE_SCREEN (s);
-
+
+ float angle = sAttrib->xRotate + sAttrib->yRotate;
+
+ // fix angle to be between -180 and 180
+ while (angle < -180.0f || angle > 180.0f)
+ {
+ if (angle < -180.0f)
+ angle += 360.0f;
+ else
+ angle -= 360.0f;
+ }
+
+ // Don't paint if the viewport isn't visible.
+ if ((angle > 90.0f || angle < -90.0f) && !cs->paintAllViewports && cs->desktopOpacity == OPAQUE)
+ return;
+
if (cs->nOutput > 1)
{
int cubeOutput, dView;
@@ -1277,12 +1482,20 @@ cubePaintTransformedScreen (CompScreen *s,
int hsize, xMove = 0;
float size;
Bool clear;
+ Bool wasCulled = FALSE;
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)
{
cs->outputXScale = (float) s->width / s->outputDev[output].width;
@@ -1386,21 +1599,16 @@ cubePaintTransformedScreen (CompScreen *s,
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;
- }
+ cs->xrotations = (int) (size * sa.xRotate + 180) / 360;
else
- {
- cs->xrotations = (int) (size * sa.xRotate) / 360;
- sa.xRotate = sa.xRotate -
- (360.0f * cs->xrotations) / size + 360.0f / size;
- cs->xrotations--;
- }
+ cs->xrotations = (int) (size * sa.xRotate - 180) / 360;
+
+ sa.xRotate -= (360.0f * cs->xrotations) / size;
}
- if (!clear && cs->grabIndex == 0 && hsize > 2 &&
+ if (!clear && cs->grabIndex == 0 && hsize > 2 && !cs->disableCaps &&
(cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f))
{
CompTransform sTransform = *transform;
@@ -1462,7 +1670,7 @@ cubePaintTransformedScreen (CompScreen *s,
/* outside cube */
if (cs->invert == 1)
{
- if (cs->grabIndex || hsize > 4)
+ if (cs->grabIndex)
{
GLenum filter;
int i;
@@ -1487,19 +1695,52 @@ cubePaintTransformedScreen (CompScreen *s,
}
else
{
- if (sAttrib->xRotate != 0.0f)
+ int i;
+
+ // xrotations ==> dx for the viewport which is the nearest to the viewer in z axis.
+ // xrotations +/- hsize / 2 ==> dx for the viewport which is the farest to the viewer in z axis.
+
+ if (sa.xRotate < 0.0f)
{
- xMove = cs->xrotations;
-
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
- xMove);
-
- xMove++;
+ for (i = 0; i <= hsize / 2; i++)
+ {
+ xMove = cs->xrotations + hsize / 2 + i;
+ sa.yRotate -= (hsize / 2 + i) * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ xMove);
+ sa.yRotate += (hsize / 2 + i) * 360.0f / size;
+
+ if (i == 0 || i * 2 == hsize) // same viewport.
+ continue;
+
+ xMove = cs->xrotations + hsize / 2 - i;
+ sa.yRotate -= (hsize / 2 - i) * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ xMove);
+ sa.yRotate += (hsize / 2 - i) * 360.0f / size;
+ }
+ }
+
+ else
+ {
+ for (i = 0; i <= hsize / 2; i++)
+ {
+ xMove = cs->xrotations - hsize / 2 - i;
+ sa.yRotate -= (-hsize / 2 - i) * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ xMove);
+ sa.yRotate += (-hsize / 2 - i) * 360.0f / size;
+
+ if (i == 0 || i * 2 == hsize) // same viewport.
+ continue;
+
+ xMove = cs->xrotations - hsize / 2 + i;
+ sa.yRotate -= (-hsize / 2 + i) * 360.0f / size;
+ cubeMoveViewportAndPaint (s, &sa, transform, output, mask,
+ xMove);
+ sa.yRotate += (-hsize / 2 + i) * 360.0f / size;
+ }
}
-
- sa.yRotate -= 360.0f / size;
-
- cubeMoveViewportAndPaint (s, &sa, transform, output, mask, xMove);
}
}
else
@@ -1561,6 +1802,45 @@ cubePaintTransformedScreen (CompScreen *s,
}
WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen);
+
+ if (cs->desktopOpacity != OPAQUE && wasCulled)
+ glEnable(GL_CULL_FACE);
+}
+
+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
@@ -1583,6 +1863,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, "cube") == 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,
@@ -1611,6 +1970,7 @@ cubeUnfold (CompDisplay *d,
if (cs->grabIndex)
{
+ cubeFoldEvent (s, TRUE);
cs->unfolded = TRUE;
damageScreen (s);
}
@@ -1646,6 +2006,7 @@ cubeFold (CompDisplay *d,
if (cs->grabIndex)
{
+ cubeFoldEvent (s, FALSE);
cs->unfolded = FALSE;
damageScreen (s);
}
@@ -1869,6 +2230,8 @@ cubeInitDisplay (CompPlugin *p,
cubeDisplayInitOptions (cd, d->display);
d->privates[displayPrivateIndex].ptr = cd;
+
+ WRAP (cd, d, handleCompizEvent, cubeHandleCompizEvent);
return TRUE;
}
@@ -1883,6 +2246,7 @@ cubeFiniDisplay (CompPlugin *p,
#endif
CUBE_DISPLAY (d);
+ UNWRAP (cd, d, handleCompizEvent);
freeScreenPrivateIndex (d, cd->screenPrivateIndex);
@@ -1941,6 +2305,12 @@ cubeInitScreen (CompPlugin *p,
cs->unfoldVelocity = 0.0f;
cs->fullscreenOutput = TRUE;
+
+ cs->disableCaps = FALSE;
+ cs->paintAllViewports = FALSE;
+ cs->rotationMode = NoRotation;
+
+ cs->desktopOpacity = CUBE_ACTIVE_OPACITY_DEFAULT;
memset (cs->cleared, 0, sizeof (cs->cleared));
@@ -1958,6 +2328,9 @@ 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, paintBackground, cubePaintBackground);
+ WRAP (cs, s, paintWindow, cubePaintWindow);
cubeUpdateOutputs (s);
@@ -1992,6 +2365,9 @@ cubeFiniScreen (CompPlugin *p,
UNWRAP (cs, s, applyScreenTransform);
UNWRAP (cs, s, setScreenOption);
UNWRAP (cs, s, outputChangeNotify);
+ UNWRAP (cs, s, setClipPlanes);
+ UNWRAP (cs, s, paintBackground);
+ UNWRAP (cs, s, paintWindow);
finiTexture (s, &cs->texture);
finiTexture (s, &cs->sky);
@@ -2067,3 +2443,4 @@ getCompPluginInfo (void)
{
return &cubeVTable;
}
+
diff --git a/plugins/rotate.c b/plugins/rotate.c
index c19030b..b74c40c 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)
@@ -485,6 +509,8 @@ rotatePreparePaintScreen (CompScreen *s,
else
tx = (s->hsize * xrot / 360.0f) + 0.5f;
+ rotateEvent (s, FALSE, FALSE);
+
moveScreenViewport (s, tx, 0, TRUE);
rs->xrot = 0.0f;
@@ -638,6 +664,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)
{
rs->grabIndex = pushScreenGrab (s, s->invisibleCursor, "rotate");
diff --git a/src/paint.c b/src/paint.c
index a618328..9c0e252 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -157,7 +157,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)
{
@@ -179,10 +181,29 @@ paintScreenRegion (CompScreen *screen,
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;
@@ -197,7 +218,7 @@ paintScreenRegion (CompScreen *screen,
XSubtractRegion (tmpRegion, &emptyRegion, w->clip);
if ((*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
- PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
+ occlusionMask))
{
/* unredirect top most fullscreen windows. */
if (count == 0 &&
@@ -216,8 +237,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;
@@ -231,9 +257,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);
+ }
}
@@ -259,29 +298,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);
@@ -1154,3 +1174,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 63d7189..482f0da 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1688,6 +1688,7 @@ addScreen (CompDisplay *display,
s->getOutputExtentsForWindow = getOutputExtentsForWindow;
s->getAllowedActionsForWindow = getAllowedActionsForWindow;
s->focusWindow = focusWindow;
+ s->setClipPlanes = setClipPlanes;
s->paintCursor = paintCursor;
s->damageCursorRect = damageCursorRect;