Пример #1
0
static Bool
minPaintWindow (CompWindow              *w,
                const WindowPaintAttrib *attrib,
                const CompTransform     *transform,
                Region                  region,
                unsigned int            mask)
{
	CompScreen *s = w->screen;
	Bool       status;

	MIN_SCREEN (s);
	MIN_WINDOW (w);

	if (mw->adjust)
	{
		FragmentAttrib fragment;
		CompTransform  wTransform = *transform;

		if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
			return FALSE;

		UNWRAP (ms, s, paintWindow);
		status = (*s->paintWindow) (w, attrib, transform, region,
		                       mask | PAINT_WINDOW_NO_CORE_INSTANCE_MASK);
		WRAP (ms, s, paintWindow, minPaintWindow);

		initFragmentAttrib (&fragment, &w->lastPaint);

		if (w->alpha || fragment.opacity != OPAQUE)
			mask |= PAINT_WINDOW_TRANSLUCENT_MASK;

		matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
		matrixScale (&wTransform, mw->xScale, mw->yScale, 1.0f);
		matrixTranslate (&wTransform,
		                 mw->tx / mw->xScale - w->attrib.x,
		                 mw->ty / mw->yScale - w->attrib.y,
		                 0.0f);

		glPushMatrix ();
		glLoadMatrixf (wTransform.m);

		(*s->drawWindow) (w, &wTransform, &fragment, region,
		                  mask | PAINT_WINDOW_TRANSFORMED_MASK);

		glPopMatrix ();
	}
	else
	{
		/* no core instance from windows that have been animated */
		if (mw->state == IconicState)
			mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;

		UNWRAP (ms, s, paintWindow);
		status = (*s->paintWindow) (w, attrib, transform, region, mask);
		WRAP (ms, s, paintWindow, minPaintWindow);
	}

	return status;
}
static Bool
staticInitWindow (CompPlugin *p,
                  CompWindow *w)
{
    StaticWindow *sw;

    STATIC_SCREEN (w->screen);

    sw = malloc (sizeof (StaticWindow));
    if (!sw)
        return FALSE;

    initFragmentAttrib (&sw->fragment, &w->paint);

    w->base.privates[ss->windowPrivateIndex].ptr = sw;

    return TRUE;
}
Пример #3
0
/*
 * groupPaintThumb - taken from switcher and modified for tab bar
 *
 */
static void
groupPaintThumb (GroupSelection      *group,
                 GroupTabBarSlot     *slot,
                 const CompTransform *transform,
                 int                 targetOpacity)
{
	CompWindow            *w = slot->window;
	CompScreen            *s = w->screen;
	AddWindowGeometryProc oldAddWindowGeometry;
	WindowPaintAttrib wAttrib = w->paint;
	int tw, th;

	tw = slot->region->extents.x2 - slot->region->extents.x1;
	th = slot->region->extents.y2 - slot->region->extents.y1;

	/* Wrap drawWindowGeometry to make sure the general
	   drawWindowGeometry function is used */
	oldAddWindowGeometry = s->addWindowGeometry;
	s->addWindowGeometry = addWindowGeometry;

	const BananaValue *
	option_fade_time = bananaGetOption (bananaIndex,
	                                    "fade_time",
	                                    s->screenNum);

	/* animate fade */
	if (group && group->tabBar->state == PaintFadeIn)
	{
		wAttrib.opacity -= wAttrib.opacity * group->tabBar->animationTime /
		                   (option_fade_time->f * 1000);
	}
	else if (group && group->tabBar->state == PaintFadeOut)
	{
		wAttrib.opacity = wAttrib.opacity * group->tabBar->animationTime /
		                  (option_fade_time->f * 1000);
	}

	wAttrib.opacity = wAttrib.opacity * targetOpacity / OPAQUE;

	if (w->mapNum)
	{
		FragmentAttrib fragment;
		CompTransform wTransform = *transform;
		int width, height;
		int vx, vy;

		width = w->width + w->output.left + w->output.right;
		height = w->height + w->output.top + w->output.bottom;

		if (width > tw)
			wAttrib.xScale = (float) tw / width;
		else
			wAttrib.xScale = 1.0f;
		if (height > th)
			wAttrib.yScale = (float) tw / height;
		else
			wAttrib.yScale = 1.0f;

		if (wAttrib.xScale < wAttrib.yScale)
			wAttrib.yScale = wAttrib.xScale;
		else
			wAttrib.xScale = wAttrib.yScale;

		/* FIXME: do some more work on the highlight on hover feature
		   // Highlight on hover
		   if (group && group->tabBar && group->tabBar->hoveredSlot == slot) {
		   wAttrib.saturation = 0;
		   wAttrib.brightness /= 1.25f;
		   }*/

		groupGetDrawOffsetForSlot (slot, &vx, &vy);

		wAttrib.xTranslate = (slot->region->extents.x1 +
		                      slot->region->extents.x2) / 2 + vx;
		wAttrib.yTranslate = slot->region->extents.y1 + vy;

		initFragmentAttrib (&fragment, &wAttrib);

		matrixTranslate (&wTransform,
		                 wAttrib.xTranslate, wAttrib.yTranslate, 0.0f);
		matrixScale (&wTransform, wAttrib.xScale, wAttrib.yScale, 1.0f);
		matrixTranslate (&wTransform, -(WIN_X (w) + WIN_WIDTH (w) / 2),
		                 -(WIN_Y (w) - w->output.top), 0.0f);

		glPushMatrix ();
		glLoadMatrixf (wTransform.m);

		(*s->drawWindow)(w, &wTransform, &fragment, &infiniteRegion,
		                 PAINT_WINDOW_TRANSFORMED_MASK |
		                 PAINT_WINDOW_TRANSLUCENT_MASK);

		glPopMatrix ();
	}

	s->addWindowGeometry = oldAddWindowGeometry;
}
Пример #4
0
/*
 * groupPaintTabBar
 *
 */
static void
groupPaintTabBar (GroupSelection          *group,
                  const WindowPaintAttrib *wAttrib,
                  const CompTransform     *transform,
                  unsigned int            mask,
                  Region                  clipRegion)
{
	CompWindow      *topTab;
	CompScreen      *s = group->screen;
	GroupTabBar     *bar = group->tabBar;
	int count;
	REGION box;

	GROUP_SCREEN (s);

	if (HAS_TOP_WIN (group))
		topTab = TOP_TAB (group);
	else
		topTab = PREV_TOP_TAB (group);

#define PAINT_BG     0
#define PAINT_SEL    1
#define PAINT_THUMBS 2
#define PAINT_TEXT   3
#define PAINT_MAX    4

	box.rects = &box.extents;
	box.numRects = 1;

	const BananaValue *
	option_fade_time = bananaGetOption (bananaIndex,
	                                    "fade_time",
	                                    s->screenNum);

	const BananaValue *
	option_mipmaps = bananaGetOption (bananaIndex,
	                                  "mipmaps",
	                                  s->screenNum);

	const BananaValue *
	option_fade_text_time = bananaGetOption (bananaIndex,
	                                         "fade_text_time",
	                                         s->screenNum);

	for (count = 0; count < PAINT_MAX; count++)
	{
		int alpha = OPAQUE;
		float wScale = 1.0f, hScale = 1.0f;
		GroupCairoLayer *layer = NULL;

		if (bar->state == PaintFadeIn)
			alpha -= alpha * bar->animationTime / (option_fade_time->f * 1000);
		else if (bar->state == PaintFadeOut)
			alpha = alpha * bar->animationTime / (option_fade_time->f * 1000);

		switch (count) {
		case PAINT_BG:
		{
			int newWidth;

			layer = bar->bgLayer;

			/* handle the repaint of the background */
			newWidth = bar->region->extents.x2 - bar->region->extents.x1;
			if (layer && (newWidth > layer->texWidth))
				newWidth = layer->texWidth;

			wScale = (double) (bar->region->extents.x2 -
			                   bar->region->extents.x1) / (double) newWidth;

			/* FIXME: maybe move this over to groupResizeTabBarRegion -
			   the only problem is that we would have 2 redraws if
			   there is an animation */
			if (newWidth != bar->oldWidth || bar->bgAnimation)
				groupRenderTabBarBackground (group);

			bar->oldWidth = newWidth;
			box.extents = bar->region->extents;
		}
		break;

		case PAINT_SEL:
			if (group->topTab != gs->draggedSlot)
			{
				layer = bar->selectionLayer;
				box.extents = group->topTab->region->extents;
			}
			break;

		case PAINT_THUMBS:
		{
			GLenum oldTextureFilter;
			GroupTabBarSlot *slot;

			oldTextureFilter = display.textureFilter;

			if (option_mipmaps->b)
				display.textureFilter = GL_LINEAR_MIPMAP_LINEAR;

			for (slot = bar->slots; slot; slot = slot->next)
			{
				if (slot != gs->draggedSlot || !gs->dragged)
					groupPaintThumb (group, slot, transform,
					                 wAttrib->opacity);
			}

			display.textureFilter = oldTextureFilter;
		}
		break;

		case PAINT_TEXT:
			if (bar->textLayer && (bar->textLayer->state != PaintOff))
			{
				layer = bar->textLayer;

				box.extents.x1 = bar->region->extents.x1 + 5;
				box.extents.x2 = bar->region->extents.x1 +
				                 bar->textLayer->texWidth + 5;
				box.extents.y1 = bar->region->extents.y2 -
				                 bar->textLayer->texHeight - 5;
				box.extents.y2 = bar->region->extents.y2 - 5;

				if (box.extents.x2 > bar->region->extents.x2)
					box.extents.x2 = bar->region->extents.x2;

				/* recalculate the alpha again for text fade... */
				if (layer->state == PaintFadeIn)
					alpha -= alpha * layer->animationTime /
					         (option_fade_text_time->f * 1000);
				else if (layer->state == PaintFadeOut)
					alpha = alpha * layer->animationTime /
					        (option_fade_text_time->f * 1000);
			}
			break;
		}

		if (layer)
		{
			CompMatrix matrix = layer->texture.matrix;

			/* remove the old x1 and y1 so we have a relative value */
			box.extents.x2 -= box.extents.x1;
			box.extents.y2 -= box.extents.y1;
			box.extents.x1 = (box.extents.x1 - topTab->attrib.x) / wScale +
			                 topTab->attrib.x;
			box.extents.y1 = (box.extents.y1 - topTab->attrib.y) / hScale +
			                 topTab->attrib.y;

			/* now add the new x1 and y1 so we have a absolute value again,
			   also we don't want to stretch the texture... */
			if (box.extents.x2 * wScale < layer->texWidth)
				box.extents.x2 += box.extents.x1;
			else
				box.extents.x2 = box.extents.x1 + layer->texWidth;

			if (box.extents.y2 * hScale < layer->texHeight)
				box.extents.y2 += box.extents.y1;
			else
				box.extents.y2 = box.extents.y1 + layer->texHeight;

			matrix.x0 -= box.extents.x1 * matrix.xx;
			matrix.y0 -= box.extents.y1 * matrix.yy;
			topTab->vCount = topTab->indexCount = 0;

			addWindowGeometry (topTab, &matrix, 1, &box, clipRegion);

			if (topTab->vCount)
			{
				FragmentAttrib fragment;
				CompTransform wTransform = *transform;

				matrixTranslate (&wTransform,
				                 WIN_X (topTab), WIN_Y (topTab), 0.0f);
				matrixScale (&wTransform, wScale, hScale, 1.0f);
				matrixTranslate (&wTransform,
				                 wAttrib->xTranslate / wScale - WIN_X (topTab),
				                 wAttrib->yTranslate / hScale - WIN_Y (topTab),
				                 0.0f);

				glPushMatrix ();
				glLoadMatrixf (wTransform.m);

				alpha = alpha * ((float)wAttrib->opacity / OPAQUE);

				initFragmentAttrib (&fragment, wAttrib);
				fragment.opacity = alpha;

				(*s->drawWindowTexture)(topTab, &layer->texture,
				                        &fragment, mask |
				                        PAINT_WINDOW_BLEND_MASK |
				                        PAINT_WINDOW_TRANSFORMED_MASK |
				                        PAINT_WINDOW_TRANSLUCENT_MASK);

				glPopMatrix ();
			}
		}
	}
}
static void
scalePaintDecoration (CompWindow	      *w,
		      const WindowPaintAttrib *attrib,
		      const CompTransform     *transform,
		      Region		      region,
		      unsigned int	      mask)
{
    CompScreen *s = w->screen;

    SCALE_SCREEN (s);

    if (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i != SCALE_ICON_NONE)
    {
	WindowPaintAttrib sAttrib = *attrib;
	CompIcon	  *icon;

	SCALE_WINDOW (w);

	icon = getWindowIcon (w, 96, 96);
	if (!icon)
	    icon = w->screen->defaultIcon;

	if (icon && (icon->texture.name || iconToTexture (w->screen, icon)))
	{
	    REGION iconReg;
	    float  scale;
	    float  x, y;
	    int    width, height;
	    int    scaledWinWidth, scaledWinHeight;
	    float  ds;

	    scaledWinWidth  = w->width  * sw->scale;
	    scaledWinHeight = w->height * sw->scale;

	    switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) {
	    case SCALE_ICON_NONE:
	    case SCALE_ICON_EMBLEM:
		scale = 1.0f;
		break;
	    case SCALE_ICON_BIG:
	    default:
		sAttrib.opacity /= 3;
		scale = MIN (((float) scaledWinWidth / icon->width),
			     ((float) scaledWinHeight / icon->height));
		break;
	    }

	    width  = icon->width  * scale;
	    height = icon->height * scale;

	    switch (ss->opt[SCALE_SCREEN_OPTION_ICON].value.i) {
	    case SCALE_ICON_NONE:
	    case SCALE_ICON_EMBLEM:
		x = w->attrib.x + scaledWinWidth - icon->width;
		y = w->attrib.y + scaledWinHeight - icon->height;
		break;
	    case SCALE_ICON_BIG:
	    default:
		x = w->attrib.x + scaledWinWidth / 2 - width / 2;
		y = w->attrib.y + scaledWinHeight / 2 - height / 2;
		break;
	    }

	    x += sw->tx;
	    y += sw->ty;

	    if (sw->slot)
	    {
		sw->delta =
		    fabs (sw->slot->x1 - w->attrib.x) +
		    fabs (sw->slot->y1 - w->attrib.y) +
		    fabs (1.0f - sw->slot->scale) * 500.0f;
	    }

	    if (sw->delta)
	    {
		float o;

		ds =
		    fabs (sw->tx) +
		    fabs (sw->ty) +
		    fabs (1.0f - sw->scale) * 500.0f;

		if (ds > sw->delta)
		    ds = sw->delta;

		o = ds / sw->delta;

		if (sw->slot)
		{
		    if (o < sw->lastThumbOpacity)
			o = sw->lastThumbOpacity;
		}
		else
		{
		    if (o > sw->lastThumbOpacity)
			o = 0.0f;
		}

		sw->lastThumbOpacity = o;

		sAttrib.opacity = sAttrib.opacity * o;
	    }

	    mask |= PAINT_WINDOW_BLEND_MASK;

	    iconReg.rects    = &iconReg.extents;
	    iconReg.numRects = 1;

	    iconReg.extents.x1 = 0;
	    iconReg.extents.y1 = 0;
	    iconReg.extents.x2 = iconReg.extents.x1 + width;
	    iconReg.extents.y2 = iconReg.extents.y1 + height;

	    w->vCount = w->indexCount = 0;
	    if (iconReg.extents.x1 < iconReg.extents.x2 &&
		iconReg.extents.y1 < iconReg.extents.y2)
		(*w->screen->addWindowGeometry) (w,
						 &icon->texture.matrix, 1,
						 &iconReg, &iconReg);

	    if (w->vCount)
	    {
		FragmentAttrib fragment;
		CompTransform  wTransform = *transform;

		initFragmentAttrib (&fragment, &sAttrib);

		matrixScale (&wTransform, scale, scale, 1.0f);
		matrixTranslate (&wTransform, x / scale, y / scale, 0.0f);

		glPushMatrix ();
		glLoadMatrixf (wTransform.m);

		(*w->screen->drawWindowTexture) (w,
						 &icon->texture, &fragment,
						 mask);

		glPopMatrix ();
	    }
	}
    }
}
Пример #6
0
static void
thumbPaintThumb (CompScreen          *s,
                 Thumbnail           *t,
                 const CompTransform *transform)
{
	AddWindowGeometryProc oldAddWindowGeometry;
	CompWindow            *w = t->win;
	int wx = t->x;
	int wy = t->y;
	float width  = t->width;
	float height = t->height;
	WindowPaintAttrib sAttrib;
	unsigned int mask = PAINT_WINDOW_TRANSFORMED_MASK |
	                    PAINT_WINDOW_TRANSLUCENT_MASK;

	THUMB_SCREEN (s);

	if (!w)
		return;

	sAttrib = w->paint;

	if (t->textData)
		height += t->textData->height + TEXT_DISTANCE;

	/* Wrap drawWindowGeometry to make sure the general
	   drawWindowGeometry function is used */
	oldAddWindowGeometry = s->addWindowGeometry;
	s->addWindowGeometry = addWindowGeometry;

	if (w->texture->pixmap)
	{
		int off = t->offset;
		GLenum filter = display.textureFilter;
		FragmentAttrib fragment;
		CompTransform wTransform = *transform;

		glEnable (GL_BLEND);
		glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glDisableClientState (GL_TEXTURE_COORD_ARRAY);

		const BananaValue *
		option_window_like = bananaGetOption (bananaIndex,
		                                      "window_like",
		                                      s->screenNum);

		if (option_window_like->b)
		{
			glColor4f (1.0, 1.0, 1.0, t->opacity);
			enableTexture (s, &ts->windowTexture, COMP_TEXTURE_FILTER_GOOD);
		}
		else
		{
			unsigned short color[] = { 0, 0, 0, 0 };

			const BananaValue *
			option_thumb_color = bananaGetOption (bananaIndex,
			                                      "thumb_color",
			                                      s->screenNum);

			stringToColor (option_thumb_color->s, color);

			glColor4us (color[0],
			            color[1],
			            color[2],
			            color[3] * t->opacity);

			enableTexture (s, &ts->glowTexture, COMP_TEXTURE_FILTER_GOOD);
		}

		glBegin (GL_QUADS);

		glTexCoord2f (1, 0);
		glVertex2f (wx, wy);
		glVertex2f (wx, wy + height);
		glVertex2f (wx + width, wy + height);
		glVertex2f (wx + width, wy);

		glTexCoord2f (0, 1);
		glVertex2f (wx - off, wy - off);
		glTexCoord2f (0, 0);
		glVertex2f (wx - off, wy);
		glTexCoord2f (1, 0);
		glVertex2f (wx, wy);
		glTexCoord2f (1, 1);
		glVertex2f (wx, wy - off);

		glTexCoord2f (1, 1);
		glVertex2f (wx + width, wy - off);
		glTexCoord2f (1, 0);
		glVertex2f (wx + width, wy);
		glTexCoord2f (0, 0);
		glVertex2f (wx + width + off, wy);
		glTexCoord2f (0, 1);
		glVertex2f (wx + width + off, wy - off);

		glTexCoord2f (0, 0);
		glVertex2f (wx - off, wy + height);
		glTexCoord2f (0, 1);
		glVertex2f (wx - off, wy + height + off);
		glTexCoord2f (1, 1);
		glVertex2f (wx, wy + height + off);
		glTexCoord2f (1, 0);
		glVertex2f (wx, wy + height);

		glTexCoord2f (1, 0);
		glVertex2f (wx + width, wy + height);
		glTexCoord2f (1, 1);
		glVertex2f (wx + width, wy + height + off);
		glTexCoord2f (0, 1);
		glVertex2f (wx + width + off, wy + height + off);
		glTexCoord2f (0, 0);
		glVertex2f (wx + width + off, wy + height);

		glTexCoord2f (1, 1);
		glVertex2f (wx, wy - off);
		glTexCoord2f (1, 0);
		glVertex2f (wx, wy);
		glTexCoord2f (1, 0);
		glVertex2f (wx + width, wy);
		glTexCoord2f (1, 1);
		glVertex2f (wx + width, wy - off);

		glTexCoord2f (1, 0);
		glVertex2f (wx, wy + height);
		glTexCoord2f (1, 1);
		glVertex2f (wx, wy + height + off);
		glTexCoord2f (1, 1);
		glVertex2f (wx + width, wy + height + off);
		glTexCoord2f (1, 0);
		glVertex2f (wx + width, wy + height);

		glTexCoord2f (0, 0);
		glVertex2f (wx - off, wy);
		glTexCoord2f (0, 0);
		glVertex2f (wx - off, wy + height);
		glTexCoord2f (1, 0);
		glVertex2f (wx, wy + height);
		glTexCoord2f (1, 0);
		glVertex2f (wx, wy);

		glTexCoord2f (1, 0);
		glVertex2f (wx + width, wy);
		glTexCoord2f (1, 0);
		glVertex2f (wx + width, wy + height);
		glTexCoord2f (0, 0);
		glVertex2f (wx + width + off, wy + height);
		glTexCoord2f (0, 0);
		glVertex2f (wx + width + off, wy);

		glEnd ();

		if (option_window_like->b)
		{
			disableTexture (s, &ts->windowTexture);
		}
		else
		{
			disableTexture (s, &ts->glowTexture);
		}

		glColor4usv (defaultColor);

		glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

		if (t->textData)
		{
			float ox = 0.0;

			if (t->textData->width < width)
				ox = (width - (int)t->textData->width) / 2.0;

			textDrawText (s, t->textData, wx + ox, wy + height, t->opacity);
		}

		glEnableClientState (GL_TEXTURE_COORD_ARRAY);
		glDisable (GL_BLEND);

		screenTexEnvMode (s, GL_REPLACE);

		glColor4usv (defaultColor);

		sAttrib.opacity *= t->opacity;
		sAttrib.yScale = t->scale;
		sAttrib.xScale = t->scale;

		sAttrib.xTranslate = wx - w->attrib.x + w->input.left * sAttrib.xScale;
		sAttrib.yTranslate = wy - w->attrib.y + w->input.top * sAttrib.yScale;

		const BananaValue *
		option_mipmap = bananaGetOption (bananaIndex,
		                                 "mipmap",
		                                 s->screenNum);

		if (option_mipmap->b)
			display.textureFilter = GL_LINEAR_MIPMAP_LINEAR;

		initFragmentAttrib (&fragment, &sAttrib);

		matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
		matrixScale (&wTransform, sAttrib.xScale, sAttrib.yScale, 1.0f);
		matrixTranslate (&wTransform,
		                 sAttrib.xTranslate / sAttrib.xScale - w->attrib.x,
		                 sAttrib.yTranslate / sAttrib.yScale - w->attrib.y,
		                 0.0f);

		glPushMatrix ();
		glLoadMatrixf (wTransform.m);
		(*s->drawWindow) (w, &wTransform, &fragment, &infiniteRegion, mask);
		glPopMatrix ();

		display.textureFilter = filter;
	}

	s->addWindowGeometry = oldAddWindowGeometry;
}
static Bool
ringPaintWindow (CompWindow		 *w,
       		 const WindowPaintAttrib *attrib,
		 const CompTransform	 *transform,
		 Region		         region,
		 unsigned int		 mask)
{
    CompScreen *s = w->screen;
    Bool       status;

    RING_SCREEN (s);

    if (rs->state != RingStateNone)
    {
	WindowPaintAttrib sAttrib = *attrib;
	Bool		  scaled = FALSE;

	RING_WINDOW (w);

    	if (w->mapNum)
	{
	    if (!w->texture->pixmap && !w->bindFailed)
		bindWindow (w);
	}

	if (rw->adjust || rw->slot)
	{
	    scaled = rw->adjust || (rw->slot && rs->paintingSwitcher);
	    mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
	}
	else if (rs->state != RingStateIn)
	{
	    if (ringGetDarkenBack (s))
	    {
		/* modify brightness of the other windows */
		sAttrib.brightness = sAttrib.brightness / 2;
	    }
	}

	UNWRAP (rs, s, paintWindow);
	status = (*s->paintWindow) (w, &sAttrib, transform, region, mask);
	WRAP (rs, s, paintWindow, ringPaintWindow);

	if (scaled && w->texture->pixmap)
	{
	    FragmentAttrib fragment;
	    CompTransform  wTransform = *transform;

	    if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
		return FALSE;

	    initFragmentAttrib (&fragment, &w->lastPaint);

	    if (rw->slot)
	    {
    		fragment.brightness = (float) fragment.brightness * 
		                      rw->slot->depthBrightness;

		if (w != rs->selectedWindow)
		    fragment.opacity = (float)fragment.opacity *
			               ringGetInactiveOpacity (s) / 100;
	    }

	    if (w->alpha || fragment.opacity != OPAQUE)
		mask |= PAINT_WINDOW_TRANSLUCENT_MASK;

	    matrixTranslate (&wTransform, w->attrib.x, w->attrib.y, 0.0f);
	    matrixScale (&wTransform, rw->scale, rw->scale, 1.0f);
	    matrixTranslate (&wTransform,
			     rw->tx / rw->scale - w->attrib.x,
			     rw->ty / rw->scale - w->attrib.y,
			     0.0f);

	    glPushMatrix ();
	    glLoadMatrixf (wTransform.m);

	    (*s->drawWindow) (w, &wTransform, &fragment, region,
			      mask | PAINT_WINDOW_TRANSFORMED_MASK);

	    glPopMatrix ();
	}

	if (scaled && (rs->state != RingStateIn) &&
	    ((ringGetOverlayIcon (s) != OverlayIconNone) || 
	     !w->texture->pixmap))
	{
	    CompIcon *icon;

	    icon = getWindowIcon (w, MAX_ICON_SIZE, MAX_ICON_SIZE);
	    if (!icon)
		icon = w->screen->defaultIcon;

	    if (icon && (icon->texture.name || iconToTexture (w->screen, icon)))
	    {
		REGION              iconReg;
		CompMatrix          matrix;
		float               scale;
		float               x, y;
		int                 width, height;
		int                 scaledWinWidth, scaledWinHeight;
		RingOverlayIconEnum iconOverlay;

		scaledWinWidth  = w->attrib.width  * rw->scale;
		scaledWinHeight = w->attrib.height * rw->scale;

		if (!w->texture->pixmap)
		    iconOverlay = OverlayIconBig;
		else
		    iconOverlay = ringGetOverlayIcon (s);

	    	switch (iconOverlay) {
    		case OverlayIconNone:
		case OverlayIconEmblem:
		    scale = (rw->slot) ? rw->slot->depthScale : 1.0f;
		    scale = MIN ((scale * ICON_SIZE / icon->width),
				 (scale * ICON_SIZE / icon->height));
		    break;
		case OverlayIconBig:
		default:
		    if (w->texture->pixmap)
		    {
			/* only change opacity if not painting an
			   icon for a minimized window */
			sAttrib.opacity /= 3;
			scale = MIN (((float) scaledWinWidth / icon->width),
				     ((float) scaledWinHeight / icon->height));
		    }
		    else
		    {
			scale =
			    0.8f * ((rw->slot) ? rw->slot->depthScale : 1.0f);
			scale = MIN ((scale * ringGetThumbWidth (s) /
				      icon->width),
				     (scale * ringGetThumbHeight (s) /
				      icon->height));
		    }
		    break;
		}

		width  = icon->width  * scale;
		height = icon->height * scale;

	    	switch (iconOverlay) {
		case OverlayIconNone:
		case OverlayIconEmblem:
		    x = w->attrib.x + scaledWinWidth - width;
		    y = w->attrib.y + scaledWinHeight - height;
		    break;
		case OverlayIconBig:
		default:
		    x = w->attrib.x + scaledWinWidth / 2 - width / 2;
		    y = w->attrib.y + scaledWinHeight / 2 - height / 2;
		    break;
		}

		x += rw->tx;
		y += rw->ty;

		mask |=
		    PAINT_WINDOW_BLEND_MASK | PAINT_WINDOW_TRANSFORMED_MASK;

		iconReg.rects    = &iconReg.extents;
		iconReg.numRects = 1;

		iconReg.extents.x1 = w->attrib.x;
		iconReg.extents.y1 = w->attrib.y;
		iconReg.extents.x2 = w->attrib.x + icon->width;
		iconReg.extents.y2 = w->attrib.y + icon->height;

		matrix = icon->texture.matrix;
		matrix.x0 -= (w->attrib.x * icon->texture.matrix.xx);
		matrix.y0 -= (w->attrib.y * icon->texture.matrix.yy);

		w->vCount = w->indexCount = 0;
		(*w->screen->addWindowGeometry) (w, &matrix, 1,
	    					 &iconReg, &infiniteRegion);

		if (w->vCount)
		{
		    FragmentAttrib fragment;
		    CompTransform  wTransform = *transform;

		    if (!w->texture->pixmap)
			sAttrib.opacity = w->paint.opacity;

		    initFragmentAttrib (&fragment, &sAttrib);

		    if (rw->slot)
			fragment.brightness = (float) fragment.brightness * 
			                      rw->slot->depthBrightness;

		    matrixTranslate (&wTransform, 
				     w->attrib.x, w->attrib.y, 0.0f);
		    matrixScale (&wTransform, scale, scale, 1.0f);
		    matrixTranslate (&wTransform,
				     (x - w->attrib.x) / scale - w->attrib.x,
				     (y - w->attrib.y) / scale - w->attrib.y,
				     0.0f);

		    glPushMatrix ();
		    glLoadMatrixf (wTransform.m);

		    (*w->screen->drawWindowTexture) (w, &icon->texture,
						     &fragment, mask);

		    glPopMatrix ();
		}
	    }
	}
    }
    else
    {
	UNWRAP (rs, s, paintWindow);
	status = (*s->paintWindow) (w, attrib, transform, region, mask);
	WRAP (rs, s, paintWindow, ringPaintWindow);
    }

    return status;
}