From 969ff01695db71f7d2030cf61b2aa1d47a83301a Mon Sep 17 00:00:00 2001 From: Roi Cohen Date: Tue, 5 Jun 2007 15:32:02 +0300 Subject: [PATCH] transparent cube --- include/cube.h | 42 ++++++++------ metadata/cube.xml.in | 29 +++++++++ plugins/cube.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 202 insertions(+), 25 deletions(-) diff --git a/include/cube.h b/include/cube.h index 0dcb14b..520cf3d 100644 --- a/include/cube.h +++ b/include/cube.h @@ -25,7 +25,7 @@ #include -#define CUBE_ABIVERSION 20070605 +#define CUBE_ABIVERSION 20070606 #define CUBE_DISPLAY_OPTION_ABI 0 #define CUBE_DISPLAY_OPTION_INDEX 1 @@ -42,22 +42,26 @@ 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_ADJUST_IMAGE 14 -#define CUBE_SCREEN_OPTION_NUM 15 +#define CUBE_SCREEN_OPTION_COLOR 0 +#define CUBE_SCREEN_OPTION_IN 1 +#define CUBE_SCREEN_OPTION_SCALE_IMAGE 2 +#define CUBE_SCREEN_OPTION_IMAGES 3 +#define CUBE_SCREEN_OPTION_SKYDOME 4 +#define CUBE_SCREEN_OPTION_SKYDOME_IMG 5 +#define CUBE_SCREEN_OPTION_SKYDOME_ANIM 6 +#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START 7 +#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END 8 +#define CUBE_SCREEN_OPTION_ACCELERATION 9 +#define CUBE_SCREEN_OPTION_SPEED 10 +#define CUBE_SCREEN_OPTION_TIMESTEP 11 +#define CUBE_SCREEN_OPTION_MIPMAP 12 +#define CUBE_SCREEN_OPTION_BACKGROUNDS 13 +#define CUBE_SCREEN_OPTION_ADJUST_IMAGE 14 +#define CUBE_SCREEN_OPTION_ACTIVE_OPACITY 15 +#define CUBE_SCREEN_OPTION_INACTIVE_OPACITY 16 +#define CUBE_SCREEN_OPTION_FADE_TIME 17 +#define CUBE_SCREEN_OPTION_TRANSPARENT_MANUAL_ONLY 18 +#define CUBE_SCREEN_OPTION_NUM 19 typedef void (*CubeGetRotationProc) (CompScreen *s, float *x, @@ -92,6 +96,7 @@ typedef struct _CubeScreen { PaintOutputProc paintOutput; PaintTransformedOutputProc paintTransformedOutput; PaintBackgroundProc paintBackground; + PaintWindowProc paintWindow; ApplyScreenTransformProc applyScreenTransform; SetScreenOptionProc setScreenOption; OutputChangeNotifyProc outputChangeNotify; @@ -144,6 +149,9 @@ typedef struct _CubeScreen { Bool disableCaps; Bool paintAllViewports; + float desktopOpacity; + float toOpacity; + CompTexture *bg; int nBg; } CubeScreen; diff --git a/metadata/cube.xml.in b/metadata/cube.xml.in index 0f674e7..7405531 100644 --- a/metadata/cube.xml.in +++ b/metadata/cube.xml.in @@ -134,6 +134,35 @@ <_long>Adjust top face image to rotation false + + + + diff --git a/plugins/cube.c b/plugins/cube.c index 43c6578..1963b66 100644 --- a/plugins/cube.c +++ b/plugins/cube.c @@ -818,10 +818,42 @@ 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); WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen); - } static Bool @@ -836,7 +868,7 @@ cubePaintOutput (CompScreen *s, CUBE_SCREEN (s); - if (cs->grabIndex) + if (cs->grabIndex || cs->desktopOpacity != OPAQUE) { mask &= ~PAINT_SCREEN_REGION_MASK; mask |= PAINT_SCREEN_TRANSFORMED_MASK; @@ -857,7 +889,7 @@ cubeDonePaintScreen (CompScreen *s) { CUBE_SCREEN (s); - if (cs->grabIndex) + if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity) damageScreen (s); UNWRAP (cs, s, donePaintScreen); @@ -1131,7 +1163,7 @@ cubePaintTopBottom (CompScreen *s, screenLighting (s, TRUE); - glColor3usv (cs->color); + glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity); glPushMatrix (); @@ -1145,6 +1177,13 @@ cubePaintTopBottom (CompScreen *s, glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f); glScalef (cs->outputXScale, cs->outputYScale, 1.0f); + 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); int i; @@ -1182,6 +1221,10 @@ cubePaintTopBottom (CompScreen *s, glColor4usv (defaultColor); glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + screenTexEnvMode(s, GL_REPLACE); + glDisable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } static void @@ -1199,6 +1242,7 @@ cubePaintTransformedOutput (CompScreen *s, GLenum filter = s->display->textureFilter; PaintOrder paintOrder; Bool clear; + Bool wasCulled = FALSE; int output = 0; CUBE_SCREEN (s); @@ -1208,6 +1252,13 @@ cubePaintTransformedOutput (CompScreen *s, hsize = s->hsize * cs->nOutput; size = hsize; + if (cs->desktopOpacity != OPAQUE) + { + wasCulled = glIsEnabled(GL_CULL_FACE); + if (wasCulled) + glDisable(GL_CULL_FACE); + } + if (!cs->fullscreenOutput) { cs->outputXScale = (float) s->width / s->outputDev[output].width; @@ -1295,11 +1346,11 @@ cubePaintTransformedOutput (CompScreen *s, else paintOrder = BTF; // Inside cube - start with BTF faces. - if (cs->invert == -1 || cs->paintAllViewports) + if (cs->invert == -1 || cs->paintAllViewports || cs->desktopOpacity != OPAQUE) cubePaintAllViewports(s, &sa, transform, region, outputPtr, mask, xMove, size, hsize, paintOrder); if (!clear && cs->grabIndex == 0 && hsize > 2 && !cs->disableCaps && - (cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f)) + (cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f || cs->desktopOpacity != OPAQUE)) { (*cs->paintTopBottom) (s, &sa, transform, outputPtr, hsize); } @@ -1309,15 +1360,62 @@ cubePaintTransformedOutput (CompScreen *s, else paintOrder = FTB; // Inside cube - continue with FTB faces. - if (cs->invert == 1 || cs->paintAllViewports) + if (cs->invert == 1 || cs->paintAllViewports || cs->desktopOpacity != OPAQUE) cubePaintAllViewports(s, &sa, transform, region, outputPtr, mask, xMove, size, hsize, paintOrder); s->display->textureFilter = filter; + if (cs->desktopOpacity != OPAQUE && wasCulled) + glEnable(GL_CULL_FACE); + WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput); } 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) @@ -1326,6 +1424,8 @@ cubePaintBackground (CompScreen *s, CUBE_SCREEN (s); + cubeSetBackgroundOpacity(s); + n = cs->opt[CUBE_SCREEN_OPTION_BACKGROUNDS].value.list.nValue; if (n) { @@ -1336,13 +1436,17 @@ cubePaintBackground (CompScreen *s, GLfloat *d, *data; if (!nBox) + { + cubeUnSetBackgroundOpacity(s); return; + } n = (s->x * cs->nOutput + cs->srcOutput) % n; if (s->desktopWindowCount) { cubeUnloadBackgrounds (s); + cubeUnSetBackgroundOpacity(s); return; } else @@ -1358,7 +1462,10 @@ cubePaintBackground (CompScreen *s, data = malloc (sizeof (GLfloat) * nBox * 16); if (!data) + { + cubeUnSetBackgroundOpacity(s); return; + } d = data; n = nBox; @@ -1415,6 +1522,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 @@ -1826,7 +1958,11 @@ static const CompMetadataOptionInfo cubeScreenOptionInfo[] = { { "timestep", "float", "0.1", 0, 0 }, { "mipmap", "bool", 0, 0, 0 }, { "backgrounds", "list", "string", 0, 0 }, - { "adjust_image", "bool", 0, 0, 0 } + { "adjust_image", "bool", 0, 0, 0 }, + { "active_opacity", "float", "0.0100.0", 0, 0 }, + { "inactive_opacity", "float", "0.0100.0", 0, 0 }, + { "fade_time", "float", "0.0", 0, 0 }, + { "transparent_manual_only", "bool", 0, 0, 0 } }; static Bool @@ -1896,6 +2032,8 @@ cubeInitScreen (CompPlugin *p, cs->paintAllViewports = FALSE; cs->rotationMode = NoRotation; + cs->desktopOpacity = OPAQUE; + memset (cs->cleared, 0, sizeof (cs->cleared)); cubeUpdateOutputs (s); @@ -1918,6 +2056,7 @@ cubeInitScreen (CompPlugin *p, WRAP (cs, s, paintOutput, cubePaintOutput); WRAP (cs, s, paintTransformedOutput, cubePaintTransformedOutput); WRAP (cs, s, paintBackground, cubePaintBackground); + WRAP (cs, s, paintWindow, cubePaintWindow); WRAP (cs, s, applyScreenTransform, cubeApplyScreenTransform); WRAP (cs, s, setScreenOption, cubeSetGlobalScreenOption); WRAP (cs, s, outputChangeNotify, cubeOutputChangeNotify); @@ -1940,6 +2079,7 @@ cubeFiniScreen (CompPlugin *p, UNWRAP (cs, s, paintOutput); UNWRAP (cs, s, paintTransformedOutput); UNWRAP (cs, s, paintBackground); + UNWRAP (cs, s, paintWindow); UNWRAP (cs, s, applyScreenTransform); UNWRAP (cs, s, setScreenOption); UNWRAP (cs, s, outputChangeNotify); -- 1.4.4.2