/* Handle the velocity */ static void throwPreparePaintScreen (CompScreen *s, int ms) { CompWindow *w; THROW_SCREEN (s); for (w = s->windows; w; w = w->next) { THROW_WINDOW (w); if (tw->moving) tw->time += ms; tw->xVelocity /= (1.0 + (throwGetFrictionConstant (s) / 100)); tw->yVelocity /= (1.0 + (throwGetFrictionConstant (s) / 100)); if (!tw->moving && ( (tw->xVelocity < 0.0f || tw->xVelocity > 0.0f) || (tw->yVelocity < 0.0f || tw->yVelocity > 0.0))) { int dx = roundf(tw->xVelocity * (ms / 10) * (throwGetVelocityX (s) / 10)); int dy = roundf (tw->yVelocity * (ms / 10) * (throwGetVelocityY (s) / 10)); if (throwGetConstrainX (s)) { if ((WIN_REAL_X (w) + dx) < 0) dx = 0; else if ((WIN_REAL_X (w) + WIN_REAL_W (w) + dx) > w->screen->width) dx = 0; } if (throwGetConstrainY (s)) { if ((WIN_REAL_Y (w) + dy) < 0) dy = 0; else if ((WIN_REAL_Y (w) + WIN_REAL_H (w) + dy) > w->screen->height) dy = 0; } moveWindow (w, dx, dy, TRUE, FALSE); syncWindowPosition (w); } } UNWRAP (ts, s, preparePaintScreen); (*s->preparePaintScreen) (s, ms); WRAP (ts, s, preparePaintScreen, throwPreparePaintScreen); }
/* * groupPaintWindow * */ Bool groupPaintWindow (CompWindow *w, const WindowPaintAttrib *attrib, const CompTransform *transform, Region region, unsigned int mask) { Bool status; Bool doRotate, doTabbing, showTabbar; CompScreen *s = w->screen; GROUP_SCREEN (s); GROUP_WINDOW (w); if (gw->group) { GroupSelection *group = gw->group; doRotate = (group->changeState != NoTabChange) && HAS_TOP_WIN (group) && HAS_PREV_TOP_WIN (group) && (IS_TOP_TAB (w, group) || IS_PREV_TOP_TAB (w, group)); doTabbing = (gw->animateState & (IS_ANIMATED | FINISHED_ANIMATION)) && !(IS_TOP_TAB (w, group) && (group->tabbingState == Tabbing)); showTabbar = group->tabBar && (group->tabBar->state != PaintOff) && (((IS_TOP_TAB (w, group)) && ((group->changeState == NoTabChange) || (group->changeState == TabChangeNewIn))) || (IS_PREV_TOP_TAB (w, group) && (group->changeState == TabChangeOldOut))); } else { doRotate = FALSE; doTabbing = FALSE; showTabbar = FALSE; } if (gw->windowHideInfo) mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK; if (gw->inSelection || gw->resizeGeometry || doRotate || doTabbing || showTabbar) { WindowPaintAttrib wAttrib = *attrib; CompTransform wTransform = *transform; float animProgress = 0.0f; int drawnPosX = 0, drawnPosY = 0; if (gw->inSelection) { const BananaValue * option_select_opacity = bananaGetOption (bananaIndex, "select_opacity", s->screenNum); const BananaValue * option_select_saturation = bananaGetOption (bananaIndex, "select_saturation", s->screenNum); const BananaValue * option_select_brightness = bananaGetOption (bananaIndex, "select_brightness", s->screenNum); wAttrib.opacity = OPAQUE * option_select_opacity->i / 100; wAttrib.saturation = COLOR * option_select_saturation->i / 100; wAttrib.brightness = BRIGHT * option_select_brightness->i / 100; } if (doTabbing) { /* fade the window out */ float progress; int distanceX, distanceY; float origDistance, distance; if (gw->animateState & FINISHED_ANIMATION) { drawnPosX = gw->destination.x; drawnPosY = gw->destination.y; } else { drawnPosX = gw->orgPos.x + gw->tx; drawnPosY = gw->orgPos.y + gw->ty; } distanceX = drawnPosX - gw->destination.x; distanceY = drawnPosY - gw->destination.y; distance = sqrt (pow (distanceX, 2) + pow (distanceY, 2)); distanceX = (gw->orgPos.x - gw->destination.x); distanceY = (gw->orgPos.y - gw->destination.y); origDistance = sqrt (pow (distanceX, 2) + pow (distanceY, 2)); if (!distanceX && !distanceY) progress = 1.0f; else progress = 1.0f - (distance / origDistance); animProgress = progress; progress = MAX (progress, 0.0f); if (gw->group->tabbingState == Tabbing) progress = 1.0f - progress; wAttrib.opacity = (float)wAttrib.opacity * progress; } if (doRotate) { const BananaValue * option_change_animation_time = bananaGetOption (bananaIndex, "change_animation_time", s->screenNum); float timeLeft = gw->group->changeAnimationTime; int animTime = option_change_animation_time->f * 500; if (gw->group->changeState == TabChangeOldOut) timeLeft += animTime; /* 0 at the beginning, 1 at the end */ animProgress = 1 - (timeLeft / (2 * animTime)); } if (gw->resizeGeometry) { int xOrigin, yOrigin; float xScale, yScale; BoxRec box; groupGetStretchRectangle (w, &box, &xScale, &yScale); xOrigin = w->attrib.x - w->input.left; yOrigin = w->attrib.y - w->input.top; matrixTranslate (&wTransform, xOrigin, yOrigin, 0.0f); matrixScale (&wTransform, xScale, yScale, 1.0f); matrixTranslate (&wTransform, (gw->resizeGeometry->x - w->attrib.x) / xScale - xOrigin, (gw->resizeGeometry->y - w->attrib.y) / yScale - yOrigin, 0.0f); mask |= PAINT_WINDOW_TRANSFORMED_MASK; } else if (doRotate || doTabbing) { float animWidth, animHeight; float animScaleX, animScaleY; CompWindow *morphBase, *morphTarget; if (doTabbing) { if (gw->group->tabbingState == Tabbing) { morphBase = w; morphTarget = TOP_TAB (gw->group); } else { morphTarget = w; if (HAS_TOP_WIN (gw->group)) morphBase = TOP_TAB (gw->group); else morphBase = gw->group->lastTopTab; } } else { morphBase = PREV_TOP_TAB (gw->group); morphTarget = TOP_TAB (gw->group); } animWidth = (1 - animProgress) * WIN_REAL_WIDTH (morphBase) + animProgress * WIN_REAL_WIDTH (morphTarget); animHeight = (1 - animProgress) * WIN_REAL_HEIGHT (morphBase) + animProgress * WIN_REAL_HEIGHT (morphTarget); animWidth = MAX (1.0f, animWidth); animHeight = MAX (1.0f, animHeight); animScaleX = animWidth / WIN_REAL_WIDTH (w); animScaleY = animHeight / WIN_REAL_HEIGHT (w); if (doRotate) matrixScale (&wTransform, 1.0f, 1.0f, 1.0f / s->width); matrixTranslate (&wTransform, WIN_REAL_X (w) + WIN_REAL_WIDTH (w) / 2.0f, WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) / 2.0f, 0.0f); if (doRotate) { float rotateAngle = animProgress * 180.0f; if (IS_TOP_TAB (w, gw->group)) rotateAngle += 180.0f; if (gw->group->changeAnimationDirection < 0) rotateAngle *= -1.0f; matrixRotate (&wTransform, rotateAngle, 0.0f, 1.0f, 0.0f); } if (doTabbing) matrixTranslate (&wTransform, drawnPosX - WIN_X (w), drawnPosY - WIN_Y (w), 0.0f); matrixScale (&wTransform, animScaleX, animScaleY, 1.0f); matrixTranslate (&wTransform, -(WIN_REAL_X (w) + WIN_REAL_WIDTH (w) / 2.0f), -(WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) / 2.0f), 0.0f); mask |= PAINT_WINDOW_TRANSFORMED_MASK; } UNWRAP (gs, s, paintWindow); status = (*s->paintWindow)(w, &wAttrib, &wTransform, region, mask); if (showTabbar) groupPaintTabBar (gw->group, &wAttrib, &wTransform, mask, region); WRAP (gs, s, paintWindow, groupPaintWindow); } else { UNWRAP (gs, s, paintWindow); status = (*s->paintWindow)(w, attrib, transform, region, mask); WRAP (gs, s, paintWindow, groupPaintWindow); } return status; }
void groupComputeGlowQuads (CompWindow *w, CompMatrix *matrix) { BoxRec *box; CompMatrix *quadMatrix; int glowSize, glowOffset; int glowType; GROUP_WINDOW (w); const BananaValue * option_glow = bananaGetOption (bananaIndex, "glow", w->screen->screenNum); if (option_glow->b && matrix) { 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; } GROUP_DISPLAY (&display); const BananaValue * option_glow_size = bananaGetOption (bananaIndex, "glow_size", w->screen->screenNum); const BananaValue * option_glow_type = bananaGetOption (bananaIndex, "glow_type", w->screen->screenNum); glowSize = option_glow_size->i; glowType = option_glow_type->i; glowOffset = (glowSize * gd->glowTextureProperties[glowType].glowOffset / gd->glowTextureProperties[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_REAL_X (w) - glowSize + glowOffset; box->y1 = WIN_REAL_Y (w) - glowSize + glowOffset; box->x2 = WIN_REAL_X (w) + glowOffset; box->y2 = WIN_REAL_Y (w) + glowOffset; quadMatrix->xx = 1.0f / glowSize; quadMatrix->yy = -1.0f / glowSize; quadMatrix->x0 = -(box->x1 * quadMatrix->xx); quadMatrix->y0 = 1.0 -(box->y1 * quadMatrix->yy); box->x2 = MIN (WIN_REAL_X (w) + glowOffset, WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2)); box->y2 = MIN (WIN_REAL_Y (w) + glowOffset, WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2)); /* Top right corner */ box = &gw->glowQuads[GLOWQUAD_TOPRIGHT].box; gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix = *matrix; quadMatrix = &gw->glowQuads[GLOWQUAD_TOPRIGHT].matrix; box->x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset; box->y1 = WIN_REAL_Y (w) - glowSize + glowOffset; box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset; box->y2 = WIN_REAL_Y (w) + glowOffset; 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); box->x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset, WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2)); box->y2 = MIN (WIN_REAL_Y (w) + glowOffset, WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2)); /* Bottom left corner */ box = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].box; gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix = *matrix; quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMLEFT].matrix; box->x1 = WIN_REAL_X (w) - glowSize + glowOffset; box->y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset; box->x2 = WIN_REAL_X (w) + glowOffset; box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset; quadMatrix->xx = 1.0f / glowSize; quadMatrix->yy = 1.0f / glowSize; quadMatrix->x0 = -(box->x1 * quadMatrix->xx); quadMatrix->y0 = -(box->y1 * quadMatrix->yy); box->y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset, WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2)); box->x2 = MIN (WIN_REAL_X (w) + glowOffset, WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2)); /* Bottom right corner */ box = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].box; gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix = *matrix; quadMatrix = &gw->glowQuads[GLOWQUAD_BOTTOMRIGHT].matrix; box->x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset; box->y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset; box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset; box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + 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); box->x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset, WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2)); box->y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset, WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2)); /* Top edge */ box = &gw->glowQuads[GLOWQUAD_TOP].box; gw->glowQuads[GLOWQUAD_TOP].matrix = *matrix; quadMatrix = &gw->glowQuads[GLOWQUAD_TOP].matrix; box->x1 = WIN_REAL_X (w) + glowOffset; box->y1 = WIN_REAL_Y (w) - glowSize + glowOffset; box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset; box->y2 = WIN_REAL_Y (w) + 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_REAL_X (w) + glowOffset; box->y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset; box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset; box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + 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_REAL_X (w) - glowSize + glowOffset; box->y1 = WIN_REAL_Y (w) + glowOffset; box->x2 = WIN_REAL_X (w) + glowOffset; box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - 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_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset; box->y1 = WIN_REAL_Y (w) + glowOffset; box->x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset; box->y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset; quadMatrix->xx = -1.0f / glowSize; quadMatrix->yy = 0.0f; quadMatrix->x0 = 1.0 - (box->x1 * quadMatrix->xx); quadMatrix->y0 = 0.0; }
/* Handle Rotation */ static void FWHandleRotateMotionEvent (CompWindow *w, float dx, float dy, int x, int y) { FREEWINS_WINDOW (w); FREEWINS_DISPLAY (w->screen->display); x -= 100; y -= 100; int oldX = lastPointerX - 100; int oldY = lastPointerY - 100; float midX = WIN_REAL_X(w) + WIN_REAL_W(w)/2.0; float midY = WIN_REAL_Y(w) + WIN_REAL_H(w)/2.0; float angX; float angY; float angZ; /* Save the current angles so we can work with them */ if (freewinsGetSnap (w->screen) || fwd->snap) { angX = fww->transform.unsnapAngX; angY = fww->transform.unsnapAngY; angZ = fww->transform.unsnapAngZ; } else { angX = fww->animate.destAngX; angY = fww->animate.destAngY; angZ = fww->animate.destAngZ; } /* Check for Y axis clicking (Top / Bottom) */ if (pointerY > midY) { /* Check for X axis clicking (Left / Right) */ if (pointerX > midX) fww->corner = CornerBottomRight; else if (pointerX < midX) fww->corner = CornerBottomLeft; } else if (pointerY < midY) { /* Check for X axis clicking (Left / Right) */ if (pointerX > midX) fww->corner = CornerTopRight; else if (pointerX < midX) fww->corner = CornerTopLeft; } float percentFromXAxis = 0.0, percentFromYAxis = 0.0; if (freewinsGetZAxisRotation (w->screen) == ZAxisRotationInterchangable) { /* Trackball rotation was too hard to implement. If anyone can implement it, * please come forward so I can replace this hacky solution to the problem. * Anyways, what happens here, is that we determine how far away we are from * each axis (y and x). The further we are away from the y axis, the more * up / down movements become Z axis movements and the further we are away from * the x-axis, the more left / right movements become z rotations. */ /* We determine this by taking a percentage of how far away the cursor is from * each axis. We divide the 3D rotation by this percentage ( and divide by the * percentage squared in order to ensure that rotation is not too violent when we * are quite close to the origin. We multiply the 2D rotation by this percentage also * so we are essentially rotating in 3D and 2D all the time, but this is only really * noticeable when you move the cursor over to the extremes of a window. In every case * percentage can be defined as decimal-percentage (i.e 0.036 == 3.6%). Like I mentioned * earlier, if you can replace this with trackball rotation, please come forward! */ float halfWidth = WIN_REAL_W (w) / 2.0f; float halfHeight = WIN_REAL_H (w) / 2.0f; float distFromXAxis = fabs (fww->iMidX - pointerX); float distFromYAxis = fabs (fww->iMidY - pointerY); percentFromXAxis = distFromXAxis / halfWidth; percentFromYAxis = distFromYAxis / halfHeight; } else if (freewinsGetZAxisRotation (w->screen) == ZAxisRotationSwitch) FWDetermineZAxisClick (w, pointerX, pointerY, TRUE); dx *= 360; dy *= 360; /* Handle inversion */ Bool can2D = fww->can2D, can3D = fww->can3D; if (fwd->invert && freewinsGetZAxisRotation (w->screen) != ZAxisRotationInterchangable) { can2D = !fww->can2D; can3D = !fww->can3D; } if(can2D) { float zX = 1.0f; float zY = 1.0f; if (freewinsGetZAxisRotation (w->screen) == ZAxisRotationInterchangable) { zX = percentFromXAxis; zY = percentFromYAxis; } zX = zX > 1.0f ? 1.0f : zX; zY = zY > 1.0f ? 1.0f : zY; switch (fww->corner) { case CornerTopRight: if ((x) < oldX) angZ -= dx * zX; else if ((x) > oldX) angZ += dx * zX; if ((y) < oldY) angZ -= dy * zY; else if ((y) > oldY) angZ += dy * zY; break; case CornerTopLeft: if ((x) < oldX) angZ -= dx * zX; else if ((x) > oldX) angZ += dx * zX; if ((y) < oldY) angZ += dy * zY; else if ((y) > oldY) angZ -= dy * zY; break; case CornerBottomLeft: if ((x) < oldX) angZ += dx * zX; else if ((x) > oldX) angZ -= dx * zX; if ((y) < oldY) angZ += dy * zY; else if ((y) > oldY) angZ -= dy * zY; break; case CornerBottomRight: if ((x) < oldX) angZ += dx * zX; else if ((x) > oldX) angZ -= dx * zX; if ((y) < oldY) angZ -= dy * zY; else if ((y) > oldY) angZ += dy * zY; break; } } if (can3D) { if (freewinsGetZAxisRotation (w->screen) != ZAxisRotationInterchangable) { percentFromXAxis = 0.0f; percentFromYAxis = 0.0f; } angX -= dy * (1 - percentFromXAxis); angY += dx * (1 - percentFromYAxis); } /* Restore angles */ if (freewinsGetSnap (w->screen) || fwd->snap) { fww->transform.unsnapAngX = angX; fww->transform.unsnapAngY = angY; fww->transform.unsnapAngZ = angZ; } else { fww->animate.destAngX = angX; fww->animate.destAngY = angY; fww->animate.destAngZ = angZ; } FWHandleSnap(w); }