#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); } }