示例#1
0
static int organicCompareWindows(const void *elem1, const void *elem2)
{
	CompWindow *w1 = *((CompWindow **) elem1);
	CompWindow *w2 = *((CompWindow **) elem2);

	return (WIN_X(w1) + WIN_Y(w1)) - (WIN_X(w2) + WIN_Y(w2));
}
示例#2
0
/*
 * groupWindowResizeNotify
 *
 */
void
groupWindowResizeNotify (CompWindow *w,
                         int        dx,
                         int        dy,
                         int        dwidth,
                         int        dheight)
{
	CompScreen *s = w->screen;

	GROUP_SCREEN (s);
	GROUP_WINDOW (w);

	if (gw->resizeGeometry)
	{
		free (gw->resizeGeometry);
		gw->resizeGeometry = NULL;
	}

	UNWRAP (gs, s, windowResizeNotify);
	(*s->windowResizeNotify)(w, dx, dy, dwidth, dheight);
	WRAP (gs, s, windowResizeNotify, groupWindowResizeNotify);

	if (gw->glowQuads)
		groupComputeGlowQuads (w, &gs->glowTexture.matrix);

	if (gw->group && gw->group->tabBar && IS_TOP_TAB (w, gw->group))
	{
		if (gw->group->tabBar->state != PaintOff)
		{
			groupRecalcTabBarPos (gw->group, pointerX,
			                      WIN_X (w), WIN_X (w) + WIN_WIDTH (w));
		}
	}
}
示例#3
0
文件: expand.cpp 项目: hedmo/compiz
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);

}
示例#4
0
Bool
fxSidekickInit (CompWindow *w)
{
	ANIM_WINDOW (w);

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

	// determine number of rotations randomly in [0.9, 1.1] range
	aw->numZoomRotations =
	        option_sidekick_num_rotations->f *
	        (1.0f + 0.2f * rand () / RAND_MAX - 0.1f);

	float winCenterX = WIN_X (w) + WIN_W (w) / 2.0;
	float iconCenterX = aw->com.icon.x + aw->com.icon.width / 2.0;

	// if window is to the right of icon, rotate clockwise instead
	// to make rotation look more pleasant
	if (winCenterX > iconCenterX)
		aw->numZoomRotations *= -1;

	return fxZoomInit (w);
}
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);
}
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;
}
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);
}
示例#8
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;
			}
		}
	}
}
示例#9
0
文件: glide.c 项目: 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);
}
Bool
fxSidekickInit (CompWindow * w)
{
    ANIM_WINDOW(w);

    // determine number of rotations randomly in [0.9, 1.1] range
    aw->numZoomRotations =
	animGetF (w, ANIM_SCREEN_OPTION_SIDEKICK_NUM_ROTATIONS) *
	(1.0f + 0.2f * rand() / RAND_MAX - 0.1f);

    float winCenterX = WIN_X(w) + WIN_W(w) / 2.0;
    float iconCenterX = aw->com.icon.x + aw->com.icon.width / 2.0;

    // if window is to the right of icon, rotate clockwise instead
    // to make rotation look more pleasant
    if (winCenterX > iconCenterX)
	aw->numZoomRotations *= -1;

    return fxZoomInit (w);
}
示例#11
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);
}
示例#12
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);
}
示例#13
0
static unsigned int
groupUpdateResizeRectangle (CompWindow *w,
                            XRectangle *masterGeometry,
                            Bool       damage)
{
	XRectangle newGeometry;
	unsigned int mask = 0;
	int newWidth, newHeight;
	int widthDiff, heightDiff;

	GROUP_WINDOW (w);
	GROUP_DISPLAY (&display);

	if (!gw->resizeGeometry || !gd->resizeInfo)
		return 0;

	newGeometry.x = WIN_X (w) + (masterGeometry->x -
	                             gd->resizeInfo->origGeometry.x);
	newGeometry.y = WIN_Y (w) + (masterGeometry->y -
	                             gd->resizeInfo->origGeometry.y);

	widthDiff = masterGeometry->width - gd->resizeInfo->origGeometry.width;
	newGeometry.width = MAX (1, WIN_WIDTH (w) + widthDiff);
	heightDiff = masterGeometry->height - gd->resizeInfo->origGeometry.height;
	newGeometry.height = MAX (1, WIN_HEIGHT (w) + heightDiff);

	if (constrainNewWindowSize (w,
	                            newGeometry.width, newGeometry.height,
	                            &newWidth, &newHeight))
	{

		newGeometry.width  = newWidth;
		newGeometry.height = newHeight;
	}

	if (damage)
	{
		if (memcmp (&newGeometry, gw->resizeGeometry,
		            sizeof (newGeometry)) != 0)
		{
			addWindowDamage (w);
		}
	}

	if (newGeometry.x != gw->resizeGeometry->x)
	{
		gw->resizeGeometry->x = newGeometry.x;
		mask |= CWX;
	}
	if (newGeometry.y != gw->resizeGeometry->y)
	{
		gw->resizeGeometry->y = newGeometry.y;
		mask |= CWY;
	}
	if (newGeometry.width != gw->resizeGeometry->width)
	{
		gw->resizeGeometry->width = newGeometry.width;
		mask |= CWWidth;
	}
	if (newGeometry.height != gw->resizeGeometry->height)
	{
		gw->resizeGeometry->height = newGeometry.height;
		mask |= CWHeight;
	}

	return mask;
}
示例#14
0
文件: particle.c 项目: Elive/ecomp
void
drawParticles(CompScreen *s, CompWindow *w, ParticleSystem *ps)
{
   glPushMatrix();
   if (w)
     glTranslated(WIN_X(w) - ps->x, WIN_Y(w) - ps->y, 0);

   glEnable(GL_BLEND);
   if (ps->tex)
     {
        glBindTexture(GL_TEXTURE_2D, ps->tex);
        glEnable(GL_TEXTURE_2D);
     }
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

   int i;
   Particle *part;

   /* Check that the cache is big enough */
   if (ps->numParticles > ps->vertex_cache_count)
     {
        ps->vertices_cache =
          realloc(ps->vertices_cache,
                  ps->numParticles * 4 * 3 * sizeof(GLfloat));
        ps->vertex_cache_count = ps->numParticles;
     }

   if (ps->numParticles > ps->coords_cache_count)
     {
        ps->coords_cache =
          realloc(ps->coords_cache,
                  ps->numParticles * 4 * 2 * sizeof(GLfloat));
        ps->coords_cache_count = ps->numParticles;
     }

   if (ps->numParticles > ps->color_cache_count)
     {
        ps->colors_cache =
          realloc(ps->colors_cache,
                  ps->numParticles * 4 * 4 * sizeof(GLfloat));
        ps->color_cache_count = ps->numParticles;
     }

   if (ps->darken > 0)
     {
        if (ps->dcolors_cache_count < ps->numParticles)
          {
             ps->dcolors_cache =
               realloc(ps->dcolors_cache,
                       ps->numParticles * 4 * 4 * sizeof(GLfloat));
             ps->dcolors_cache_count = ps->numParticles;
          }
     }

   GLfloat *dcolors = ps->dcolors_cache;
   GLfloat *vertices = ps->vertices_cache;
   GLfloat *coords = ps->coords_cache;
   GLfloat *colors = ps->colors_cache;

   int numActive = 0;

   for (i = 0; i < ps->numParticles; i++)
     {
        part = &ps->particles[i];
        if (part->life > 0.0f)
          {
             numActive += 4;

             float w = part->width / 2;
             float h = part->height / 2;

             w += (w * part->w_mod) * part->life;
             h += (h * part->h_mod) * part->life;

             vertices[0] = part->x - w;
             vertices[1] = part->y - h;
             vertices[2] = part->z;

             vertices[3] = part->x - w;
             vertices[4] = part->y + h;
             vertices[5] = part->z;

             vertices[6] = part->x + w;
             vertices[7] = part->y + h;
             vertices[8] = part->z;

             vertices[9] = part->x + w;
             vertices[10] = part->y - h;
             vertices[11] = part->z;

             vertices += 12;

             coords[0] = 0.0;
             coords[1] = 0.0;

             coords[2] = 0.0;
             coords[3] = 1.0;

             coords[4] = 1.0;
             coords[5] = 1.0;

             coords[6] = 1.0;
             coords[7] = 0.0;

             coords += 8;

             colors[0] = part->r;
             colors[1] = part->g;
             colors[2] = part->b;
             colors[3] = part->life * part->a;
             colors[4] = part->r;
             colors[5] = part->g;
             colors[6] = part->b;
             colors[7] = part->life * part->a;
             colors[8] = part->r;
             colors[9] = part->g;
             colors[10] = part->b;
             colors[11] = part->life * part->a;
             colors[12] = part->r;
             colors[13] = part->g;
             colors[14] = part->b;
             colors[15] = part->life * part->a;

             colors += 16;

             if (ps->darken > 0)
               {
                  dcolors[0] = part->r;
                  dcolors[1] = part->g;
                  dcolors[2] = part->b;
                  dcolors[3] = part->life * part->a * ps->darken;
                  dcolors[4] = part->r;
                  dcolors[5] = part->g;
                  dcolors[6] = part->b;
                  dcolors[7] = part->life * part->a * ps->darken;
                  dcolors[8] = part->r;
                  dcolors[9] = part->g;
                  dcolors[10] = part->b;
                  dcolors[11] = part->life * part->a * ps->darken;
                  dcolors[12] = part->r;
                  dcolors[13] = part->g;
                  dcolors[14] = part->b;
                  dcolors[15] = part->life * part->a * ps->darken;

                  dcolors += 16;
               }
          }
     }

   glEnableClientState(GL_COLOR_ARRAY);

   glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), ps->coords_cache);
   glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), ps->vertices_cache);

   // darken the background
   if (ps->darken > 0)
     {
        glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
        glColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), ps->dcolors_cache);
        glDrawArrays(GL_QUADS, 0, numActive);
     }
   // draw particles
   glBlendFunc(GL_SRC_ALPHA, ps->blendMode);

   glColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), ps->colors_cache);

   glDrawArrays(GL_QUADS, 0, numActive);

   glDisableClientState(GL_COLOR_ARRAY);

   glPopMatrix();
   glColor4usv(defaultColor);
   screenTexEnvMode(s, GL_REPLACE);
   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
}
示例#15
0
/*
 * 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;
}
示例#16
0
/*
 * groupPaintThumb - taken from switcher and modified for tab bar
 *
 */
static void
groupPaintThumb (GroupSelection      *group,
                 GroupTabBarSlot     *slot,
                 const CompTransform *transform,
                 int                 targetOpacity)
{
	CompWindow            *w = slot->window;
	CompScreen            *s = w->screen;
	AddWindowGeometryProc oldAddWindowGeometry;
	WindowPaintAttrib wAttrib = w->paint;
	int tw, th;

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

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

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

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

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

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

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

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

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

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

		groupGetDrawOffsetForSlot (slot, &vx, &vy);

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

		initFragmentAttrib (&fragment, &wAttrib);

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

		glPushMatrix ();
		glLoadMatrixf (wTransform.m);

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

		glPopMatrix ();
	}

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

	GROUP_SCREEN (s);

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

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

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

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

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

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

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

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

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

			layer = bar->bgLayer;

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

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

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

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

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

		case PAINT_THUMBS:
		{
			GLenum oldTextureFilter;
			GroupTabBarSlot *slot;

			oldTextureFilter = display.textureFilter;

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

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

			display.textureFilter = oldTextureFilter;
		}
		break;

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

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

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

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

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

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

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

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

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

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

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

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

				glPushMatrix ();
				glLoadMatrixf (wTransform.m);

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

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

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

				glPopMatrix ();
			}
		}
	}
}
// 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;
}
示例#19
0
void
groupWindowGrabNotify (CompWindow   *w,
                       int          x,
                       int          y,
                       unsigned int state,
                       unsigned int mask)
{
	CompScreen *s = w->screen;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);
	GROUP_WINDOW (w);

	if (gw->group && !gd->ignoreMode && !gs->queued)
	{
		Bool doResizeAll;
		int i;

		const BananaValue *
		option_resize_all = bananaGetOption (bananaIndex,
		                                     "resize_all",
		                                     s->screenNum);

		doResizeAll = option_resize_all->b &&
		              (mask & CompWindowGrabResizeMask);

		if (gw->group->tabBar)
			groupTabSetVisibility (gw->group, FALSE, 0);

		for (i = 0; i < gw->group->nWins; i++)
		{
			CompWindow *cw = gw->group->windows[i];
			if (!cw)
				continue;

			if (cw->id != w->id)
			{
				GroupWindow *gcw = GET_GROUP_WINDOW (cw, gs);

				groupEnqueueGrabNotify (cw, x, y, state, mask);

				if (doResizeAll && !(cw->state & MAXIMIZE_STATE))
				{
					if (!gcw->resizeGeometry)
						gcw->resizeGeometry = malloc (sizeof (XRectangle));
					if (gcw->resizeGeometry)
					{
						gcw->resizeGeometry->x      = WIN_X (cw);
						gcw->resizeGeometry->y      = WIN_Y (cw);
						gcw->resizeGeometry->width  = WIN_WIDTH (cw);
						gcw->resizeGeometry->height = WIN_HEIGHT (cw);
					}
				}
			}
		}

		if (doResizeAll)
		{
			if (!gd->resizeInfo)
				gd->resizeInfo = malloc (sizeof (GroupResizeInfo));

			if (gd->resizeInfo)
			{
				gd->resizeInfo->resizedWindow       = w;
				gd->resizeInfo->origGeometry.x      = WIN_X (w);
				gd->resizeInfo->origGeometry.y      = WIN_Y (w);
				gd->resizeInfo->origGeometry.width  = WIN_WIDTH (w);
				gd->resizeInfo->origGeometry.height = WIN_HEIGHT (w);
			}
		}

		gw->group->grabWindow = w->id;
		gw->group->grabMask = mask;
	}

	UNWRAP (gs, s, windowGrabNotify);
	(*s->windowGrabNotify)(w, x, y, state, mask);
	WRAP (gs, s, windowGrabNotify, groupWindowGrabNotify);
}
示例#20
0
void
groupWindowUngrabNotify (CompWindow *w)
{
	CompScreen *s = w->screen;

	GROUP_SCREEN (s);
	GROUP_DISPLAY (&display);
	GROUP_WINDOW (w);

	if (gw->group && !gd->ignoreMode && !gs->queued)
	{
		int i;
		XRectangle rect;

		groupDequeueMoveNotifies (s);

		if (gd->resizeInfo)
		{
			rect.x      = WIN_X (w);
			rect.y      = WIN_Y (w);
			rect.width  = WIN_WIDTH (w);
			rect.height = WIN_HEIGHT (w);
		}

		for (i = 0; i < gw->group->nWins; i++)
		{
			CompWindow *cw = gw->group->windows[i];
			if (!cw)
				continue;

			if (cw->id != w->id)
			{
				GROUP_WINDOW (cw);

				if (gw->resizeGeometry)
				{
					unsigned int mask;

					gw->resizeGeometry->x      = WIN_X (cw);
					gw->resizeGeometry->y      = WIN_Y (cw);
					gw->resizeGeometry->width  = WIN_WIDTH (cw);
					gw->resizeGeometry->height = WIN_HEIGHT (cw);

					mask = groupUpdateResizeRectangle (cw, &rect, FALSE);
					if (mask)
					{
						XWindowChanges xwc;
						xwc.x      = gw->resizeGeometry->x;
						xwc.y      = gw->resizeGeometry->y;
						xwc.width  = gw->resizeGeometry->width;
						xwc.height = gw->resizeGeometry->height;

						if (w->mapNum && (mask & (CWWidth | CWHeight)))
							sendSyncRequest (w);

						configureXWindow (cw, mask, &xwc);
					}
					else
					{
						free (gw->resizeGeometry);
						gw->resizeGeometry =  NULL;
					}
				}
				if (gw->needsPosSync)
				{
					syncWindowPosition (cw);
					gw->needsPosSync = FALSE;
				}
				groupEnqueueUngrabNotify (cw);
			}
		}

		if (gd->resizeInfo)
		{
			free (gd->resizeInfo);
			gd->resizeInfo = NULL;
		}

		gw->group->grabWindow = None;
		gw->group->grabMask = 0;
	}

	UNWRAP (gs, s, windowUngrabNotify);
	(*s->windowUngrabNotify)(w);
	WRAP ( gs, s, windowUngrabNotify, groupWindowUngrabNotify);
}
示例#21
0
/*
 * groupAddWindowToGroup
 *
 */
void
groupAddWindowToGroup (CompWindow     *w,
                       GroupSelection *group,
                       long int       initialIdent)
{
	GROUP_SCREEN (w->screen);
	GROUP_WINDOW (w);

	if (gw->group)
		return;

	if (group)
	{
		CompWindow *topTab = NULL;

		group->windows = realloc (group->windows,
		                          sizeof (CompWindow *) * (group->nWins + 1));
		group->windows[group->nWins] = w;
		group->nWins++;
		gw->group = group;

		updateWindowOutputExtents (w);
		groupUpdateWindowProperty (w);

		if (group->nWins == 2)
		{
			/* first window in the group got its glow, too */
			updateWindowOutputExtents (group->windows[0]);
		}

		if (group->tabBar)
		{
			if (HAS_TOP_WIN (group))
				topTab = TOP_TAB (group);
			else if (HAS_PREV_TOP_WIN (group))
			{
				topTab = PREV_TOP_TAB (group);
				group->topTab = group->prevTopTab;
				group->prevTopTab = NULL;
			}

			if (topTab)
			{
				if (!gw->slot)
					groupCreateSlot (group, w);

				gw->destination.x = WIN_CENTER_X (topTab) - (WIN_WIDTH (w) / 2);
				gw->destination.y = WIN_CENTER_Y (topTab) -
				                    (WIN_HEIGHT (w) / 2);
				gw->mainTabOffset.x = WIN_X (w) - gw->destination.x;
				gw->mainTabOffset.y = WIN_Y (w) - gw->destination.y;
				gw->orgPos.x = WIN_X (w);
				gw->orgPos.y = WIN_Y (w);

				gw->xVelocity = gw->yVelocity = 0.0f;

				gw->animateState = IS_ANIMATED;

				groupStartTabbingAnimation (group, TRUE);

				addWindowDamage (w);
			}
		}
	}
	else
	{
		/* create new group */
		GroupSelection *g = malloc (sizeof (GroupSelection));
		if (!g)
			return;

		g->windows = malloc (sizeof (CompWindow *));
		if (!g->windows)
		{
			free (g);
			return;
		}

		g->windows[0] = w;
		g->screen     = w->screen;
		g->nWins      = 1;

		g->topTab      = NULL;
		g->prevTopTab  = NULL;
		g->nextTopTab  = NULL;

		g->changeAnimationTime      = 0;
		g->changeAnimationDirection = 0;

		g->changeState  = NoTabChange;
		g->tabbingState = NoTabbing;
		g->ungroupState = UngroupNone;

		g->tabBar = NULL;

		g->checkFocusAfterTabChange = FALSE;

		g->grabWindow = None;
		g->grabMask   = 0;

		g->inputPrevention = None;
		g->ipwMapped       = FALSE;

		/* glow color */
		g->color[0] = (int)(rand () / (((double)RAND_MAX + 1) / 0xffff));
		g->color[1] = (int)(rand () / (((double)RAND_MAX + 1) / 0xffff));
		g->color[2] = (int)(rand () / (((double)RAND_MAX + 1) / 0xffff));
		g->color[3] = 0xffff;

		if (initialIdent)
			g->identifier = initialIdent;
		else
		{
			/* we got no valid group Id passed, so find out a new valid
			   unique one */
			GroupSelection *tg;
			Bool invalidID = FALSE;

			g->identifier = gs->groups ? gs->groups->identifier : 0;
			do
			{
				invalidID = FALSE;
				for (tg = gs->groups; tg; tg = tg->next)
				{
					if (tg->identifier == g->identifier)
					{
						invalidID = TRUE;

						g->identifier++;
						break;
					}
				}
			}
			while (invalidID);
		}

		/* relink stack */
		if (gs->groups)
			gs->groups->prev = g;

		g->next = gs->groups;
		g->prev = NULL;
		gs->groups = g;

		gw->group = g;

		groupUpdateWindowProperty (w);
	}
}
示例#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);
}
示例#23
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;
}
示例#24
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);
		}
	}
}