diff --git a/plugins/cube.c b/plugins/cube.c index 06effb2..45dc44e 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,20 +134,24 @@ 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_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 #define MULTM(x,y,z) \ z[0] = x[0] * y[0] + x[4] * y[1] + x[8] * y[2] + x[12] * y[3]; \ @@ -174,6 +193,8 @@ typedef struct _CubeScreen { SetScreenOptionProc setScreenOption; OutputChangeNotifyProc outputChangeNotify; SetClipPlanesProc setClipPlanes; + PaintBackgroundProc paintBackground; + PaintWindowProc paintWindow; CompOption opt[CUBE_SCREEN_OPTION_NUM]; @@ -223,6 +244,9 @@ typedef struct _CubeScreen { Bool disableCaps; Bool paintAllViewports; + + float desktopOpacity; + float toOpacity; #ifdef USE_LIBRSVG cairo_t *cr; @@ -1018,6 +1042,12 @@ cubeSetScreenOption (CompPlugin *plugin, case CUBE_SCREEN_OPTION_MIPMAP: if (compSetBoolOption (o, value)) 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; } @@ -1151,6 +1181,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 @@ -1216,11 +1286,43 @@ 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 @@ -1235,7 +1337,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; @@ -1253,7 +1355,7 @@ cubeDonePaintScreen (CompScreen *s) { CUBE_SCREEN (s); - if (cs->grabIndex) + if (cs->grabIndex || cs->desktopOpacity != cs->toOpacity) damageScreen (s); UNWRAP (cs, s, donePaintScreen); @@ -1261,6 +1363,71 @@ cubeDonePaintScreen (CompScreen *s) WRAP (cs, s, donePaintScreen, cubeDonePaintScreen); } +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) + wa.opacity = cs->desktopOpacity; + + UNWRAP (cs, s, paintWindow); + status = (*s->paintWindow) (w, &wa, transform, region, mask); + WRAP (cs, s, paintWindow, cubePaintWindow); + + return status; +} + static Bool cubeCheckFTB (CompScreen *s, const ScreenPaintAttrib *sAttrib, @@ -1452,12 +1619,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) { @@ -1566,7 +1741,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) @@ -1581,7 +1756,7 @@ cubePaintTransformedScreen (CompScreen *s, screenLighting (s, TRUE); - glColor3usv (cs->color); + glColor4us (cs->color[0], cs->color[1], cs->color[2], cs->desktopOpacity); glPushMatrix (); @@ -1592,6 +1767,12 @@ cubePaintTransformedScreen (CompScreen *s, glVertexPointer (3, GL_FLOAT, 0, cs->vertices); + if (cs->desktopOpacity != OPAQUE) + { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + int i; for (i = 0; i < 2; i++) { @@ -1632,13 +1813,19 @@ cubePaintTransformedScreen (CompScreen *s, glColor4usv (defaultColor); glEnableClientState (GL_TEXTURE_COORD_ARRAY); + + 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); WRAP (cs, s, paintTransformedScreen, cubePaintTransformedScreen); + if (cs->desktopOpacity != OPAQUE && wasCulled) + glEnable(GL_CULL_FACE); + s->display->textureFilter = filter; }