static Bool
elementsPaintOutput (CompScreen              *s,
		 const ScreenPaintAttrib *sa,
		 const CompTransform	 *transform,
		 Region                  region,
		 CompOutput              *output,
		 unsigned int            mask)
{
	CompDisplay *d = s->display;
	Bool status;
	Bool active = elementActive(s);

	E_SCREEN (s);

	UNWRAP (eScreen, s, paintOutput);
	status = (*s->paintOutput) (s, sa, transform, region, output, mask);
	WRAP (eScreen, s, paintOutput, elementsPaintOutput);

	if(elementsGetApplyTransform (d))
		return status;

	if (active && elementsGetOverWindows (d))
	{
		CompTransform sTransform = *transform;
		transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform);
		glPushMatrix ();
		glLoadMatrixf (sTransform.m);
		beginRendering (s);
		glPopMatrix ();
	}

    return status;
}

static Bool
elementsDrawWindow (CompWindow           *w,
		const CompTransform  *transform,
		const FragmentAttrib *attrib,
		Region               region,
		unsigned int         mask)
{
	Bool status;

	E_SCREEN (w->screen);
	Bool active = FALSE;
	int ii;
	for (ii = 0; ii <= 4; ii++)
	{
		if (eScreen->isActive[ii])
			active = TRUE;
	}
	UNWRAP (eScreen, w->screen, drawWindow);
	status = (*w->screen->drawWindow) (w, transform, attrib, region, mask);
	WRAP (eScreen, w->screen, drawWindow, elementsDrawWindow);

	if (active && (w->type & CompWindowTypeDesktopMask) && 
		!elementsGetOverWindows (w->screen->display))
	{
		beginRendering (eScreen, w->screen);
	}
static Bool
stepPositions(void *closure)
{
	CompScreen *s = closure;
	int i, ii, numSnow, numAutumn, numStars, numFf, numBubbles, numTmp;
	element *ele;
	Bool onTopOfWindows;
	E_SCREEN(s);

	Bool active = FALSE;			//THis makes sure nothing happens if all features are off.
	for (ii = 0; ii <= 4; ii++)
	{
		if (eScreen->isActive[ii])
			active = TRUE;
	}

	if (!active)
		return TRUE;

	ele = eScreen->allElements;

	if (eScreen->isActive[0])
		numAutumn = elementsGetNumLeaves (s->display);	
	else
		numAutumn = 0;
	if (eScreen->isActive[1])
		numFf = elementsGetNumFireflies (s->display);
	else
		numFf = 0;
	if (eScreen->isActive[2])
		numSnow = elementsGetNumSnowflakes (s->display);
	else
		numSnow = 0;
	if (eScreen->isActive[3])
		numStars = elementsGetNumStars (s->display);
	else
		numStars = 0;
	if (eScreen->isActive[4])
		numBubbles = elementsGetNumBubbles (s->display);
	else
		numBubbles = 0;

	numTmp = numAutumn + numFf + numSnow + numStars + numBubbles;
	onTopOfWindows = elementsGetOverWindows (s->display);
	for (i = 0; i < numTmp; i++)
		elementTestCreate(eScreen, ele++);
	if (active && !onTopOfWindows )
	{
		CompWindow *w;
		for (w = s->windows; w; w = w->next)
		{
			if (w->type & CompWindowTypeDesktopMask)
				addWindowDamage (w);
		}
    	}
	else if (active)
		damageScreen (s);

	return TRUE;
static Bool
stepPositions(CompScreen *s, int elapsed)
{
	int i, numSnow, numAutumn, numStars, numFf, numBubbles, numTmp;
	element *ele;
	Bool onTopOfWindows;
	Bool active = elementActive(s);

	E_SCREEN(s);

	if (!active)
		return TRUE;

	ele = eScreen->allElements;

	if (eScreen->isActive[0])
		numAutumn = elementsGetNumLeaves (s->display);
	else
		numAutumn = 0;
	if (eScreen->isActive[1])
		numFf = elementsGetNumFireflies (s->display);
	else
		numFf = 0;
	if (eScreen->isActive[2])
		numSnow = elementsGetNumSnowflakes (s->display);
	else
		numSnow = 0;
	if (eScreen->isActive[3])
		numStars = elementsGetNumStars (s->display);
	else
		numStars = 0;
	if (eScreen->isActive[4])
		numBubbles = elementsGetNumBubbles (s->display);
	else
		numBubbles = 0;

	numTmp = numAutumn + numFf + numSnow + numStars + numBubbles;
	onTopOfWindows = elementsGetOverWindows (s->display);
	for (i = 0; i < numTmp; i++)
		elementTestCreate(eScreen, ele++, elapsed);
	if (active)
	{
		CompWindow *w;
		for (w = s->windows; w; w = w->next)
		{
			if (!onTopOfWindows && (w->type & CompWindowTypeDesktopMask))
				addWindowDamage (w);
			else if (onTopOfWindows && isNormalWin(w)) {
				eScreen->topWindow = w;
				addWindowDamage (w);
			}
		}

		damageScreen (s);
	}

	return TRUE;
}

static Bool
elementsPaintOutput (CompScreen              *s,
		 const ScreenPaintAttrib *sa,
		 const CompTransform	 *transform,
		 Region                  region,
		 CompOutput              *output, 
		 unsigned int            mask)
{
	Bool status;

	E_SCREEN (s);
	int ii;
	Bool active = FALSE;
	for (ii = 0; ii <= 4; ii++)
	{
		if (eScreen->isActive[ii])
			active = TRUE;
	}

	if (active && elementsGetOverWindows (s->display))
		mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;

	UNWRAP (eScreen, s, paintOutput);
	status = (*s->paintOutput) (s, sa, transform, region, output, mask);
	WRAP (eScreen, s, paintOutput, elementsPaintOutput);

	if (active && elementsGetOverWindows (s->display))
	{
		CompTransform sTransform = *transform;
		transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform);
		glPushMatrix ();
		glLoadMatrixf (sTransform.m);
		beginRendering (eScreen, s);
		glPopMatrix ();
	}
static Bool
elementsDrawWindow (CompWindow           *w,
		const CompTransform  *transform,
		const FragmentAttrib *attrib,
		Region               region,
		unsigned int         mask)
{
	CompScreen *s = w->screen;
	CompDisplay *d = s->display;
	Bool active = elementActive(s);
	Bool status = FALSE;

	E_SCREEN (s);

	if (active) {
		Bool applyTransform = elementsGetApplyTransform (d);
		Bool onTop = elementsGetOverWindows (d);
		Bool isDesktop = (w->type & CompWindowTypeDesktopMask) && !onTop;
		Bool isTopMost = w && (w == eScreen->topWindow) && onTop;

		if (isDesktop) {
			UNWRAP (eScreen, s, drawWindow);
			status = (*s->drawWindow) (w, transform, attrib, region, mask);
			WRAP (eScreen, s, drawWindow, elementsDrawWindow);
			beginRendering (s);
		} else if (isTopMost && applyTransform) {
			UNWRAP (eScreen, s, drawWindow);
			status = (*s->drawWindow) (w, transform, attrib, region, mask);
			WRAP (eScreen, s, drawWindow, elementsDrawWindow);
			beginRendering (s);
		} else {
			UNWRAP (eScreen, s, drawWindow);
			status = (*s->drawWindow) (w, transform, attrib, region, mask);
			WRAP (eScreen, s, drawWindow, elementsDrawWindow);
		}
	} else {
		UNWRAP (eScreen, s, drawWindow);
		status = (*s->drawWindow) (w, transform, attrib, region, mask);
		WRAP (eScreen, s, drawWindow, elementsDrawWindow);
	}

	return status;
}