All pastes #810493 Raw Edit

scott

public c v1 · immutable
·published 2007-12-10 00:14 UTC
rendered paste body
#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <compiz-core.h> #include "sound_options.h"#include "../animation/animation-internal.h"static void animHandleEvent(CompDisplay * d, XEvent * event);static Bool animGetWindowIconGeometry(CompWindow * w, XRectangle * rect);static Bool windowHasUserTime(CompWindow *w);static inline Bool isWinVisible(CompWindow *w);static void updateLastClientListStacking(CompScreen *s);static void animHandleEvent(CompDisplay * d, XEvent * event){    CompWindow *w;    ANIM_DISPLAY(d);    switch (event->type)    {    case PropertyNotify:	if (event->xproperty.atom == d->clientListStackingAtom)	{	    CompScreen *s = findScreenAtDisplay (d, event->xproperty.window);	    if (s)		updateLastClientListStacking(s);	}	break;    case MapNotify:	w = findWindowAtDisplay(d, event->xmap.window);	if (w)	{	    ANIM_WINDOW(w);	    if (aw->animRemainingTime > 0)	    {		aw->state = aw->newState;	    }	    while (aw->unmapCnt)	    {		unmapWindow(w);		aw->unmapCnt--;	    }	}	break;    case DestroyNotify:	w = findWindowAtDisplay(d, event->xunmap.window);	if (w)	{	    ANIM_WINDOW(w);	    aw->destroyCnt++;	    w->destroyRefCnt++;	    addWindowDamage(w);	}	break;    case UnmapNotify:	w = findWindowAtDisplay(d, event->xunmap.window);	if (w)	{//	    ANIM_SCREEN(w->screen);	    if (w->pendingUnmaps && onCurrentDesktop(w))	// Normal -> Iconic	    {		ANIM_WINDOW(w);//		int duration = 200;//		AnimEffect chosenEffect =//		    getMatchingAnimSelection (w, WindowEventShade, &duration);		if (w->shaded)		{		    // SHADE event!		compLogMessage( w->screen->display, "sound", CompLogLevelDebug, "SHADE event" );		    aw->nowShaded = TRUE;/*		    if (chosenEffect)		    {			Bool startingNew = TRUE;			if (aw->curWindowEvent != WindowEventNone)			{			    if (aw->curWindowEvent != WindowEventUnshade)			    {				postAnimationCleanupCustom(w, TRUE, FALSE, FALSE);			    }			    else			    {				// Play the unshade effect backwards from where it left				aw->animRemainingTime =				    aw->animTotalTime -				    aw->animRemainingTime;				// avoid window remains				if (aw->animRemainingTime <= 0)				    aw->animRemainingTime = 1;				startingNew = FALSE;				if (aw->animOverrideProgressDir == 0)				    aw->animOverrideProgressDir = 2;				else if (aw->animOverrideProgressDir == 1)				    aw->animOverrideProgressDir = 0;			    }			}			if (startingNew)			{			    AnimEffect effectToBePlayed;			    effectToBePlayed = animGetAnimEffect(				chosenEffect,				as->shadeRandomEffects,				as->nShadeRandomEffects,				as->opt[ANIM_SCREEN_OPTION_ALL_RANDOM].value.b);			    // handle empty random effect list			    if (effectToBePlayed == AnimEffectNone)				break;									    aw->curAnimEffect = effectToBePlayed;			    aw->animTotalTime = duration;			    aw->animRemainingTime = aw->animTotalTime;			}			animActivateEvent(w->screen, TRUE);			aw->curWindowEvent = WindowEventShade;			// Store coords in this viewport to omit 3d effect			// painting in other viewports			aw->lastKnownCoords.x = w->attrib.x;			aw->lastKnownCoords.y = w->attrib.y;			if (!animEnsureModel(w))			{			    postAnimationCleanup(w, TRUE);			}			aw->unmapCnt++;			w->unmapRefCnt++;			damagePendingOnScreen (w->screen);		    }*/		}		else if (!w->invisible &&			 animGetWindowIconGeometry(w, &aw->icon))		{		    // MINIMIZE event!		compLogMessage( w->screen->display, "sound", CompLogLevelDebug, "MINIMIZE event" );/*		    aw->newState = IconicState;		    chosenEffect =			getMatchingAnimSelection (w, WindowEventMinimize, &duration);		    if (chosenEffect)		    {			Bool startingNew = TRUE;			if (aw->curWindowEvent != WindowEventNone)			{			    if (aw->curWindowEvent != WindowEventUnminimize)			    {				postAnimationCleanupCustom(w, TRUE, FALSE, FALSE);			    }			    else			    {				// Play the unminimize effect backwards from where it left				aw->animRemainingTime =				    aw->animTotalTime - aw->animRemainingTime;				// avoid window remains				if (aw->animRemainingTime == 0)				    aw->animRemainingTime = 1;				startingNew = FALSE;				if (aw->animOverrideProgressDir == 0)				    aw->animOverrideProgressDir = 2;				else if (aw->animOverrideProgressDir == 1)				    aw->animOverrideProgressDir = 0;			    }			}			if (startingNew)			{			    AnimEffect effectToBePlayed;									    effectToBePlayed = animGetAnimEffect(				chosenEffect,				as->minimizeRandomEffects,				as->nMinimizeRandomEffects,				as->opt[ANIM_SCREEN_OPTION_ALL_RANDOM].value.b);			    // handle empty random effect list			    if (effectToBePlayed == AnimEffectNone)				break;			    aw->curAnimEffect = effectToBePlayed;			    aw->animTotalTime = duration;			    aw->animRemainingTime = aw->animTotalTime;			}			animActivateEvent(w->screen, TRUE);			aw->curWindowEvent = WindowEventMinimize;			// Store coords in this viewport to omit 3d effect			// painting in other viewports			aw->lastKnownCoords.x = w->attrib.x;			aw->lastKnownCoords.y = w->attrib.y;			if (!animEnsureModel(w))			{			    postAnimationCleanup(w, TRUE);			}			else			{			    aw->unmapCnt++;			    w->unmapRefCnt++;			    damagePendingOnScreen (w->screen);			}		    }		}*/	    }	    else				// X -> Withdrawn	    {		ANIM_WINDOW(w);		// don't animate windows that don't have certain properties		// like the fullscreen darkening layer of gksudo		// or the darkening layer of x-session-manager		if (!(w->resName || windowHasUserTime (w)) ||		    (aw->wmName && strcasecmp (aw->wmName, "x-session-manager") == 0))		    break;		// CLOSE event!		compLogMessage( w->screen->display, "sound", CompLogLevelDebug, "CLOSE event!" );/*		int duration = 200;		AnimEffect chosenEffect =		    getMatchingAnimSelection (w, WindowEventClose, &duration);		aw->state = NormalState;		aw->newState = WithdrawnState;		if (chosenEffect)		{		    int tmpSteps = 0;		    Bool startingNew = TRUE;		    if (aw->animRemainingTime > 0 &&			aw->curWindowEvent != WindowEventOpen)		    {			tmpSteps = aw->animRemainingTime;			aw->animRemainingTime = 0;		    }		    if (aw->curWindowEvent != WindowEventNone)		    {			if (aw->curWindowEvent == WindowEventOpen)			{			    // Play the create effect backward from where it left			    aw->animRemainingTime =				aw->animTotalTime - aw->animRemainingTime;			    // avoid window remains			    if (aw->animRemainingTime <= 0)				aw->animRemainingTime = 1;			    startingNew = FALSE;			    if (aw->animOverrideProgressDir == 0)				aw->animOverrideProgressDir = 2;			    else if (aw->animOverrideProgressDir == 1)				aw->animOverrideProgressDir = 0;			}			else if (aw->curWindowEvent == WindowEventClose)			{			    if (aw->animOverrideProgressDir == 2)			    {				aw->animRemainingTime = tmpSteps;				startingNew = FALSE;			    }			}			else			{			    postAnimationCleanupCustom(w, TRUE, TRUE, FALSE);			}		    }		    if (startingNew)		    {			AnimEffect effectToBePlayed;			effectToBePlayed = animGetAnimEffect(			    chosenEffect,			    as->closeRandomEffects,			    as->nCloseRandomEffects,			    as->opt[ANIM_SCREEN_OPTION_ALL_RANDOM].value.b);			// handle empty random effect list			if (effectToBePlayed == AnimEffectNone)			    break;								aw->curAnimEffect = effectToBePlayed;			aw->animTotalTime = duration;			aw->animRemainingTime = aw->animTotalTime;		    }		    animActivateEvent(w->screen, TRUE);		    aw->curWindowEvent = WindowEventClose;		    // Store coords in this viewport to omit 3d effect		    // painting in other viewports		    aw->lastKnownCoords.x = w->attrib.x;		    aw->lastKnownCoords.y = w->attrib.y;		    if (!animEnsureModel(w))		    {			postAnimationCleanup(w, TRUE);		    }		    else if (getMousePointerXY			     (w->screen, &aw->icon.x, &aw->icon.y))		    {			aw->icon.width = FAKE_ICON_SIZE;			aw->icon.height = FAKE_ICON_SIZE;			if (aw->curAnimEffect == AnimEffectMagicLamp)			    aw->icon.width = 				MAX(aw->icon.width,				    animGetI(as, aw, ANIM_SCREEN_OPTION_MAGIC_LAMP_OPEN_START_WIDTH));			else if (aw->curAnimEffect == AnimEffectVacuum)			    aw->icon.width =				MAX(aw->icon.width,				    animGetI(as, aw, ANIM_SCREEN_OPTION_VACUUM_OPEN_START_WIDTH));			aw->unmapCnt++;			w->unmapRefCnt++;			damagePendingOnScreen (w->screen);		    }		}///		else if (getMatchingAnimSelection (w, WindowEventOpen, &duration))		{		    // stop the current animation and prevent it from rewinding		    if (aw->animRemainingTime > 0 &&			aw->curWindowEvent != WindowEventOpen)		    {			aw->animRemainingTime = 0;		    }		    if ((aw->curWindowEvent != WindowEventNone) &&			(aw->curWindowEvent != WindowEventClose))		    {			postAnimationCleanup(w, TRUE);		    }		    // set some properties to make sure this window will use the		    // correct open effect the next time it's "opened"		    animActivateEvent(w->screen, TRUE);		    aw->curWindowEvent = WindowEventClose;		    aw->unmapCnt++;		    w->unmapRefCnt++;		    damagePendingOnScreen (w->screen);		}///	    }*/	}	break;    case ConfigureNotify:    {	XConfigureEvent *ce = &event->xconfigure;	w = findWindowAtDisplay (d, ce->window);	if (!w)	    break;	if (w->prev)	{	    if (ce->above && ce->above == w->prev->id)		break;	}	else if (ce->above == None)	    break;	CompScreen *s = findScreenAtDisplay (d, event->xproperty.window);	if (!s)	    break;	ANIM_SCREEN(s);	int i;	int n = s->nClientList;	Bool winOpenedClosed = FALSE;	Window *clientList = (Window *) (s->clientList + n);	Window *clientListStacking = clientList + n;	if (n != as->nLastClientListStacking)	    winOpenedClosed = TRUE;	// if restacking occurred and not window open/close	if (!winOpenedClosed)	{	    ANIM_WINDOW(w);	    aw->configureNotified = TRUE;	    // Find which window is restacked 	    // e.g. here 8507730 was raised:	    // 54526074 8507730 48234499 14680072 6291497	    // 54526074 48234499 14680072 8507730 6291497	    // compare first changed win. of row 1 with last	    // changed win. of row 2, and vica versa	    // the matching one is the restacked one	    CompWindow *wRestacked = 0;	    CompWindow *wStart = 0;	    CompWindow *wEnd = 0;	    CompWindow *wOldAbove = 0;	    CompWindow *wChangeStart = 0;	    CompWindow *wChangeEnd = 0;	    Bool raised = FALSE;	    int changeStart = -1;	    int changeEnd = -1;	    for (i = 0; i < n; i++)	    {		CompWindow *wi =		    findWindowAtScreen (s, clientListStacking[i]);		// skip if minimized (prevents flashing problem)		if (!wi || !isWinVisible(wi))		    continue;		// skip if (tabbed and) hidden by Group plugin		if (wi->state & (CompWindowStateSkipPagerMask |				 CompWindowStateSkipTaskbarMask))		    continue;		if (clientListStacking[i] !=		    as->lastClientListStacking[i])		{		    if (changeStart < 0)		    {			changeStart = i;			wChangeStart = wi; // make use of already found w		    }		    else		    {			changeEnd = i;			wChangeEnd = wi;		    }		}		else if (changeStart >= 0) // found some change earlier		    break;	    }	    // if restacking occurred	    if (changeStart >= 0 && changeEnd >= 0)	    {		CompWindow *w2;		// if we have only 2 windows changed, 		// choose the one clicked on		Bool preferRaised = FALSE;		Bool onlyTwo = FALSE;		if (wChangeEnd &&		    clientListStacking[changeEnd] ==		    as->lastClientListStacking[changeStart] &&		    clientListStacking[changeStart] ==		    as->lastClientListStacking[changeEnd])		{		    // Check if the window coming on top was		    // configureNotified (clicked on)		    AnimWindow *aw2 = GET_ANIM_WINDOW(wChangeEnd, as);		    if (aw2->configureNotified)		    {			preferRaised = TRUE;		    }		    onlyTwo = TRUE;		}		// Clear all configureNotified's		for (w2 = s->windows; w2; w2 = w2->next)		{		    AnimWindow *aw2 = GET_ANIM_WINDOW(w2, as);		    aw2->configureNotified = FALSE;		}		if (preferRaised ||		    (!onlyTwo &&		     clientListStacking[changeEnd] ==		     as->lastClientListStacking[changeStart]))		{		    // raised		    raised = TRUE;		    wRestacked = wChangeEnd;		    wStart = wChangeStart;		    wEnd = wRestacked;		    wOldAbove = wStart;		}		else if (clientListStacking[changeStart] ==			 as->lastClientListStacking[changeEnd] && // lowered			 // We don't animate lowering if there is no			 // window above this window, since this window needs			 // to be drawn on such a "host" in animPaintWindow			 // (at least for now).			 changeEnd < n - 1)		{		    wRestacked = wChangeStart;		    wStart = wRestacked;		    wEnd = wChangeEnd;		    wOldAbove = findWindowAtScreen			(s, as->lastClientListStacking[changeEnd+1]);		}		for (; wOldAbove && !isWinVisible(wOldAbove);		     wOldAbove = wOldAbove->next)		    ;	    }	    if (wRestacked && wStart && wEnd && wOldAbove)	    {		AnimWindow *awRestacked = GET_ANIM_WINDOW(wRestacked, as);		if (awRestacked->created)		{		    RestackInfo *restackInfo = calloc(1, sizeof(RestackInfo));		    if (restackInfo)		    {			restackInfo->wRestacked = wRestacked;			restackInfo->wStart = wStart;			restackInfo->wEnd = wEnd;			restackInfo->wOldAbove = wOldAbove;			restackInfo->raised = raised;			if (awRestacked->restackInfo)			    free(awRestacked->restackInfo);			awRestacked->restackInfo = restackInfo;			as->aWinWasRestackedJustNow = TRUE;		    }		}	    }	}	updateLastClientListStacking(s);    }    break;    default:	break;    }    UNWRAP(ad, d, handleEvent);    (*d->handleEvent) (d, event);    WRAP(ad, d, handleEvent, animHandleEvent);    switch (event->type)    {    case PropertyNotify:	if (event->xproperty.atom == d->winActiveAtom &&	    d->activeWindow != ad->activeWindow)	{	    ad->activeWindow = d->activeWindow;	    w = findWindowAtDisplay(d, d->activeWindow);/*	    if (w)	    {		int duration = 200;		AnimEffect chosenEffect =		    getMatchingAnimSelection (w, WindowEventFocus, &duration);		if (!(chosenEffect == AnimEffectFocusFade ||		      chosenEffect == AnimEffectDodge))		    initiateFocusAnimation(w);	    }*/	}	break;    default:	break;    }}static inline BoolisWinVisible(CompWindow *w){    return (!w->destroyed &&	    !(!w->shaded &&	      (w->attrib.map_state != IsViewable)));}static voidupdateLastClientListStacking(CompScreen *s){    ANIM_SCREEN(s);    int n = s->nClientList;    Window *clientListStacking = (Window *) (s->clientList + n) + n;    if (as->nLastClientListStacking != n) // the number of windows has changed    {	Window *list;	list = realloc (as->lastClientListStacking, sizeof (Window) * n);	as->lastClientListStacking  = list;	if (!list)	{	    as->nLastClientListStacking = 0;	    return;	}	as->nLastClientListStacking = n;    }    // Store new client stack listing    memcpy(as->lastClientListStacking, clientListStacking,	   sizeof (Window) * n);}static Bool animGetWindowIconGeometry(CompWindow * w, XRectangle * rect){    Atom actual;    int result, format;    unsigned long n, left;    unsigned char *data;    ANIM_DISPLAY(w->screen->display);    result = XGetWindowProperty(w->screen->display->display, w->id,				ad->winIconGeometryAtom,				0L, 4L, FALSE, XA_CARDINAL, &actual,				&format, &n, &left, &data);    if (result == Success && n && data)    {	if (n == 4)	{	    unsigned long *geometry = (unsigned long *)data;	    rect->x = geometry[0];	    rect->y = geometry[1];	    rect->width = geometry[2];	    rect->height = geometry[3];	    XFree(data);	    return TRUE;	}	XFree(data);    }    return FALSE;}static BoolwindowHasUserTime(CompWindow *w){    Time t;    return getWindowUserTime (w, &t);}