rendered paste body#include "group.h"
/*
* groupHandleChanges
*
*/
void
groupHandleChanges(CompScreen* s)
{
int i;
GROUP_DISPLAY(s->display);
GROUP_SCREEN(s);
GroupSelection *group;
CompWindow* w;
for(group = gd->groups; group; group = group ? group->next : NULL)
{
// Ungroup
if (group->prev)
{
if (group->prev->ungroup && !group->prev->animationSteps)
groupDeleteGroup(s->display, group->prev);
}
if (!group->next) {
if (group->ungroup && !group->animationSteps) {
groupDeleteGroup(s->display, group);
group = NULL;
continue;
}
}
if (group->animated && group->animationSteps != 0)
{
if(group->topTab == -1 && group->prevTopTab != -1) //Untab
{
//no need to commit changes, we already did in groupUntabGroup.
for(i = 0; i < group->nWins; i++) {
w = group->windows[i];
GROUP_WINDOW(w);
if(i == group->prevTopTab || !gw->animate)
continue;
//groupEnqueueMoveNotify (w, group->dx - w->screen->width, group->dy, TRUE);
gs->queued = TRUE;
moveWindow (w, group->dx - w->screen->width, group->dy, FALSE, FALSE);
syncWindowPosition(w);
gs->queued = FALSE;
groupRemoveSkipMasks(w);
}
group->prevTopTab = group->topTab;
group->x = 0;
group->y = 0;
group->dx = 0;
group->dy = 0;
if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b)
damageScreen (s);
}
}
else if (group->animated && group->animationSteps == 0)
{
if(group->topTab != -1) //Tab + addWindowToGroup
{
COMMIT_XY_CHANGES(group);
for(i = 0; i < group->nWins; i++)
{
w = group->windows[i];
GROUP_WINDOW(w);
if (i == group->topTab || !gw->animate)
continue;
//groupEnqueueMoveNotify (w, w->screen->width - group->dx, -group->dy, TRUE);
gs->queued = TRUE;
moveWindow (w, w->screen->width - group->dx, -group->dy, FALSE, FALSE);
syncWindowPosition(w);
gs->queued = FALSE;
groupAddSkipMasks(w);
}
group->prevTopTab = group->topTab;
if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b)
damageScreen (s);
}
//Not animated any more.
group->animated = FALSE;
for(i = 0; i < group->nWins; i++)
{
w = group->windows[i];
GROUP_WINDOW(w);
gw->animate = FALSE;
}
}
else
{
if(group->topTab != group->prevTopTab && group->topTab != -1 && group->prevTopTab != -1) //Change Tab
{
group->dx += PREV_TOP_TAB(group)->attrib.x - group->x;
group->dy += PREV_TOP_TAB(group)->attrib.y - group->y;
CompWindow* topTab = TOP_TAB(group);
CompWindow* prevTopTab = PREV_TOP_TAB(group);
//groupEnqueueMoveNotify (topTab, group->dx - topTab->screen->width, group->dy, TRUE);
gs->queued = TRUE;
moveWindow (topTab, group->dx - topTab->screen->width, group->dy, FALSE, FALSE);
syncWindowPosition(topTab);
gs->queued = FALSE;
groupRemoveSkipMasks(topTab);
activateWindow (topTab);
//groupEnqueueMoveNotify (prevTopTab, prevTopTab->screen->width - group->dx, -group->dy, TRUE);
gs->queued = TRUE;
moveWindow (prevTopTab, prevTopTab->screen->width - group->dx, -group->dy, FALSE, FALSE);
syncWindowPosition(prevTopTab);
gs->queued = FALSE;
groupAddSkipMasks(prevTopTab);
group->x = TOP_TAB(group)->attrib.x;
group->y = TOP_TAB(group)->attrib.y;
group->prevTopTab = group->topTab;
if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b)
damageScreen (s);
}
}
}
}
/*
* groupDrawTabAnimation
*
*/
void groupDrawTabAnimation(CompScreen * s)
{
GROUP_DISPLAY(s->display);
GROUP_SCREEN(s);
int stepX, stepY;
int i;
GroupSelection *group;
for(group = gd->groups; group; group = group->next)
{
if(!group->animated || group->animationSteps == 0)
continue;
for(i = 0; i < group->nWins; i++)
{
CompWindow *cw = group->windows[i];
if(!cw || i == group->topTab || i == group->prevTopTab)
continue;
GROUP_WINDOW(cw);
if (!gw->animate)
continue;
stepX = (gw->destinationX - WIN_X(cw)) / group->animationSteps;
stepY = (gw->destinationY - WIN_Y(cw)) / group->animationSteps;
gs->queued = TRUE;
moveWindow (cw, stepX, stepY, FALSE, FALSE);
gs->queued = FALSE;
if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b)
damageScreen (s);
}
group->animationSteps--;
groupSyncWindows(group);
}
}
/*
* groupTabBarVertices
*
*/
void
groupTabBarVertices(CompScreen *s, int x, int y, int width, int height)
{
GROUP_SCREEN(s);
GROUP_DISPLAY(s->display);
int i;
int border_radius = gs->opt[GROUP_SCREEN_OPTION_BORDER_RADIUS].value.i;
for (i = 0; i < NUM_CORNER_POINTS; i++)
glVertex2f(border_radius * gd->cornerPointsX[i] + x +
width - border_radius,
-border_radius * gd->cornerPointsY[i] +
border_radius + y);
for (i = NUM_CORNER_POINTS - 1; i >= 0; i--)
glVertex2f(-border_radius * gd->cornerPointsX[i] + x +
border_radius,
-border_radius * gd->cornerPointsY[i] +
border_radius + y);
for (i = 0; i < NUM_CORNER_POINTS; i++)
glVertex2f(-border_radius * gd->cornerPointsX[i] + x +
border_radius,
border_radius * gd->cornerPointsY[i] + y +
height - border_radius);
for (i = NUM_CORNER_POINTS - 1; i >= 0; i--)
glVertex2f(border_radius * gd->cornerPointsX[i] + x +
width - border_radius,
border_radius * gd->cornerPointsY[i] + y +
height - border_radius);
}
/*
* groupPaintThumb - taken from switcher and modified for tab bar
*
*/
void groupPaintThumb(GroupSelection *group, GroupTabBarSlot *slot)
{
CompWindow *w = slot->window;
CompWindow *topTab = TOP_TAB(group);
int tw, th, tx, ty;
tw = slot->width;
th = slot->height;
tx = slot->rx + group->tabBar->rx + WIN_X(topTab);
ty = slot->ry + group->tabBar->ry + WIN_Y(topTab);
WindowPaintAttrib sAttrib = w->lastPaint;
// animate fade
if (group->tabBar->animationSteps)
{
if (group->tabBar->visible) // fade in
sAttrib.opacity = sAttrib.opacity / group->tabBar->animationSteps;
else // fade out
sAttrib.opacity = sAttrib.opacity - (sAttrib.opacity / group->tabBar->animationSteps);
}
if (w->mapNum) {
if (WIN_WIDTH(w) > tw)
sAttrib.xScale = (float) tw / WIN_WIDTH(w);
else
sAttrib.xScale = 1.0f;
if (WIN_HEIGHT(w) > th)
sAttrib.yScale = (float) tw / WIN_HEIGHT(w);
else
sAttrib.yScale = 1.0f;
if (sAttrib.xScale < sAttrib.yScale)
sAttrib.yScale = sAttrib.xScale;
else
sAttrib.xScale = sAttrib.yScale;
sAttrib.xTranslate = tx - w->attrib.x;
sAttrib.yTranslate = ty - w->attrib.y;
(w->screen->drawWindow) (w, &sAttrib, getInfiniteRegion(),
PAINT_WINDOW_TRANSFORMED_MASK);
addWindowDamage(w);
}
}
/*
* groupPaintTabBar
*
*/
void groupPaintTabBar(GroupSelection * group)
{
if (group->topTab < 0 ||
(!group->tabBar->visible && !group->tabBar->animationSteps))
return;
CompWindow *topTab = group->windows[group->topTab];
CompScreen *s = topTab->screen;
GROUP_SCREEN(s);
if (VIEWPORT(topTab->attrib.x, s))
return;
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_BLEND);
int x1, x2, y1, y2, width, height;
width = group->tabBar->width;
height = group->tabBar->height;
x1 = group->tabBar->rx + WIN_X(topTab);
y1 = group->tabBar->ry + WIN_Y(topTab);
x2 = x1 + width;
y2 = y1 + height;
// fade
int alpha_fill = gs->opt[GROUP_SCREEN_OPTION_TAB_FILL_COLOR].value.c[3];
int alpha_line = gs->opt[GROUP_SCREEN_OPTION_TAB_BORDER_COLOR].value.c[3];
if (group->tabBar->animationSteps) {
// fade in
if (group->tabBar->visible) {
alpha_fill = alpha_fill / group->tabBar->animationSteps;
alpha_line = alpha_line / group->tabBar->animationSteps;
// fade out
} else {
alpha_fill = alpha_fill - (alpha_fill / group->tabBar->animationSteps);
alpha_line = alpha_line - (alpha_line / group->tabBar->animationSteps);
}
}
//glColor4usv(gs->opt[GROUP_SCREEN_OPTION_TAB_FILL_COLOR].value.c);
glColor4us(gs->opt[GROUP_SCREEN_OPTION_TAB_FILL_COLOR].value.c[0],
gs->opt[GROUP_SCREEN_OPTION_TAB_FILL_COLOR].value.c[1],
gs->opt[GROUP_SCREEN_OPTION_TAB_FILL_COLOR].value.c[2],
alpha_fill);
glBegin(GL_POLYGON);
groupTabBarVertices(s, x1, y1, width, height);
glEnd();
//glColor4usv(gs->opt[GROUP_SCREEN_OPTION_TAB_BORDER_COLOR].value.c);
glColor4us(gs->opt[GROUP_SCREEN_OPTION_TAB_BORDER_COLOR].value.c[0],
gs->opt[GROUP_SCREEN_OPTION_TAB_BORDER_COLOR].value.c[0],
gs->opt[GROUP_SCREEN_OPTION_TAB_BORDER_COLOR].value.c[0],
alpha_line);
glBegin(GL_LINE_LOOP);
groupTabBarVertices(s, x1, y1, width, height);
glEnd();
glColor4usv(defaultColor);
glDisable(GL_BLEND);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// draw thumbs
if (gs->opt[GROUP_SCREEN_OPTION_TAB_CREATE_MIPMAPS].value.b)
s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
GroupTabBarSlot *slot;
for(slot = group->tabBar->slots; slot; slot = slot->next)
{
groupPaintThumb(group, slot);
}
if (group->tabBar->animationSteps)
group->tabBar->animationSteps--;
addWindowDamage(topTab);
}
/*
* groupPreparePaintScreen
*
*/
void groupPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
{
GROUP_SCREEN(s);
UNWRAP(gs, s, preparePaintScreen);
(*s->preparePaintScreen) (s, msSinceLastPaint);
WRAP(gs, s, preparePaintScreen, groupPreparePaintScreen);
groupHandleChanges(s);
groupDrawTabAnimation(s);
groupDequeueMoveNotifies (s);
groupDequeueResizeNotifies (s);
groupDequeueGrabNotifies (s);
groupDequeueUngrabNotifies (s);
}
/*
* groupPaintScreen
*
*/
Bool
groupPaintScreen(CompScreen * s,
const ScreenPaintAttrib * sAttrib,
Region region, int output, unsigned int mask)
{
GROUP_SCREEN(s);
GROUP_DISPLAY(s->display);
Bool status;
gs->wasTransformed = FALSE;
// if we draw groups use BTF
if (gd->groups) {
mask &= ~PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK;
mask |= PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK;
}
UNWRAP(gs, s, paintScreen);
status = (*s->paintScreen) (s, sAttrib, region, output, mask);
WRAP(gs, s, paintScreen, groupPaintScreen);
if (status && gs->grab && !gs->wasTransformed) {
int x1, x2, y1, y2;
x1 = MIN(gs->x1, gs->x2);
y1 = MIN(gs->y1, gs->y2);
x2 = MAX(gs->x1, gs->x2);
y2 = MAX(gs->y1, gs->y2);
if (gs->grabIndex) {
glPushMatrix();
prepareXCoords(s, output, -DEFAULT_Z_CAMERA);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_BLEND);
glColor4usv(gs->opt[GROUP_SCREEN_OPTION_SELECTION_COLOR].value.c);
glRecti(x1, y2, x2, y1);
glColor4usv(gs->opt[GROUP_SCREEN_OPTION_LINE_COLOR].value.c);
glBegin(GL_LINE_LOOP);
glVertex2i(x1, y1);
glVertex2i(x2, y1);
glVertex2i(x2, y2);
glVertex2i(x1, y2);
glEnd();
glColor4usv(defaultColor);
glDisable(GL_BLEND);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
}
}
return status;
}
/*
* groupPaintTransformedScreen
*
*/
void
groupPaintTransformedScreen(CompScreen * s, const ScreenPaintAttrib * sa,
Region region, int output, unsigned int mask)
{
GROUP_SCREEN(s);
UNWRAP(gs, s, paintTransformedScreen);
(*s->paintTransformedScreen) (s, sa, region, output, mask);
WRAP(gs, s, paintTransformedScreen, groupPaintTransformedScreen);
if (gs->grab) {
gs->wasTransformed = TRUE;
int x1, x2, y1, y2;
x1 = MIN(gs->x1, gs->x2);
y1 = MIN(gs->y1, gs->y2);
x2 = MAX(gs->x1, gs->x2);
y2 = MAX(gs->y1, gs->y2);
if (gs->grabIndex) {
glPushMatrix();
glLoadIdentity();
(s->applyScreenTransform) (s, sa, output);
prepareXCoords(s, output, -sa->zTranslate);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_BLEND);
glColor4usv(gs->opt[GROUP_SCREEN_OPTION_SELECTION_COLOR].value.c);
glRecti(x1, y2, x2, y1);
glColor4usv(gs->opt[GROUP_SCREEN_OPTION_LINE_COLOR].value.c);
glBegin(GL_LINE_LOOP);
glVertex2i(x1, y1);
glVertex2i(x2, y1);
glVertex2i(x2, y2);
glVertex2i(x1, y2);
glEnd();
glColor4usv(defaultColor);
glDisable(GL_BLEND);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
}
}
}
void groupRecomputeGlow (CompScreen *s)
{
GROUP_SCREEN(s);
CompWindow *w;
for (w = s->windows; w; w = w->next)
groupComputeGlowQuads (w, &gs->glowTexture.matrix);
}
void
groupComputeGlowQuads (CompWindow *w, CompMatrix *matrix)
{
GROUP_WINDOW(w);
GROUP_SCREEN(w->screen);
BoxRec *box;
CompMatrix *quadMatrix;
if (gs->opt[GROUP_SCREEN_OPTION_GLOW].value.b) {
if (!gw->glowQuads)
gw->glowQuads = malloc (NUM_GLOWQUADS * sizeof(GlowQuad));
if (!gw->glowQuads)
return;
} else {
if (gw->glowQuads) {
free (gw->glowQuads);
gw->glowQuads = NULL;
}
return;
}
int glowSize = gs->opt[GROUP_SCREEN_OPTION_GLOW_SIZE].value.i;
int glowOffset = (glowSize * glowTextureProperties[gs->glowType].glowOffset /
glowTextureProperties[gs->glowType].textureSize) + 1;
/* Top left corner */
box = &gw->glowQuads[GLOWQUAD_TOPLEFT].box;
gw->glowQuads[GLOWQUAD_TOPLEFT].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_TOPLEFT].matrix;
box->x1 = WIN_X(w) - w->input.left - glowSize + glowOffset;
box->y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset;
box->x2 = MIN(WIN_X(w) - w->input.left + glowOffset,
WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2));
box->y2 = MIN(WIN_Y(w) - w->input.top + glowOffset,
WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2));
quadMatrix->xx = 1.0f / glowSize;
quadMatrix->yy = -1.0f / glowSize;
quadMatrix->x0 = -(box->x1 * quadMatrix->xx);
quadMatrix->y0 = 1.0 -(box->y1 * quadMatrix->yy);
/* Top right corner */
box = &gw->glowQuads[GLOWQUAD_TOPRIGHT].box;
gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix;
box->x1 = MAX(WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset,
WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2));
box->y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset;
box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset;
box->y2 = MIN(WIN_Y(w) - w->input.top + glowOffset,
WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2));
quadMatrix->xx = -1.0f / glowSize;
quadMatrix->yy = -1.0f / glowSize;
quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx);
quadMatrix->y0 = 1.0 - (box->y1 * quadMatrix->yy);
/* Bottom left corner */
box = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].box;
gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix;
box->x1 = WIN_X(w) - w->input.left - glowSize + glowOffset;
box->y1 = MAX(WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset,
WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2));
box->x2 = MIN(WIN_X(w) - w->input.left + glowOffset,
WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2));
box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset;
quadMatrix->xx = 1.0f / glowSize;
quadMatrix->yy = 1.0f / glowSize;
quadMatrix->x0 = -(box->x1 * quadMatrix->xx);
quadMatrix->y0 = -(box->y1 * quadMatrix->yy);
/* Bottom right corner */
box = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].box;
gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix;
box->x1 = MAX(WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset,
WIN_X(w) - w->input.left + ((WIN_WIDTH(w) + w->input.left + w->input.right) / 2));
box->y1 = MAX(WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset,
WIN_Y(w) - w->input.top + ((WIN_HEIGHT(w) + w->input.top + w->input.bottom) / 2));
box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset;
box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset;
quadMatrix->xx = -1.0f / glowSize;
quadMatrix->yy = 1.0f / glowSize;
quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx);
quadMatrix->y0 = -(box->y1 * quadMatrix->yy);
/* Top edge */
box = &gw->glowQuads[GLOWQUAD_TOP].box;
gw->glowQuads[GLOWQUAD_TOP].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_TOP].matrix;
box->x1 = WIN_X(w) - w->input.left + glowOffset;
box->y1 = WIN_Y(w) - w->input.top - glowSize + glowOffset;
box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset;
box->y2 = WIN_Y(w) - w->input.top + glowOffset;
quadMatrix->xx = 0.0f;
quadMatrix->yy = -1.0f / glowSize;
quadMatrix->x0 = 1.0;
quadMatrix->y0 = 1.0 - (box->y1 * quadMatrix->yy);
/* Bottom edge */
box = &gw->glowQuads[GLOWQUAD_BOTTOM].box;
gw->glowQuads[GLOWQUAD_BOTTOM].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOM].matrix;
box->x1 = WIN_X(w) - w->input.left + glowOffset;
box->y1 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset;
box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset;
box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom + glowSize - glowOffset;
quadMatrix->xx = 0.0f;
quadMatrix->yy = 1.0f / glowSize;
quadMatrix->x0 = 1.0;
quadMatrix->y0 = -(box->y1 * quadMatrix->yy);
/* Left edge */
box = &gw->glowQuads[GLOWQUAD_LEFT].box;
gw->glowQuads[GLOWQUAD_LEFT].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_LEFT].matrix;
box->x1 = WIN_X(w) - w->input.left - glowSize + glowOffset;
box->y1 = WIN_Y(w) - w->input.top + glowOffset;
box->x2 = WIN_X(w) - w->input.left + glowOffset;
box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset;
quadMatrix->xx = 1.0f / glowSize;
quadMatrix->yy = 0.0f;
quadMatrix->x0 = -(box->x1 * quadMatrix->xx);
quadMatrix->y0 = 0.0;
/* Right edge */
box = &gw->glowQuads[GLOWQUAD_RIGHT].box;
gw->glowQuads[GLOWQUAD_RIGHT].matrix = *matrix;
quadMatrix = &gw->glowQuads[GLOWQUAD_RIGHT].matrix;
box->x1 = WIN_X(w) + WIN_WIDTH(w) + w->input.right - glowOffset;
box->y1 = WIN_Y(w) - w->input.top + glowOffset;
box->x2 = WIN_X(w) + WIN_WIDTH(w) + w->input.right + glowSize - glowOffset;
box->y2 = WIN_Y(w) + WIN_HEIGHT(w) + w->input.bottom - glowOffset;
quadMatrix->xx = -1.0f / glowSize;
quadMatrix->yy = 0.0f;
quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx);
quadMatrix->y0 = 0.0;
}
/*
* groupDrawWindow
*
*/
Bool
groupDrawWindow(CompWindow * w,
const WindowPaintAttrib * attrib,
Region region, unsigned int mask)
{
Bool status;
GROUP_WINDOW(w);
GROUP_SCREEN(w->screen);
if (!(mask & PAINT_WINDOW_SOLID_MASK) && gw->inGroup && gw->glowQuads) {
if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
region = getInfiniteRegion();
if (region->numRects) {
REGION box;
int i;
box.rects = &box.extents;
box.numRects = 1;
w->vCount = 0;
for (i = 0; i < NUM_GLOWQUADS; i++) {
box.extents = gw->glowQuads[i].box;
if (box.extents.x1 < box.extents.x2 &&
box.extents.y1 < box.extents.y2) {
(*w->screen->addWindowGeometry) (w,
&gw->glowQuads[i].matrix, 1, &box, region);
}
if (attrib->opacity != gw->oldOpacity)
damageScreenRegion (w->screen, &box);
}
gw->oldOpacity = attrib->opacity;
if (w->vCount) {
WindowPaintAttrib wAttrib = *attrib;
wAttrib.opacity = OPAQUE;
wAttrib.saturation = COLOR;
wAttrib.brightness = BRIGHT;
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4us(gw->group->color[0], gw->group->color[1],
gw->group->color[2], attrib->opacity);
/* we use PAINT_WINDOW_TRANSFORMED_MASK here to force
the usage of a good texture filter */
(*w->screen->drawWindowTexture) (w, &gs->glowTexture, &wAttrib,
mask | PAINT_WINDOW_TRANSLUCENT_MASK | PAINT_WINDOW_TRANSFORMED_MASK);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
screenTexEnvMode (w->screen, GL_REPLACE);
glColor4usv(defaultColor);
}
}
}
UNWRAP(gs, w->screen, drawWindow);
status = (*w->screen->drawWindow) (w, attrib, region, mask);
if (gw->inGroup &&
gw->group->tabbed && gw->group->topTab != -1 &&
TOP_TAB(gw->group)->id == w->id) {
GroupTabBar *bar = gw->group->tabBar;
Bool state = XPointInRegion(w->region, w->screen->display->pointerX, w->screen->display->pointerY) ||
XPointInRegion(bar->region, w->screen->display->pointerX, w->screen->display->pointerY);
if (state != bar->visible) { // state changed, animate
bar->animationSteps = 20;
bar->visible = state;
}
groupPaintTabBar(gw->group);
}
WRAP(gs, w->screen, drawWindow, groupDrawWindow);
return status;
}
/*
* groupPaintWindow
*
*/
Bool
groupPaintWindow(CompWindow * w,
const WindowPaintAttrib * attrib,
Region region, unsigned int mask)
{
Bool status;
GROUP_SCREEN(w->screen);
GROUP_WINDOW(w);
WindowPaintAttrib gAttrib = *attrib;
if (gw->inGroup &&
gw->group->tabbed && gw->group->topTab != -1 &&
!gw->group->animationSteps &&
TOP_TAB(gw->group)->id != w->id) {
return TRUE;
}
if (gw->inSelection) {
int opacity = gs->opt[GROUP_SCREEN_OPTION_OPACITY].value.i;
int saturation = gs->opt[GROUP_SCREEN_OPTION_SATURATION].value.i;
int brightness = gs->opt[GROUP_SCREEN_OPTION_BRIGHTNESS].value.i;
opacity = OPAQUE * opacity / 100;
saturation = COLOR * saturation / 100;
brightness = BRIGHT * brightness / 100;
gAttrib.opacity = opacity;
gAttrib.saturation = saturation;
gAttrib.brightness = brightness;
}
UNWRAP(gs, w->screen, paintWindow);
status = (*w->screen->paintWindow) (w, &gAttrib, region, mask);
WRAP(gs, w->screen, paintWindow, groupPaintWindow);
return status;
}
/*
* groupHandleMotionEvent
*
*/
void groupHandleMotionEvent(CompScreen * s, int xRoot, int yRoot)
{
GROUP_SCREEN(s);
if (gs->grab && gs->grabIndex) {
REGION reg;
reg.rects = ®.extents;
reg.numRects = 1;
reg.extents.x1 = MIN(gs->x1, gs->x2) - 1;
reg.extents.y1 = MIN(gs->y1, gs->y2) - 1;
reg.extents.x2 = MAX(gs->x1, gs->x2) + 1;
reg.extents.y2 = MAX(gs->y1, gs->y2) + 1;
damageScreenRegion(s, ®);
gs->x2 = xRoot;
gs->y2 = yRoot;
reg.extents.x1 = MIN(gs->x1, gs->x2) - 1;
reg.extents.y1 = MIN(gs->y1, gs->y2) - 1;
reg.extents.x2 = MAX(gs->x1, gs->x2) + 1;
reg.extents.y2 = MAX(gs->y1, gs->y2) + 1;
damageScreenRegion(s, ®);
}
}
/*
* reloadCornerPoints
*
*/
void initCornerPoints(GroupDisplay * gd)
{
int i;
float angle;
for (i = 0; i < NUM_CORNER_POINTS; i++) {
angle = (PI / 2) * ((float) i / (NUM_CORNER_POINTS - 1));
gd->cornerPointsY[i] = sin(angle);
gd->cornerPointsX[i] = cos(angle);
}
}