Exemplo n.º 1
0
void
ExpandAnim::applyTransform ()
{
    GLMatrix *transform = &mTransform;
    float defaultXScale = 0.3f;
    float forwardProgress;
    float expandProgress;
    const float expandPhaseEnd = 0.5f;

    forwardProgress = getProgress ();

    if ((1 - forwardProgress) < expandPhaseEnd)
	expandProgress = (1 - forwardProgress) / expandPhaseEnd;
    else
	expandProgress = 1.0f;

    // animation movement
    transform->translate (WIN_X (mWindow) + WIN_W (mWindow) / 2.0f,
			  WIN_Y (mWindow) + WIN_H (mWindow) / 2.0f,
			  0.0f); 

    transform->scale (defaultXScale + (1.0f - defaultXScale) *
		      expandProgress,
		      (1 - forwardProgress), 0.0f);

    transform->translate (-(WIN_X (mWindow) + WIN_W (mWindow) / 2.0f),
		      	  -(WIN_Y (mWindow) + WIN_H (mWindow) / 2.0f),
		      	  0.0f);

}
static void
getZoomCenterScaleFull (CompWindow *w,
			Point *pCurCenter, Point *pCurScale,
			Point *pWinCenter, Point *pIconCenter,
			float *pRotateProgress)
{
    ANIM_WINDOW(w);

    Point winCenter =
	{(WIN_X(w) + WIN_W(w) / 2.0),
	 (WIN_Y(w) + WIN_H(w) / 2.0)};
    Point iconCenter =
	{aw->com.icon.x + aw->com.icon.width / 2.0,
	 aw->com.icon.y + aw->com.icon.height / 2.0};
    Point winSize =
	{WIN_W(w), WIN_H(w)};
    winSize.x = (winSize.x == 0 ? 1 : winSize.x);
    winSize.y = (winSize.y == 0 ? 1 : winSize.y);

    float scaleProgress;
    float moveProgress;
    float rotateProgress = 0;

    if (aw->com.curAnimEffect == AnimEffectSidekick)
    {
	fxZoomAnimProgress (w, &moveProgress, &scaleProgress, FALSE);
	rotateProgress = moveProgress;
    }
    else if (aw->com.curAnimEffect == AnimEffectZoom)
    {
	fxZoomAnimProgress (w, &moveProgress, &scaleProgress, FALSE);
    }
    else
    {
	// other effects use this for minimization
	fxZoomAnimProgress (w, &moveProgress, &scaleProgress, TRUE);
    }

    Point curCenter =
	{(1 - moveProgress) * winCenter.x + moveProgress * iconCenter.x,
	 (1 - moveProgress) * winCenter.y + moveProgress * iconCenter.y};
    Point curScale =
	{((1 - scaleProgress) * winSize.x + scaleProgress * aw->com.icon.width) /
	 winSize.x,
	 ((1 - scaleProgress) * winSize.y + scaleProgress * aw->com.icon.height) /
	 winSize.y};

    // Copy calculated variables
    if (pCurCenter)
	*pCurCenter = curCenter;
    if (pCurScale)
	*pCurScale = curScale;
    if (pWinCenter)
	*pWinCenter = winCenter;
    if (pIconCenter)
	*pIconCenter = iconCenter;
    if (pRotateProgress)
	*pRotateProgress = rotateProgress;
}
Exemplo n.º 3
0
static void inline
fxRollUpModelStepObject(CompWindow * w,
			Model * model,
			Object * object,
			float forwardProgress, Bool fixedInterior)
{
	ANIM_WINDOW(w);

	float origx = WIN_X(w) + WIN_W(w) * object->gridPosition.x;

	if (aw->com.curWindowEvent == WindowEventShade ||
	    aw->com.curWindowEvent == WindowEventUnshade) {
		// Execute shade mode

		// find position in window contents
		// (window contents correspond to 0.0-1.0 range)
		float relPosInWinContents =
		    (object->gridPosition.y * WIN_H(w) -
		     model->topHeight) / w->height;

		if (object->gridPosition.y == 0) {
			object->position.x = origx;
			object->position.y = WIN_Y(w);
		} else if (object->gridPosition.y == 1) {
			object->position.x = origx;
			object->position.y =
			    (1 - forwardProgress) *
			    (WIN_Y(w) +
			     WIN_H(w) * object->gridPosition.y) +
			    forwardProgress * (WIN_Y(w) +
					       model->topHeight +
					       model->bottomHeight);
		} else {
			object->position.x = origx;

			if (relPosInWinContents > forwardProgress) {
				object->position.y =
				    (1 - forwardProgress) *
				    (WIN_Y(w) +
				     WIN_H(w) * object->gridPosition.y) +
				    forwardProgress * (WIN_Y(w) +
						       model->topHeight);

				if (fixedInterior)
					object->offsetTexCoordForQuadBefore.y =
					    -forwardProgress * w->height;
			} else {
				object->position.y =
				    WIN_Y(w) + model->topHeight;
				if (!fixedInterior)
					object->offsetTexCoordForQuadAfter.y =
					    (forwardProgress -
					     relPosInWinContents) * w->height;
			}
		}
	}
}
Exemplo n.º 4
0
/* Fiil FB Info. */
static int win_fb_info_setup(struct jz_fb_win_info *win)
{
	struct jz_fb_ctrl *ctrl = win->ctrl;

	int rv;

	strcpy(win->fb.fix.id, DRV_NAME);

	win->fb.fix.type		   = FB_TYPE_PACKED_PIXELS;
	win->fb.fix.type_aux		   = 0;
	win->fb.fix.xpanstep		   = 0;
	win->fb.fix.ypanstep		   = 1;
	win->fb.fix.ywrapstep		   = 0;
	win->fb.fix.accel		   = FB_ACCEL_NONE;

	win->fb.fbops			   = &jz_fb_ops;
	win->fb.flags			   = FBINFO_FLAG_DEFAULT;

	win->fb.var.nonstd		   = 0;
	win->fb.var.activate		   = FB_ACTIVATE_NOW;
	win->fb.var.accel_flags		   = 0;
	win->fb.var.vmode                  = FB_VMODE_NONINTERLACED;

	win->fb.var.xres                   = WIN_W(win);
	win->fb.var.yres                   = WIN_H(win);
	win->fb.var.xres_virtual           = WIN_W(win);
	win->fb.var.yres_virtual           = WIN_H(win);
	win->fb.var.bits_per_pixel	   = WIN_BPP(win);
	win->fb.var.xoffset                = 0;
	win->fb.var.yoffset                = 0;

	win->fb.var.pixclock               = ctrl->pixclock;

	win->fb.var.left_margin            = 0;
	win->fb.var.right_margin           = 0;
	win->fb.var.upper_margin           = 0;
	win->fb.var.lower_margin           = 0;
	win->fb.var.hsync_len              = 0;
	win->fb.var.vsync_len              = 0;
	win->fb.var.sync                   = 0;

	win->fb.pseudo_palette		   = (void *)(win + 1);

	rv = fb_info_set_color(&win->fb);
	if (rv) {
		return rv;
	}

	return rv;
}
Exemplo n.º 5
0
/*
 * Call the previous function for each of the 4 sides of the window
 */
static void snapMoveCheckEdges(CompWindow * w)
{
	snapMoveCheckNearestEdge(w, WIN_X(w),
							 WIN_Y(w), WIN_Y(w) + WIN_H(w),
							 TRUE, RightEdge, HorizontalSnap);
	snapMoveCheckNearestEdge(w, WIN_X(w) + WIN_W(w),
							 WIN_Y(w), WIN_Y(w) + WIN_H(w),
							 FALSE, LeftEdge, HorizontalSnap);
	snapMoveCheckNearestEdge(w, WIN_Y(w),
							 WIN_X(w), WIN_X(w) + WIN_W(w),
							 TRUE, BottomEdge, VerticalSnap);
	snapMoveCheckNearestEdge(w, WIN_Y(w) + WIN_H(w),
							 WIN_X(w), WIN_X(w) + WIN_W(w),
							 FALSE, TopEdge, VerticalSnap);
}
static void
fxDodgeProcessSubject (CompWindow *wCur,
		       Region wRegion,
		       Region dodgeRegion,
		       Bool alwaysInclude)
{
    XRectangle rect;
    rect.x = WIN_X(wCur);
    rect.y = WIN_Y(wCur);
    rect.width = WIN_W(wCur);
    rect.height = WIN_H(wCur);
    Region wCurRegion = XCreateRegion();
    if (!wCurRegion)
	return;

    XUnionRectWithRegion(&rect, &emptyRegion, wCurRegion);
    if (!alwaysInclude)
    {
	Region intersectionRegion = XCreateRegion();
	if (intersectionRegion)
	{
	    XIntersectRegion(wRegion, wCurRegion,
			     intersectionRegion);
	    if (!XEmptyRegion(intersectionRegion))
		XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion);
	    XDestroyRegion (intersectionRegion);
	}
    }
    else
	XUnionRegion(dodgeRegion, wCurRegion, dodgeRegion);

    XDestroyRegion (wCurRegion);
}
Bool
fxZoomInit (CompWindow * w)
{
    ANIM_WINDOW(w);

    if ((aw->com.curAnimEffect == AnimEffectSidekick &&
	 (animGetI (w, ANIM_SCREEN_OPTION_SIDEKICK_ZOOM_FROM_CENTER) ==
	  ZoomFromCenterOn ||
	  ((aw->com.curWindowEvent == WindowEventMinimize ||
	    aw->com.curWindowEvent == WindowEventUnminimize) &&
	   animGetI (w, ANIM_SCREEN_OPTION_SIDEKICK_ZOOM_FROM_CENTER) ==
	   ZoomFromCenterMin) ||
	  ((aw->com.curWindowEvent == WindowEventOpen ||
	    aw->com.curWindowEvent == WindowEventClose) &&
	   animGetI (w, ANIM_SCREEN_OPTION_SIDEKICK_ZOOM_FROM_CENTER) ==
	   ZoomFromCenterCreate))) ||
	(aw->com.curAnimEffect == AnimEffectZoom &&
	 (animGetI (w, ANIM_SCREEN_OPTION_ZOOM_FROM_CENTER) ==
	  ZoomFromCenterOn ||
	  ((aw->com.curWindowEvent == WindowEventMinimize ||
	    aw->com.curWindowEvent == WindowEventUnminimize) &&
	   animGetI (w, ANIM_SCREEN_OPTION_ZOOM_FROM_CENTER) ==
	   ZoomFromCenterMin) ||
	  ((aw->com.curWindowEvent == WindowEventOpen ||
	    aw->com.curWindowEvent == WindowEventClose) &&
	   animGetI (w, ANIM_SCREEN_OPTION_ZOOM_FROM_CENTER) ==
	   ZoomFromCenterCreate))))
    {
	aw->com.icon.x =
	    WIN_X(w) + WIN_W(w) / 2 - aw->com.icon.width / 2;
	aw->com.icon.y =
	    WIN_Y(w) + WIN_H(w) / 2 - aw->com.icon.height / 2;
    }

    // allow extra time for spring damping / deceleration
    if ((aw->com.curWindowEvent == WindowEventUnminimize ||
	 aw->com.curWindowEvent == WindowEventOpen) &&
	fxZoomGetSpringiness (w) > 1e-4)
    {
	aw->com.animTotalTime /= SPRINGY_ZOOM_PERCEIVED_T;
    }
    else if ((aw->com.curAnimEffect == AnimEffectZoom ||
	      aw->com.curAnimEffect == AnimEffectSidekick) &&
	     (aw->com.curWindowEvent == WindowEventOpen ||
	      aw->com.curWindowEvent == WindowEventClose))
    {
	aw->com.animTotalTime /= NONSPRINGY_ZOOM_PERCEIVED_T;
    }
    else
    {
	aw->com.animTotalTime /= ZOOM_PERCEIVED_T;
    }
    aw->com.animRemainingTime = aw->com.animTotalTime;

    aw->com.usingTransform = TRUE;

    return defaultAnimInit (w);
}
Exemplo n.º 8
0
static double
layoutOrganicCalculateOverlap(CompScreen * s, int win, int x, int y)
{
	int i;
	int x1, y1, x2, y2;
	int overlapX, overlapY;
	int xMin, xMax, yMin, yMax;
	double result = -0.01;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	x1 = x;
	y1 = y;
	x2 = x1 + WIN_W(ss->windows[win]) * as->scale;
	y2 = y1 + WIN_H(ss->windows[win]) * as->scale;

	for (i = 0; i < ss->nWindows; i++) {
		if (i == win)
			continue;

		overlapX = overlapY = 0;
		xMax = MAX(ss->slots[i].x1, x1);
		xMin =
		    MIN(ss->slots[i].x1 + WIN_W(ss->windows[i]) * as->scale,
			x2);
		if (xMax <= xMin)
			overlapX = xMin - xMax;

		yMax = MAX(ss->slots[i].y1, y1);
		yMin =
		    MIN(ss->slots[i].y1 + WIN_H(ss->windows[i]) * as->scale,
			y2);

		if (yMax <= yMin)
			overlapY = yMin - yMax;

		result += (double)overlapX *overlapY;
	}

	return result;
}
Exemplo n.º 9
0
static void inline
fxHorizontalFoldsModelStepObject(CompWindow * w,
				 Model * model,
				 Object * object,
				 float forwardProgress,
				 float sinForProg, float foldMaxAmp, int rowNo)
{
	ANIM_WINDOW(w);

	float origx = w->attrib.x + (WIN_W(w) * object->gridPosition.x -
				     w->output.left) * model->scale.x;
	float origy = w->attrib.y + (WIN_H(w) * object->gridPosition.y -
				     w->output.top) * model->scale.y;

	object->position.x = origx;

	if (aw->com.curWindowEvent == WindowEventShade ||
	    aw->com.curWindowEvent == WindowEventUnshade) {
		// Execute shade mode

		float relDistToFoldCenter = (rowNo % 2 == 1 ? 0.5 : 0);

		if (object->gridPosition.y == 0) {
			object->position.y = WIN_Y(w);
			object->position.z = 0;
		} else if (object->gridPosition.y == 1) {
			object->position.y =
			    (1 - forwardProgress) * origy +
			    forwardProgress *
			    (WIN_Y(w) + model->topHeight + model->bottomHeight);
			object->position.z = 0;
		} else {
			object->position.y =
			    (1 - forwardProgress) * origy +
			    forwardProgress * (WIN_Y(w) + model->topHeight);
			object->position.z =
			    getObjectZ(model, forwardProgress, sinForProg,
				       relDistToFoldCenter, foldMaxAmp);
		}
	} else {
		// Execute normal mode

		float relDistToFoldCenter;

		relDistToFoldCenter = (rowNo % 2 == 0 ? 0.5 : 0);

		object->position.y =
		    (1 - forwardProgress) * origy +
		    forwardProgress * (BORDER_Y(w) + BORDER_H(w) / 2.0);
		object->position.z =
		    getObjectZ(model, forwardProgress, sinForProg,
			       relDistToFoldCenter, foldMaxAmp);
	}
}
Exemplo n.º 10
0
Arquivo: dream.c Projeto: Elive/ecomp
static void
fxDreamModelStepObject(CompWindow *w,
                       Model *model, Object *object, float forwardProgress)
{
   float waveAmpMax = MIN(WIN_H(w), WIN_W(w)) * 0.125f;
   float waveWidth = 10.0f;
   float waveSpeed = 7.0f;

   float origx = w->attrib.x + (WIN_W(w) * object->gridPosition.x -
                                w->output.left) * model->scale.x;
   float origy = w->attrib.y + (WIN_H(w) * object->gridPosition.y -
                                w->output.top) * model->scale.y;

   object->position.y = origy;
   object->position.x =
     origx +
     forwardProgress *waveAmpMax *model->scale.x *
     sin(object->gridPosition.y *M_PI *waveWidth +
         waveSpeed *forwardProgress);
}
static void
layoutOrganicRemoveOverlap (CompScreen *s,
                            int        areaWidth,
                            int        areaHeight)
{
    int        i, spacing;
    CompWindow *w;

    SCALE_SCREEN (s);
    ADDON_SCREEN (s);

    spacing = ss->opt[SCALE_SCREEN_OPTION_SPACING].value.i;

    while (layoutOrganicLocalSearch (s, areaWidth, areaHeight))
    {
        for (i = 0; i < ss->nWindows; i++)
        {
            int centerX, centerY;
            int newX, newY, newWidth, newHeight;

            w = ss->windows[i];

            centerX = ss->slots[i].x1 + WIN_W (w) / 2;
            centerY = ss->slots[i].y1 + WIN_H (w) / 2;

            newWidth = (int)((1.0 - ORGANIC_STEP) *
                             (double)WIN_W (w)) - spacing / 2;
            newHeight = (int)((1.0 - ORGANIC_STEP) *
                              (double)WIN_H (w)) - spacing / 2;
            newX = centerX - (newWidth / 2);
            newY = centerY - (newHeight / 2);

            ss->slots[i].x1 = newX;
            ss->slots[i].y1 = newY;
            ss->slots[i].x2 = newX + WIN_W (w);
            ss->slots[i].y2 = newY + WIN_H (w);
        }
        as->scale -= ORGANIC_STEP;
    }
}
Exemplo n.º 12
0
Arquivo: glide.c Projeto: Elive/ecomp
static void
applyGlideTransform(CompWindow *w, CompTransform *transform)
{
   ANIM_SCREEN(w->screen);
   ANIM_WINDOW(w);

   float finalDistFac;
   float finalRotAng;
   float thickness;

   fxGlideGetParams(as, aw, &finalDistFac, &finalRotAng, &thickness);

   float forwardProgress;
   if (fxGlideZoomToTaskBar(as, aw))
     {
        float dummy;
        fxZoomAnimProgress(as, aw, &forwardProgress, &dummy, TRUE);
     }
   else
     forwardProgress = fxGlideAnimProgress(aw);

   float finalz = finalDistFac * 0.8 * DEFAULT_Z_CAMERA *
     w->screen->width;

   Vector3d rotAxis = {1, 0, 0};
   Point3d rotAxisOffset =
   {WIN_X(w) + WIN_W(w) / 2.0f,
    WIN_Y(w) + WIN_H(w) / 2.0f,
    0};
   Point3d translation = {0, 0, finalz * forwardProgress};

   float rotAngle = finalRotAng * forwardProgress;
   aw->glideModRotAngle = fmodf(rotAngle + 720, 360.0f);

   // put back to window position
   matrixTranslate (transform, rotAxisOffset.x, rotAxisOffset.y, 0);

   resetAndPerspectiveDistortOnZ (transform, -1.0 / w->screen->width);

   // animation movement
   matrixTranslate (transform, translation.x, translation.y, translation.z);

   // animation rotation
   matrixRotate (transform, rotAngle, rotAxis.x, rotAxis.y, rotAxis.z);

   // intentional scaling of z by 0 to prevent weird opacity results and
   // flashing that happen when z coords are between 0 and 1 (bug in ecomp?)
   matrixScale (transform, 1.0f, 1.0f, 0.0f);

   // place window rotation axis at origin
   matrixTranslate (transform, -rotAxisOffset.x, -rotAxisOffset.y, 0);
}
Exemplo n.º 13
0
static void scaleaddonDrawWindowTitle(CompWindow * w)
{
	float x, y, width, height;
	CompScreen *s = w->screen;

	SCALE_WINDOW(w);
	ADDON_WINDOW(w);
	ADDON_DISPLAY(s->display);

	width = aw->textData->width;
	height = aw->textData->height;

	x = sw->tx + w->attrib.x + ((WIN_W(w) * sw->scale) / 2) - (width / 2);
	y = sw->ty + w->attrib.y + ((WIN_H(w) * sw->scale) / 2) - (height / 2);

	(ad->textFunc->drawText) (s, aw->textData, floor(x), floor(y), 1.0f);
}
static void
scaleaddonDrawWindowHighlight (CompWindow *w)
{
    GLboolean  wasBlend;
    GLint      oldBlendSrc, oldBlendDst;
    float      x, y, width, height;
    CompScreen *s = w->screen;

    SCALE_WINDOW (w);
    ADDON_WINDOW (w);

    if (aw->rescaled)
        return;

    x      = sw->tx + w->attrib.x - (w->input.left * sw->scale);
    y      = sw->ty + w->attrib.y - (w->input.top * sw->scale);
    width  = WIN_W (w) * sw->scale;
    height = WIN_H (w) * sw->scale;

    /* we use a poor replacement for roundf()
     * (available in C99 only) here */
    x = floor (x + 0.5f);
    y = floor (y + 0.5f);

    wasBlend = glIsEnabled (GL_BLEND);
    glGetIntegerv (GL_BLEND_SRC, &oldBlendSrc);
    glGetIntegerv (GL_BLEND_DST, &oldBlendDst);

    if (!wasBlend)
        glEnable (GL_BLEND);

    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glColor4us (scaleaddonGetHighlightColorRed (s),
                scaleaddonGetHighlightColorGreen (s),
                scaleaddonGetHighlightColorBlue (s),
                scaleaddonGetHighlightColorAlpha (s));

    glRectf (x, y + height, x + width, y);

    glColor4usv (defaultColor);

    if (!wasBlend)
        glDisable (GL_BLEND);
    glBlendFunc (oldBlendSrc, oldBlendDst);
}
Exemplo n.º 15
0
Bool
fxCurvedFoldModelStep(CompScreen *s, CompWindow *w, float time)
{
    if (!defaultAnimStep(s, w, time))
        return FALSE;

    ANIM_SCREEN(s);
    ANIM_WINDOW(w);

    Model *model = aw->model;

    float forwardProgress;
    if ((aw->curWindowEvent == WindowEventMinimize ||
            aw->curWindowEvent == WindowEventUnminimize) &&
            animGetB(as, aw, ANIM_SCREEN_OPTION_CURVED_FOLD_Z2TOM))
    {
        float dummy;
        fxZoomAnimProgress(as, aw, &forwardProgress, &dummy, TRUE);
    }
    else
        forwardProgress = defaultAnimProgress(aw);

    float curveMaxAmp =
        animGetF(as, aw, ANIM_SCREEN_OPTION_CURVED_FOLD_AMP) * WIN_W(w) *
        pow(WIN_H(w) / (s->height * 1.2f), 0.7);
    int i;
    for (i = 0; i < model->numObjects; i++)
        fxCurvedFoldModelStepObject
        (w,
         model,
         &model->objects[i],
         forwardProgress,
         curveMaxAmp);

    return TRUE;
}
Exemplo n.º 16
0
/*
 * Detect visible windows edges
 */
static void snapUpdateWindowsEdges(CompWindow * w)
{
	CompWindow *c = NULL;
	Edge *e = NULL, *next = NULL;

	SNAP_WINDOW(w);
	Region edgeRegion, resultRegion;
	XRectangle rect;
	Bool remove = FALSE;

	// First add all the windows
	c = w->screen->windows;
	while (c)
	{
		// Just check that we're not trying to snap to current window,
		// that the window is not invisible and of a valid type
		if (c == w || !isSnapWindow(c))
		{
			c = c->next;
			continue;
		}
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_Y(c), WIN_X(c), WIN_X(c) + WIN_W(c), TopEdge, FALSE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_Y(c) + WIN_H(c), WIN_X(c), WIN_X(c) + WIN_W(c),
					BottomEdge, FALSE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_X(c), WIN_Y(c), WIN_Y(c) + WIN_H(c), LeftEdge, FALSE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, c->id,
					WIN_X(c) + WIN_W(c), WIN_Y(c), WIN_Y(c) + WIN_H(c),
					RightEdge, FALSE);
		c = c->next;
	}

	// Now strip invisible edges
	// Loop through all the windows stack, and through all the edges
	// If an edge has been passed, check if it's in the region window,
	// if the edge is fully under the window, drop it, or if it's only
	// partly covered, cut it/split it in one/two smaller visible edges
	for (c = w->screen->windows; c; c = c->next)
	{
		if (c == w || !isSnapWindow(c))
			continue;
		for (e = sw->edges; e; e = next)
		{
			if (!e->passed)
			{
				if (e->id == c->id)
					e->passed = TRUE;
				next = e->next;
				continue;
			}
			switch (e->type)
			{
				case LeftEdge:
				case RightEdge:
					rect.x = e->position;
					rect.y = e->start;
					rect.width = 1;
					rect.height = e->end - e->start;
					break;
				case TopEdge:
				case BottomEdge:
				default:
					rect.x = e->start;
					rect.y = e->position;
					rect.width = e->end - e->start;
					rect.height = 1;
			}
			// If the edge is in the window region, remove it,
			// if it's partly in the region, split it
			edgeRegion = XCreateRegion();
			resultRegion = XCreateRegion();
			XUnionRectWithRegion(&rect, edgeRegion, edgeRegion);
			XSubtractRegion(edgeRegion, c->region, resultRegion);
			if (XEmptyRegion(resultRegion))
				remove = TRUE;
			else if (!XEqualRegion(edgeRegion, resultRegion))
			{
				snapAddRegionEdges(sw, e, resultRegion);
				remove = TRUE;
			}
			next = e->next;
			if (remove)
			{
				if (e->prev == NULL)
					sw->edges = e->next;
				if (e->next == NULL)
					sw->reverseEdges = e->prev;
				snapRemoveEdge(e);
				remove = FALSE;
			}
			XDestroyRegion(resultRegion);
			XDestroyRegion(edgeRegion);
		}
	}
}
Exemplo n.º 17
0
static Bool layoutOrganicThumbs(CompScreen * s)
{
	CompWindow *w;
	int i, moMode;
	XRectangle workArea;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	moMode = ss->opt[SCALE_SCREEN_OPTION_MULTIOUTPUT_MODE].value.i;

	switch (moMode) {
	case SCALE_MOMODE_ALL:
		workArea = s->workArea;
		break;
	case SCALE_MOMODE_CURRENT:
	default:
		workArea = s->outputDev[s->currentOutputDev].workArea;
		break;
	}

	as->scale = 1.0f;

	qsort(ss->windows, ss->nWindows, sizeof(CompWindow *),
	      organicCompareWindows);

	for (i = 0; i < ss->nWindows; i++) {
		w = ss->windows[i];
		SCALE_WINDOW(w);

		sw->slot = &ss->slots[i];
		ss->slots[i].x1 = WIN_X(w) - workArea.x;
		ss->slots[i].y1 = WIN_Y(w) - workArea.y;
		ss->slots[i].x2 = WIN_X(w) + WIN_W(w) - workArea.x;
		ss->slots[i].y2 = WIN_Y(w) + WIN_H(w) - workArea.y;

		if (ss->slots[i].x1 < 0) {
			ss->slots[i].x2 += abs(ss->slots[i].x1);
			ss->slots[i].x1 = 0;
		}
		if (ss->slots[i].x2 > workArea.width - workArea.x) {
			ss->slots[i].x1 -=
			    abs(ss->slots[i].x2 - workArea.width);
			ss->slots[i].x2 = workArea.width - workArea.x;
		}

		if (ss->slots[i].y1 < 0) {
			ss->slots[i].y2 += abs(ss->slots[i].y1);
			ss->slots[i].y1 = 0;
		}
		if (ss->slots[i].y2 > workArea.height - workArea.y) {
			ss->slots[i].y1 -= abs(ss->slots[i].y2 -
					       workArea.height - workArea.y);
			ss->slots[i].y2 = workArea.height - workArea.y;
		}
	}

	ss->nSlots = ss->nWindows;

	layoutOrganicRemoveOverlap(s, workArea.width - workArea.x,
				   workArea.height - workArea.y);
	for (i = 0; i < ss->nWindows; i++) {
		w = ss->windows[i];
		SCALE_WINDOW(w);

		if (ss->type == ScaleTypeGroup)
			raiseWindow(ss->windows[i]);

		ss->slots[i].x1 += w->input.left + workArea.x;
		ss->slots[i].x2 += w->input.left + workArea.x;
		ss->slots[i].y1 += w->input.top + workArea.y;
		ss->slots[i].y2 += w->input.top + workArea.y;
		sw->adjust = TRUE;
	}

	return TRUE;
}
Exemplo n.º 18
0
static double
layoutOrganicFindBestVerticalPosition(CompScreen * s,
				      int win, int *bestY, int areaHeight)
{
	int i, x1, x2, h;
	double bestOverlap = 1e31, overlap;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	x1 = ss->slots[win].x1;
	x2 = ss->slots[win].x1 + WIN_W(ss->windows[win]) * as->scale;
	h = WIN_H(ss->windows[win]) * as->scale;
	*bestY = ss->slots[win].y1;

	for (i = 0; i < ss->nWindows; i++) {
		CompWindow *w = ss->windows[i];

		if (i == win)
			continue;

		if (ss->slots[i].x1 < x2 &&
		    ss->slots[i].x1 + WIN_W(w) * as->scale > x1) {
			if (ss->slots[i].y1 - h >= 0
			    && ss->slots[i].y1 < areaHeight) {
				overlap =
				    layoutOrganicCalculateOverlap(s, win, x1,
								  ss->slots[i].
								  y1 - h);
				if (overlap < bestOverlap) {
					*bestY = ss->slots[i].y1 - h;
					bestOverlap = overlap;
				}
			}
			if (WIN_H(w) * as->scale + ss->slots[i].y1 > 0 &&
			    WIN_H(w) * as->scale + h + ss->slots[i].y1 <
			    areaHeight) {
				overlap =
				    layoutOrganicCalculateOverlap(s, win, x1,
								  WIN_H(w) *
								  as->scale +
								  ss->slots[i].
								  y1);

				if (overlap < bestOverlap) {
					*bestY =
					    ss->slots[i].y1 +
					    WIN_H(w) * as->scale;
					bestOverlap = overlap;
				}
			}
		}
	}

	overlap = layoutOrganicCalculateOverlap(s, win, x1, 0);
	if (overlap < bestOverlap) {
		*bestY = 0;
		bestOverlap = overlap;
	}

	overlap = layoutOrganicCalculateOverlap(s, win, x1, areaHeight - h);
	if (overlap < bestOverlap) {
		*bestY = areaHeight - h;
		bestOverlap = overlap;
	}

	return bestOverlap;
}
Exemplo n.º 19
0
static double
layoutOrganicFindBestHorizontalPosition(CompScreen * s,
					int win, int *bestX, int areaWidth)
{
	int i, y1, y2, w;
	double bestOverlap = 1e31, overlap;

	SCALE_SCREEN(s);
	ADDON_SCREEN(s);

	y1 = ss->slots[win].y1;
	y2 = ss->slots[win].y1 + WIN_H(ss->windows[win]) * as->scale;

	w = WIN_W(ss->windows[win]) * as->scale;
	*bestX = ss->slots[win].x1;

	for (i = 0; i < ss->nWindows; i++) {
		CompWindow *lw = ss->windows[i];
		if (i == win)
			continue;

		if (ss->slots[i].y1 < y2 &&
		    ss->slots[i].y1 + WIN_H(lw) * as->scale > y1) {
			if (ss->slots[i].x1 - w >= 0) {
				overlap = layoutOrganicCalculateOverlap(s, win,
									ss->
									slots
									[i].x1 -
									w, y1);

				if (overlap < bestOverlap) {
					*bestX = ss->slots[i].x1 - w;
					bestOverlap = overlap;
				}
			}
			if (WIN_W(lw) * as->scale + ss->slots[i].x1 + w <
			    areaWidth) {
				overlap =
				    layoutOrganicCalculateOverlap(s, win,
								  ss->slots[i].
								  x1 +
								  WIN_W(lw) *
								  as->scale,
								  y1);

				if (overlap < bestOverlap) {
					*bestX =
					    ss->slots[i].x1 +
					    WIN_W(lw) * as->scale;
					bestOverlap = overlap;
				}
			}
		}
	}

	overlap = layoutOrganicCalculateOverlap(s, win, 0, y1);
	if (overlap < bestOverlap) {
		*bestX = 0;
		bestOverlap = overlap;
	}

	overlap = layoutOrganicCalculateOverlap(s, win, areaWidth - w, y1);
	if (overlap < bestOverlap) {
		*bestX = areaWidth - w;
		bestOverlap = overlap;
	}

	return bestOverlap;
}
Exemplo n.º 20
0
static Bool
scaleaddonZoomWindow(CompDisplay * d,
		     CompAction * action,
		     CompActionState state, CompOption * option, int nOption)
{
	CompScreen *s;
	Window xid;

	xid = getIntOptionNamed(option, nOption, "root", 0);

	s = findScreenAtDisplay(d, xid);
	if (s) {
		CompWindow *w;

		SCALE_SCREEN(s);
		ADDON_DISPLAY(d);

		if (!ss->grabIndex)
			return FALSE;

		w = findWindowAtDisplay(d, ad->highlightedWindow);
		if (w) {
			SCALE_WINDOW(w);
			ADDON_WINDOW(w);

			XRectangle outputRect;
			BOX outputBox;
			int head;

			if (!sw->slot)
				return FALSE;

			head =
			    outputDeviceForPoint(s, sw->slot->x1, sw->slot->y1);
			outputBox = w->screen->outputDev[head].region.extents;

			outputRect.x = outputBox.x1;
			outputRect.y = outputBox.y1;
			outputRect.width = outputBox.x2 - outputBox.x1;
			outputRect.height = outputBox.y2 - outputBox.y1;

			/* damage old rect */
			addWindowDamage(w);

			if (!aw->rescaled) {
				aw->oldAbove = w->next;
				raiseWindow(w);

				/* backup old values */
				aw->origSlot = *sw->slot;

				aw->rescaled = TRUE;

				sw->slot->x1 =
				    (outputRect.width / 2) - (WIN_W(w) / 2) +
				    w->input.left + outputRect.x;
				sw->slot->y1 =
				    (outputRect.height / 2) - (WIN_H(w) / 2) +
				    w->input.top + outputRect.y;
				sw->slot->x2 = sw->slot->x1 + WIN_W(w);
				sw->slot->y2 = sw->slot->y1 + WIN_H(w);
				sw->slot->scale = 1.0f;
			} else {
				if (aw->oldAbove)
					restackWindowBelow(w, aw->oldAbove);

				aw->rescaled = FALSE;
				*(sw->slot) = aw->origSlot;
			}

			sw->adjust = TRUE;
			ss->state = SCALE_STATE_OUT;

			/* slot size may have changed, so
			 * update window title */
			scaleaddonRenderWindowTitle(w);

			addWindowDamage(w);

			return TRUE;
		}
	}

	return FALSE;
}
Exemplo n.º 21
0
static void
fxCurvedFoldModelStepObject(CompWindow *w,
                            Model *model,
                            Object *object,
                            float forwardProgress, float curveMaxAmp)
{
    ANIM_WINDOW(w);

    float origx = w->attrib.x + (WIN_W(w) * object->gridPosition.x -
                                 w->output.left) * model->scale.x;
    float origy = w->attrib.y + (WIN_H(w) * object->gridPosition.y -
                                 w->output.top) * model->scale.y;

    if (aw->curWindowEvent == WindowEventShade ||
            aw->curWindowEvent == WindowEventUnshade)
    {
        // Execute shade mode

        // find position in window contents
        // (window contents correspond to 0.0-1.0 range)
        float relPosInWinContents =
            (object->gridPosition.y * WIN_H(w) -
             model->topHeight) / w->height;
        float relDistToCenter = fabs(relPosInWinContents - 0.5);

        if (object->gridPosition.y == 0)
        {
            object->position.x = origx;
            object->position.y = WIN_Y(w);
        }
        else if (object->gridPosition.y == 1)
        {
            object->position.x = origx;
            object->position.y =
                (1 - forwardProgress) * origy +
                forwardProgress *
                (WIN_Y(w) + model->topHeight + model->bottomHeight);
        }
        else
        {
            object->position.x =
                origx + sin(forwardProgress * M_PI / 2) *
                (0.5 - object->gridPosition.x) * 2 * model->scale.x *
                curveMaxAmp *
                (1 - pow (pow(2 * relDistToCenter, 1.3), 2));
            object->position.y =
                (1 - forwardProgress) * origy +
                forwardProgress * (WIN_Y(w) + model->topHeight);
        }
    }
    else
    {
        // Execute normal mode

        // find position within window borders
        // (border contents correspond to 0.0-1.0 range)
        float relPosInWinBorders =
            (object->gridPosition.y * WIN_H(w) -
             (w->output.top - w->input.top)) / BORDER_H(w);
        float relDistToCenter = fabs(relPosInWinBorders - 0.5);

        // prevent top & bottom shadows from extending too much
        if (relDistToCenter > 0.5)
            relDistToCenter = 0.5;

        object->position.x =
            origx + sin(forwardProgress * M_PI / 2) *
            (0.5 - object->gridPosition.x) * 2 * model->scale.x *
            curveMaxAmp *
            (1 - pow (pow(2 * relDistToCenter, 1.3), 2));
        object->position.y =
            (1 - forwardProgress) * origy +
            forwardProgress * (BORDER_Y(w) + BORDER_H(w) / 2.0);
    }
}
Exemplo n.º 22
0
static void
thumbUpdateThumbnail (CompScreen *s)
{
	int igMidPoint[2], tMidPoint[2];
	int tPos[2], tmpPos[2];
	float distance = 1000000;
	int off, oDev, tHeight;
	int ox1, oy1, ox2, oy2, ow, oh;

	const BananaValue *
	option_thumb_size = bananaGetOption (bananaIndex,
	                                     "thumb_size",
	                                     s->screenNum);

	float maxSize = option_thumb_size->i;
	double scale  = 1.0;
	CompWindow *w;

	THUMB_SCREEN (s);

	if (ts->thumb.win == ts->pointedWin)
		return;

	if (ts->thumb.opacity > 0.0 && ts->oldThumb.opacity > 0.0)
		return;

	if (ts->thumb.win)
		damageThumbRegion (s, &ts->thumb);

	freeThumbText (s, &ts->oldThumb);

	ts->oldThumb       = ts->thumb;
	ts->thumb.textData = NULL;
	ts->thumb.win      = ts->pointedWin;
	ts->thumb.dock     = ts->dock;

	if (!ts->thumb.win || !ts->dock)
	{
		ts->thumb.win  = NULL;
		ts->thumb.dock = NULL;
		return;
	}

	w = ts->thumb.win;

	/* do we nee to scale the window down? */
	if (WIN_W (w) > maxSize || WIN_H (w) > maxSize)
	{
		if (WIN_W (w) >= WIN_H (w))
			scale = maxSize / WIN_W (w);
		else
			scale = maxSize / WIN_H (w);
	}

	ts->thumb.width  = WIN_W (w)* scale;
	ts->thumb.height = WIN_H (w) * scale;
	ts->thumb.scale  = scale;

	const BananaValue *
	option_title_enabled = bananaGetOption (bananaIndex,
	                                        "title_enabled",
	                                        s->screenNum);

	if (option_title_enabled->b)
		renderThumbText (s, &ts->thumb, FALSE);
	else
		freeThumbText (s, &ts->thumb);

	igMidPoint[0] = w->iconGeometry.x + (w->iconGeometry.width / 2);
	igMidPoint[1] = w->iconGeometry.y + (w->iconGeometry.height / 2);

	const BananaValue *
	option_border = bananaGetOption (bananaIndex,
	                                 "border",
	                                 s->screenNum);

	off = option_border->i;
	oDev = outputDeviceForPoint (s,
	                             w->iconGeometry.x +
	                             (w->iconGeometry.width / 2),
	                             w->iconGeometry.y +
	                             (w->iconGeometry.height / 2));

	if (s->nOutputDev == 1 || oDev > s->nOutputDev)
	{
		ox1 = 0;
		oy1 = 0;
		ox2 = s->width;
		oy2 = s->height;
		ow  = s->width;
		oh  = s->height;
	}
	else
	{
		ox1 = s->outputDev[oDev].region.extents.x1;
		ox2 = s->outputDev[oDev].region.extents.x2;
		oy1 = s->outputDev[oDev].region.extents.y1;
		oy2 = s->outputDev[oDev].region.extents.y2;
		ow  = ox2 - ox1;
		oh  = oy2 - oy1;
	}

	tHeight = ts->thumb.height;
	if (ts->thumb.textData)
		tHeight += ts->thumb.textData->height + TEXT_DISTANCE;

	// failsave position
	tPos[0] = igMidPoint[0] - (ts->thumb.width / 2.0);

	if (w->iconGeometry.y - tHeight >= 0)
		tPos[1] = w->iconGeometry.y - tHeight;
	else
		tPos[1] = w->iconGeometry.y + w->iconGeometry.height;

	// above
	tmpPos[0] = igMidPoint[0] - (ts->thumb.width / 2.0);

	if (tmpPos[0] - off < ox1)
		tmpPos[0] = ox1 + off;

	if (tmpPos[0] + off + ts->thumb.width > ox2)
	{
		if (ts->thumb.width + (2 * off) <= ow)
			tmpPos[0] = ox2 - ts->thumb.width - off;
		else
			tmpPos[0] = ox1 + off;
	}

	tMidPoint[0] = tmpPos[0] + (ts->thumb.width / 2.0);

	tmpPos[1] = WIN_Y (ts->dock) - tHeight - off;
	tMidPoint[1] = tmpPos[1] + (tHeight / 2.0);

	if (tmpPos[1] > oy1)
	{
		tPos[0]  = tmpPos[0];
		tPos[1]  = tmpPos[1];
		distance = GET_DISTANCE (igMidPoint, tMidPoint);
	}

	// below
	tmpPos[1] = WIN_Y (ts->dock) + WIN_H (ts->dock) + off;

	tMidPoint[1] = tmpPos[1] + (tHeight / 2.0);

	if (tmpPos[1] + tHeight + off < oy2 &&
	    GET_DISTANCE (igMidPoint, tMidPoint) < distance)
	{
		tPos[0]  = tmpPos[0];
		tPos[1]  = tmpPos[1];
		distance = GET_DISTANCE (igMidPoint, tMidPoint);
	}

	// left
	tmpPos[1] = igMidPoint[1] - (tHeight / 2.0);

	if (tmpPos[1] - off < oy1)
		tmpPos[1] = oy1 + off;

	if (tmpPos[1] + off + tHeight > oy2)
	{
		if (tHeight + (2 * off) <= oh)
			tmpPos[1] = oy2 - ts->thumb.height - off;
		else
			tmpPos[1] = oy1 + off;
	}

	tMidPoint[1] = tmpPos[1] + (tHeight / 2.0);

	tmpPos[0] = WIN_X (ts->dock) - ts->thumb.width - off;
	tMidPoint[0] = tmpPos[0] + (ts->thumb.width / 2.0);

	if (tmpPos[0] > ox1 && GET_DISTANCE (igMidPoint, tMidPoint) < distance)
	{
		tPos[0]  = tmpPos[0];
		tPos[1]  = tmpPos[1];
		distance = GET_DISTANCE (igMidPoint, tMidPoint);
	}

	// right
	tmpPos[0] = WIN_X (ts->dock) + WIN_W (ts->dock) + off;

	tMidPoint[0] = tmpPos[0] + (ts->thumb.width / 2.0);

	if (tmpPos[0] + ts->thumb.width + off < ox2 &&
	    GET_DISTANCE (igMidPoint, tMidPoint) < distance)
	{
		tPos[0]  = tmpPos[0];
		tPos[1]  = tmpPos[1];
		distance = GET_DISTANCE (igMidPoint, tMidPoint);
	}

	ts->thumb.x       = tPos[0];
	ts->thumb.y       = tPos[1];
	ts->thumb.offset  = off;
	ts->thumb.opacity = 0.0;

	damageThumbRegion (s, &ts->thumb);
}
Exemplo n.º 23
0
Bool
fxLeafSpreadInit (CompWindow *w)
{
	if (!polygonsAnimInit (w))
		return FALSE;

	CompScreen *s = w->screen;
	ANIM_WINDOW (w);

	if (!tessellateIntoRectangles (w, 20, 14, 15.0f))
		return FALSE;

	PolygonSet *pset = aw->eng.polygonSet;
	PolygonObject *p = pset->polygons;
	float fadeDuration = 0.26;
	float life = 0.4;
	float spreadFac = 3.5;
	float randYMax = 0.07;
	float winFacX = WIN_W (w) / 800.0;
	float winFacY = WIN_H (w) / 800.0;
	float winFacZ = (WIN_H (w) + WIN_W (w)) / 2.0 / 800.0;

	int i;

	for (i = 0; i < pset->nPolygons; i++, p++)
	{
		p->rotAxis.x = RAND_FLOAT ();
		p->rotAxis.y = RAND_FLOAT ();
		p->rotAxis.z = RAND_FLOAT ();

		float screenSizeFactor = (0.8 * DEFAULT_Z_CAMERA * s->width);
		float speed = screenSizeFactor / 10 * (0.2 + RAND_FLOAT ());

		float xx = 2 * (p->centerRelPos.x - 0.5);
		float yy = 2 * (p->centerRelPos.y - 0.5);

		float x =
		        speed * winFacX * spreadFac * (xx +
		                                       0.5 * (RAND_FLOAT () - 0.5));
		float y =
		        speed * winFacY * spreadFac * (yy +
		                                       0.5 * (RAND_FLOAT () - 0.5));
		float z = speed * winFacZ * 7 * ((RAND_FLOAT () - 0.5) / 0.5);

		p->finalRelPos.x = x;
		p->finalRelPos.y = y;
		p->finalRelPos.z = z;

		p->moveStartTime =
		        p->centerRelPos.y * (1 - fadeDuration - randYMax) +
		        randYMax * RAND_FLOAT ();
		p->moveDuration = 1;

		p->fadeStartTime = p->moveStartTime + life;
		if (p->fadeStartTime > 1 - fadeDuration)
			p->fadeStartTime = 1 - fadeDuration;
		p->fadeDuration = fadeDuration;

		p->finalRotAng = 150;
	}
	pset->doDepthTest = TRUE;
	pset->doLighting = TRUE;
	pset->correctPerspective = CorrectPerspectivePolygon;

	aw->com.animTotalTime /= LEAFSPREAD_PERCEIVED_T;
	aw->com.animRemainingTime = aw->com.animTotalTime;

	return TRUE;
}
// Returns FALSE if the subject is destroyed or if there was an error when
// calculating the dodge box
static Bool
fxDodgeFindDodgeBox (CompWindow *w, XRectangle *dodgeBox)
{
    ANIM_SCREEN(w->screen);
    ANIM_WINDOW(w);

    if (!aw->dodgeSubjectWin)  // if the subject is destroyed
	return FALSE;

    // Find the box to be dodged, it can contain multiple windows
    // when there are dialog/utility windows of subject windows
    // (stacked in the moreToBePaintedNext chain)
    // Then this would be a bounding box of the subject windows
    // intersecting with dodger.
    Region wRegion = XCreateRegion();
    if (!wRegion)
	return FALSE;

    Region dodgeRegion = XCreateRegion();
    if (!dodgeRegion)
    {
	XDestroyRegion (wRegion);
	return FALSE;
    }

    XRectangle rect;
    rect.x = WIN_X(w);
    rect.y = WIN_Y(w);
    rect.width = WIN_W(w);
    rect.height = WIN_H(w);

    int dodgeMaxAmount = (int)aw->dodgeMaxAmount;

    // to compute if subject(s) intersect with dodger w,
    // enlarge dodger window's box so that it encloses all of the covered
    // region during dodge movement. This corrects the animation when
    // there are >1 subjects (a window with its dialog/utility windows).
    switch (aw->dodgeDirection)
    {
    case 0:
	rect.y += dodgeMaxAmount;
	rect.height -= dodgeMaxAmount;
	break;
    case 1:
	rect.height += dodgeMaxAmount;
	break;
    case 2:
	rect.x += dodgeMaxAmount;
	rect.width -= dodgeMaxAmount;
	break;
    case 3:
	rect.width += dodgeMaxAmount;
	break;
    }
    XUnionRectWithRegion(&rect, &emptyRegion, wRegion);

    AnimWindow *awCur;
    CompWindow *wCur = aw->dodgeSubjectWin;
    for (; wCur; wCur = awCur->moreToBePaintedNext)
    {
	fxDodgeProcessSubject(wCur, wRegion, dodgeRegion,
			      wCur == aw->dodgeSubjectWin);
	awCur = GET_ANIM_WINDOW(wCur, as);
	if (!awCur)
	    break;
    }

    AnimWindow *awSubj = GET_ANIM_WINDOW(aw->dodgeSubjectWin, as);
    wCur = awSubj->moreToBePaintedPrev;
    for (; wCur; wCur = awCur->moreToBePaintedPrev)
    {
	fxDodgeProcessSubject(wCur, wRegion, dodgeRegion, FALSE);
	awCur = GET_ANIM_WINDOW(wCur, as);
	if (!awCur)
	    break;
    }

    XClipBox(dodgeRegion, dodgeBox);

    XDestroyRegion (wRegion);
    XDestroyRegion (dodgeRegion);

    return TRUE;
}
Exemplo n.º 25
0
Bool
fxZoomInit (CompWindow *w)
{
	ANIM_WINDOW (w);

	const BananaValue *
	option_sidekick_zoom_from_center = bananaGetOption (bananaIndex,
	                                             "sidekick_zoom_from_center",
	                                              w->screen->screenNum);

	if ((aw->com.curAnimEffect == AnimEffectSidekick &&
	     (option_sidekick_zoom_from_center->i ==
	      3 ||
	      ((aw->com.curWindowEvent == WindowEventMinimize ||
	        aw->com.curWindowEvent == WindowEventUnminimize) &&
	       option_sidekick_zoom_from_center->i ==
	       1) ||
	      ((aw->com.curWindowEvent == WindowEventOpen ||
	        aw->com.curWindowEvent == WindowEventClose) &&
	       option_sidekick_zoom_from_center->i ==
	       2))) ||
	    (aw->com.curAnimEffect == AnimEffectZoom &&
	     (option_sidekick_zoom_from_center->i ==
	      3 ||
	      ((aw->com.curWindowEvent == WindowEventMinimize ||
	        aw->com.curWindowEvent == WindowEventUnminimize) &&
	       option_sidekick_zoom_from_center->i ==
	       1) ||
	      ((aw->com.curWindowEvent == WindowEventOpen ||
	        aw->com.curWindowEvent == WindowEventClose) &&
	       option_sidekick_zoom_from_center->i ==
	       2))))
	{
		aw->com.icon.x =
		        WIN_X (w) + WIN_W (w) / 2 - aw->com.icon.width / 2;
		aw->com.icon.y =
		        WIN_Y (w) + WIN_H (w) / 2 - aw->com.icon.height / 2;
	}

	// allow extra time for spring damping / deceleration
	if ((aw->com.curWindowEvent == WindowEventUnminimize ||
	     aw->com.curWindowEvent == WindowEventOpen) &&
	    fxZoomGetSpringiness (w) > 1e-4)
	{
		aw->com.animTotalTime /= SPRINGY_ZOOM_PERCEIVED_T;
	}
	else if ((aw->com.curAnimEffect == AnimEffectZoom ||
	          aw->com.curAnimEffect == AnimEffectSidekick) &&
	         (aw->com.curWindowEvent == WindowEventOpen ||
	          aw->com.curWindowEvent == WindowEventClose))
	{
		aw->com.animTotalTime /= NONSPRINGY_ZOOM_PERCEIVED_T;
	}
	else
	{
		aw->com.animTotalTime /= ZOOM_PERCEIVED_T;
	}
	aw->com.animRemainingTime = aw->com.animTotalTime;

	aw->com.usingTransform = TRUE;

	return defaultAnimInit (w);
}