--- include/cube.h | 39 ++++++++----- metadata/cube.xml.in | 24 ++++++++ plugins/cube.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 193 insertions(+), 23 deletions(-) diff --git a/include/cube.h b/include/cube.h index 4010b6b..24ad28d 100644 --- a/include/cube.h +++ b/include/cube.h @@ -40,22 +40,25 @@ typedef struct _CubeDisplay { CompOption opt[CUBE_DISPLAY_OPTION_NUM]; } CubeDisplay; -#define CUBE_SCREEN_OPTION_COLOR 0 -#define CUBE_SCREEN_OPTION_IN 1 -#define CUBE_SCREEN_OPTION_SCALE_IMAGE 2 -#define CUBE_SCREEN_OPTION_IMAGES 3 -#define CUBE_SCREEN_OPTION_SKYDOME 4 -#define CUBE_SCREEN_OPTION_SKYDOME_IMG 5 -#define CUBE_SCREEN_OPTION_SKYDOME_ANIM 6 -#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START 7 -#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END 8 -#define CUBE_SCREEN_OPTION_ACCELERATION 9 -#define CUBE_SCREEN_OPTION_SPEED 10 -#define CUBE_SCREEN_OPTION_TIMESTEP 11 -#define CUBE_SCREEN_OPTION_MIPMAP 12 -#define CUBE_SCREEN_OPTION_BACKGROUNDS 13 -#define CUBE_SCREEN_OPTION_ADJUST_IMAGE 14 -#define CUBE_SCREEN_OPTION_NUM 15 +#define CUBE_SCREEN_OPTION_COLOR 0 +#define CUBE_SCREEN_OPTION_IN 1 +#define CUBE_SCREEN_OPTION_SCALE_IMAGE 2 +#define CUBE_SCREEN_OPTION_IMAGES 3 +#define CUBE_SCREEN_OPTION_SKYDOME 4 +#define CUBE_SCREEN_OPTION_SKYDOME_IMG 5 +#define CUBE_SCREEN_OPTION_SKYDOME_ANIM 6 +#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_START 7 +#define CUBE_SCREEN_OPTION_SKYDOME_GRAD_END 8 +#define CUBE_SCREEN_OPTION_ACCELERATION 9 +#define CUBE_SCREEN_OPTION_SPEED 10 +#define CUBE_SCREEN_OPTION_TIMESTEP 11 +#define CUBE_SCREEN_OPTION_MIPMAP 12 +#define CUBE_SCREEN_OPTION_BACKGROUNDS 13 +#define CUBE_SCREEN_OPTION_ADJUST_IMAGE 14 +#define CUBE_SCREEN_OPTION_ACTIVE_OPACITY 15 +#define CUBE_SCREEN_OPTION_INACTIVE_OPACITY 16 +#define CUBE_SCREEN_OPTION_FADE_TIME 17 +#define CUBE_SCREEN_OPTION_NUM 18 typedef void (*CubeGetRotationProc) (CompScreen *s, float *x, @@ -90,6 +93,7 @@ typedef struct _CubeScreen { PaintOutputProc paintOutput; PaintTransformedOutputProc paintTransformedOutput; PaintBackgroundProc paintBackground; + PaintWindowProc paintWindow; ApplyScreenTransformProc applyScreenTransform; SetScreenOptionProc setScreenOption; OutputChangeNotifyProc outputChangeNotify; @@ -142,6 +146,9 @@ typedef struct _CubeScreen { float outputXOffset; float outputYOffset; + float desktopOpacity; + float toOpacity; + CompTexture *bg; int nBg; } CubeScreen; diff --git a/metadata/cube.xml.in b/metadata/cube.xml.in index 0f674e7..23d93e0 100644 --- a/metadata/cube.xml.in +++ b/metadata/cube.xml.in @@ -134,6 +134,30 @@ <_long>Adjust top face image to rotation</_long> <default>false</default> </option> + <option name="active_opacity" type="float"> + <_short>Opacity During Rotation</_short> + <_long>Opacity of desktop window during rotation.</_long> + <default>30.0</default> + <min>0.0</min> + <max>100.0</max> + <precision>1.0</precision> + </option> + <option name="inactive_opacity" type="float"> + <_short>Opacity When Not Rotating</_short> + <_long>Opacity of desktop window when not rotating.</_long> + <default>100.0</default> + <min>0.0</min> + <max>100.0</max> + <precision>1.0</precision> + </option> + <option name="fade_time" type="float"> + <_short>Fade Time</_short> + <_long>Desktop Window Opacity Fade Time.</_long> + <default>1.0</default> + <min>0.0</min> + <max>10.0</max> + <precision>0.1</precision> + </option> </screen> </plugin> </compiz> diff --git a/plugins/cube.c b/plugins/cube.c index 0162e0d..bdabedc 100644 --- a/plugins/cube.c +++ b/plugins/cube.c @@ -798,6 +798,8 @@ static void cubePreparePaintScreen (CompScreen *s, int msSinceLastPaint) { + int opt; + CUBE_SCREEN (s); if (cs->grabIndex) @@ -836,6 +838,35 @@ cubePreparePaintScreen (CompScreen *s, memset (cs->cleared, 0, sizeof (Bool) * s->nOutputDev); + /* Transparency handling */ + if (cs->rotationState != RotationNone) + opt = CUBE_SCREEN_OPTION_ACTIVE_OPACITY; + else + opt = CUBE_SCREEN_OPTION_INACTIVE_OPACITY; + + cs->toOpacity = (cs->opt[opt].value.f / 100.0f) * OPAQUE; + + if (cs->opt[CUBE_SCREEN_OPTION_FADE_TIME].value.f == 0.0f) + cs->desktopOpacity = cs->toOpacity; + else if (cs->desktopOpacity != cs->toOpacity) + { + float steps = (msSinceLastPaint * OPAQUE / 1000.0) / + cs->opt[CUBE_SCREEN_OPTION_FADE_TIME].value.f; + if (steps < 12) + steps = 12; + + if (cs->toOpacity > cs->desktopOpacity) + { + cs->desktopOpacity += steps; + cs->desktopOpacity = MIN (cs->toOpacity, cs->desktopOpacity); + } + if (cs->toOpacity < cs->desktopOpacity) + { + cs->desktopOpacity -= steps; + cs->desktopOpacity = MAX (cs->toOpacity, cs->desktopOpacity); + } + } + UNWRAP (cs, s, preparePaintScreen); (*s->preparePaintScreen) (s, msSinceLastPaint); WRAP (cs, s, preparePaintScreen, cubePreparePaintScreen); @@ -853,7 +884,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; @@ -875,7 +906,7 @@ cubeDonePaintScreen (CompScreen *s) { CUBE_SCREEN (s); - if (cs->grabIndex) + if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity) damageScreen (s); UNWRAP (cs, s, donePaintScreen); @@ -1167,7 +1198,7 @@ cubePaintTopBottom (CompScreen *s, screenLighting (s, TRUE); - glColor3usv (cs->color); + glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity); glPushMatrix (); @@ -1181,6 +1212,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); for (i = 0; i < 2; i++) @@ -1217,6 +1255,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 @@ -1234,6 +1276,7 @@ cubePaintTransformedOutput (CompScreen *s, GLenum filter = s->display->textureFilter; PaintOrder paintOrder; Bool clear; + Bool wasCulled = FALSE; int output = 0; CUBE_SCREEN (s); @@ -1243,6 +1286,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; @@ -1336,13 +1386,14 @@ cubePaintTransformedOutput (CompScreen *s, paintOrder = BTF; } - if (cs->invert == -1) + if (cs->invert == -1 || cs->desktopOpacity != OPAQUE) cubePaintAllViewports (s, &sa,transform, region, outputPtr, mask, xMove, size, hsize, paintOrder); if (cs->grabIndex == 0 && hsize > 2 && - (cs->invert != 1 || sa.vRotate != 0.0f || sa.yTranslate != 0.0f)) + (cs->invert != 1 || cs->desktopOpacity != OPAQUE || + sa.vRotate != 0.0f || sa.yTranslate != 0.0f)) { (*cs->paintTopBottom) (s, &sa, transform, outputPtr, hsize); } @@ -1358,17 +1409,64 @@ cubePaintTransformedOutput (CompScreen *s, paintOrder = FTB; } - if (cs->invert == 1) + if (cs->invert == 1 || cs->desktopOpacity != OPAQUE) cubePaintAllViewports (s, &sa, transform, region, outputPtr, mask, xMove, size, hsize, paintOrder); s->display->textureFilter = filter; + if (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) @@ -1377,6 +1475,8 @@ cubePaintBackground (CompScreen *s, CUBE_SCREEN (s); + cubeSetBackgroundOpacity(s); + n = cs->opt[CUBE_SCREEN_OPTION_BACKGROUNDS].value.list.nValue; if (n) { @@ -1387,13 +1487,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 @@ -1409,7 +1513,10 @@ cubePaintBackground (CompScreen *s, data = malloc (sizeof (GLfloat) * nBox * 16); if (!data) + { + cubeUnSetBackgroundOpacity(s); return; + } d = data; n = nBox; @@ -1466,6 +1573,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 @@ -1793,7 +1925,10 @@ static const CompMetadataOptionInfo cubeScreenOptionInfo[] = { { "timestep", "float", "<min>0.1</min>", 0, 0 }, { "mipmap", "bool", 0, 0, 0 }, { "backgrounds", "list", "<type>string</type>", 0, 0 }, - { "adjust_image", "bool", 0, 0, 0 } + { "adjust_image", "bool", 0, 0, 0 }, + { "active_opacity", "float", "<min>0.0</min><max>100.0</max>", 0, 0 }, + { "inactive_opacity", "float", "<min>0.0</min><max>100.0</max>", 0, 0 }, + { "fade_time", "float", "<min>0.0</min>", 0, 0 } }; static Bool @@ -1861,6 +1996,8 @@ cubeInitScreen (CompPlugin *p, cs->rotationState = RotationNone; + cs->desktopOpacity = OPAQUE; + memset (cs->cleared, 0, sizeof (cs->cleared)); cubeUpdateOutputs (s); @@ -1883,6 +2020,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); @@ -1905,6 +2043,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.5.0.6 --=-BN45f9l1EBDZU+GMKjya Content-Disposition: attachment; filename*0=0004-Added-option-to-enable-cube-transparency-only-on-but.pat; filename*1=ch Content-Type: application/mbox; name=0004-Added-option-to-enable-cube-transparency-only-on-but.patch Content-Transfer-Encoding: 7bit