static void
scaleaddonCheckWindowHighlight (CompScreen *s)
{
    CompDisplay *d = s->display;

    ADDON_DISPLAY (d);

    if (ad->highlightedWindow != ad->lastHighlightedWindow)
    {
        CompWindow *w;

        w = findWindowAtDisplay (d, ad->highlightedWindow);
        if (w)
        {
            scaleaddonRenderWindowTitle (w);
            addWindowDamage (w);
        }

        w = findWindowAtDisplay (d, ad->lastHighlightedWindow);
        if (w)
        {
            scaleaddonRenderWindowTitle (w);
            addWindowDamage (w);
        }

        ad->lastHighlightedWindow = ad->highlightedWindow;
    }
}
예제 #2
0
파일: minimize.c 프로젝트: jordigh/fusilli
static void
minDonePaintScreen (CompScreen *s)
{
	MIN_SCREEN (s);

	if (ms->moreAdjust)
	{
		CompWindow *w;
		int        h;

		for (w = s->windows; w; w = w->next)
		{
			MIN_WINDOW (w);

			if (mw->adjust)
			{
				addWindowDamage (w);
			}
			else if (mw->region)
			{
				h = w->attrib.height + w->attrib.border_width * 2;
				if (mw->shade && mw->shade < h)
					addWindowDamage (w);
			}
		}
	}

	UNWRAP (ms, s, donePaintScreen);
	(*s->donePaintScreen) (s);
	WRAP (ms, s, donePaintScreen, minDonePaintScreen);
}
static void
fadeHandleEvent (CompDisplay *d,
		 XEvent      *event)
{
    CompWindow *w;

    FADE_DISPLAY (d);

    switch (event->type) {
    case DestroyNotify:
	w = findWindowAtDisplay (d, event->xdestroywindow.window);
	if (w)
	{
	    FADE_WINDOW (w);

	    if (!fw->direction)
		fw->opacity = OPAQUE - 1;

	    fw->direction = -1;
	    fw->destroyed = 1;

	    addWindowDamage (w);
	    return;
	}
	break;
    case UnmapNotify:
	w = findWindowAtDisplay (d, event->xunmap.window);
	if (w)
	{
	    FADE_WINDOW (w);

	    if (!fw->direction)
		fw->opacity = OPAQUE - 1;

	    fw->direction = -1;

	    addWindowDamage (w);
	    return;
	}
	break;
    case MapNotify:
	w = findWindowAtDisplay (d, event->xunmap.window);
	if (w)
	{
	    FADE_WINDOW (w);

	    /* make sure any pending unmap are processed */
	    if (fw->direction < 0)
		unmapWindow (w);
	}
    default:
	break;
    }

    UNWRAP (fd, d, handleEvent);
    (*d->handleEvent) (d, event);
    WRAP (fd, d, handleEvent, fadeHandleEvent);
}
static Bool
stepPositions(CompScreen *s, int elapsed)
{
	int i, numSnow, numAutumn, numStars, numFf, numBubbles, numTmp;
	element *ele;
	Bool onTopOfWindows;
	Bool active = elementActive(s);

	E_SCREEN(s);

	if (!active)
		return TRUE;

	ele = eScreen->allElements;

	if (eScreen->isActive[0])
		numAutumn = elementsGetNumLeaves (s->display);
	else
		numAutumn = 0;
	if (eScreen->isActive[1])
		numFf = elementsGetNumFireflies (s->display);
	else
		numFf = 0;
	if (eScreen->isActive[2])
		numSnow = elementsGetNumSnowflakes (s->display);
	else
		numSnow = 0;
	if (eScreen->isActive[3])
		numStars = elementsGetNumStars (s->display);
	else
		numStars = 0;
	if (eScreen->isActive[4])
		numBubbles = elementsGetNumBubbles (s->display);
	else
		numBubbles = 0;

	numTmp = numAutumn + numFf + numSnow + numStars + numBubbles;
	onTopOfWindows = elementsGetOverWindows (s->display);
	for (i = 0; i < numTmp; i++)
		elementTestCreate(eScreen, ele++, elapsed);
	if (active)
	{
		CompWindow *w;
		for (w = s->windows; w; w = w->next)
		{
			if (!onTopOfWindows && (w->type & CompWindowTypeDesktopMask))
				addWindowDamage (w);
			else if (onTopOfWindows && isNormalWin(w)) {
				eScreen->topWindow = w;
				addWindowDamage (w);
			}
		}

		damageScreen (s);
	}

	return TRUE;
}
예제 #5
0
static Bool
stepSnowPositions (void *closure)
{
    CompScreen *s = closure;
    int        i, numFlakes;
    SnowFlake  *snowFlake;
    Bool       onTop;

    SNOW_SCREEN (s);

    if (!ss->active)
	return TRUE;

    snowFlake = ss->allSnowFlakes;
    numFlakes = starGetNumSnowflakes (s->display);
    onTop = starGetSnowOverWindows (s->display);

    for (i = 0; i < numFlakes; i++)
	snowThink(ss, snowFlake++);

    if (ss->active && !onTop)
    {
	CompWindow *w;

	for (w = s->windows; w; w = w->next)
	{
	    if (w->type & CompWindowTypeDesktopMask)
		addWindowDamage (w);
	}
    }
    else if (ss->active)
	damageScreen (s);

    return TRUE;
}
static Bool
stepPositions(void *closure)
{
	CompScreen *s = closure;
	int i, ii, numSnow, numAutumn, numStars, numFf, numBubbles, numTmp;
	element *ele;
	Bool onTopOfWindows;
	E_SCREEN(s);

	Bool active = FALSE;			//THis makes sure nothing happens if all features are off.
	for (ii = 0; ii <= 4; ii++)
	{
		if (eScreen->isActive[ii])
			active = TRUE;
	}

	if (!active)
		return TRUE;

	ele = eScreen->allElements;

	if (eScreen->isActive[0])
		numAutumn = elementsGetNumLeaves (s->display);	
	else
		numAutumn = 0;
	if (eScreen->isActive[1])
		numFf = elementsGetNumFireflies (s->display);
	else
		numFf = 0;
	if (eScreen->isActive[2])
		numSnow = elementsGetNumSnowflakes (s->display);
	else
		numSnow = 0;
	if (eScreen->isActive[3])
		numStars = elementsGetNumStars (s->display);
	else
		numStars = 0;
	if (eScreen->isActive[4])
		numBubbles = elementsGetNumBubbles (s->display);
	else
		numBubbles = 0;

	numTmp = numAutumn + numFf + numSnow + numStars + numBubbles;
	onTopOfWindows = elementsGetOverWindows (s->display);
	for (i = 0; i < numTmp; i++)
		elementTestCreate(eScreen, ele++);
	if (active && !onTopOfWindows )
	{
		CompWindow *w;
		for (w = s->windows; w; w = w->next)
		{
			if (w->type & CompWindowTypeDesktopMask)
				addWindowDamage (w);
		}
    	}
	else if (active)
		damageScreen (s);

	return TRUE;
예제 #7
0
파일: move.c 프로젝트: JeffHoogland/ecomp
static Bool
moveTerminate(CompDisplay    *d,
              CompAction     *action,
              CompActionState state,
              CompOption     *option,
              int             nOption)
{
   MOVE_DISPLAY (d);

   if (md->w)
     {
        MOVE_SCREEN (md->w->screen);

        (md->w->screen->windowUngrabNotify)(md->w);

        if (ms->grabIndex)
          {
             removeScreenGrab (md->w->screen, ms->grabIndex, NULL);
             ms->grabIndex = 0;
          }

        if (md->moveOpacity != OPAQUE)
          /* let the window fade in */
          addWindowDamage (md->w);
        else
          md->w = 0;
     }

   return FALSE;
}
static void
scaleaddonHandleEvent (CompDisplay *d,
                       XEvent      *event)
{
    ADDON_DISPLAY (d);

    UNWRAP (ad, d, handleEvent);
    (*d->handleEvent) (d, event);
    WRAP (ad, d, handleEvent, scaleaddonHandleEvent);

    switch (event->type)
    {
    case PropertyNotify:
    {
        if (event->xproperty.atom == XA_WM_NAME)
        {
            CompWindow *w;

            w = findWindowAtDisplay (d, event->xproperty.window);
            if (w)
            {
                SCALE_SCREEN (w->screen);
                if (ss->grabIndex)
                {
                    scaleaddonRenderWindowTitle (w);
                    addWindowDamage (w);
                }
            }
        }
    }
    break;
    case MotionNotify:
    {
        CompScreen *s;
        s = findScreenAtDisplay (d, event->xmotion.root);

        if (s)
        {
            SCALE_SCREEN (s);
            if (ss->grabIndex)
            {
                SCALE_DISPLAY (d);

                ad->highlightedWindow = sd->hoveredWindow;
                scaleaddonCheckWindowHighlight (s);
            }
        }
    }
    break;
    default:
        break;
    }
}
예제 #9
0
파일: opacify.c 프로젝트: jordigh/fusilli
/* Sets the real opacity and damages the window if actual opacity and
 * requested opacity differs. */
static void
setOpacity (CompWindow *w,
            int        opacity)
{
	OPACIFY_WINDOW (w);

	if (!ow->opacified || (w->paint.opacity != opacity))
		addWindowDamage (w);

	ow->opacified = TRUE;
	ow->opacity = opacity;
}
예제 #10
0
파일: move.c 프로젝트: JeffHoogland/ecomp
static Bool
moveInitiate(CompDisplay    *d,
             CompAction     *action,
             CompActionState state,
             CompOption     *option,
             int             nOption)
{
   CompWindow *w;
   Window xid;
   int i, x, y;
   unsigned int ui;
   unsigned int mods = 0;

   MOVE_DISPLAY (d);
   xid = getIntOptionNamed (option, nOption, "window", 0);

   w = findWindowAtDisplay (d, xid);
   if (!w) return FALSE;

   if (otherScreenGrabExist (w->screen, "move", 0))
     return FALSE;

   MOVE_SCREEN (w->screen);

   XQueryPointer (d->display, w->screen->root,
                  &xid, &xid, &x, &y, &i, &i, &ui);

   if (md->w)
     return FALSE;

   lastPointerX = x;
   lastPointerY = y;

   ms->origState = w->state;

   if (!ms->grabIndex)
     ms->grabIndex = pushScreenGrab (w->screen, 0, "move");

   if (ms->grabIndex)
     {
        md->w = w;

        (w->screen->windowGrabNotify)(w, x, y, mods,
                                      CompWindowGrabMoveMask |
                                      CompWindowGrabButtonMask);

        if (md->moveOpacity != OPAQUE)
          addWindowDamage (w);
     }

   return FALSE;
}
static void
NEGToggle (CompWindow *w)
{
    NEG_WINDOW (w);

    /* toggle window negative flag */
    nw->isNeg = !nw->isNeg;

    /* check exclude list */
    if (matchEval (negGetExcludeMatch (w->screen), w))
	nw->isNeg = FALSE;

    /* cause repainting */
    addWindowDamage (w);
}
/*
 * Toggle filtering for a specific window
 */
static void
colorFilterToggleWindow (CompWindow * w)
{
    FILTER_WINDOW (w);

    /* Toggle window filtering flag */
    cfw->isFiltered = !cfw->isFiltered;

    /* Check exclude list */
    if (matchEval (colorfilterGetExcludeMatch (w->screen), w))
	cfw->isFiltered = FALSE;

    /* Ensure window is going to be repainted */
    addWindowDamage (w);
}
예제 #13
0
파일: opacify.c 프로젝트: jordigh/fusilli
/* Resets the Window to the original opacity if it still exists.
 */
static void
resetOpacity (CompScreen *s,
              Window     id)
{
	CompWindow *w;

	w = findWindowAtScreen (s, id);
	if (!w)
		return;

	OPACIFY_WINDOW (w);

	ow->opacified = FALSE;

	addWindowDamage (w);
}
예제 #14
0
파일: snow.c 프로젝트: jordigh/fusilli
static Bool
stepSnowPositions (void *closure)
{
	CompScreen *s = closure;
	int        i, numFlakes;
	SnowFlake  *snowFlake;
	Bool       onTop;

	SNOW_SCREEN (s);

	if (!ss->active)
		return TRUE;

	const BananaValue *
	option_num_snowflakes = bananaGetOption (bananaIndex,
	                                         "num_snowflakes",
	                                         -1);

	const BananaValue *
	option_snow_over_windows = bananaGetOption (bananaIndex,
	                                            "snow_over_windows",
	                                            -1);

	snowFlake = ss->allSnowFlakes;
	numFlakes = option_num_snowflakes->i;
	onTop = option_snow_over_windows->b;

	for (i = 0; i < numFlakes; i++)
		snowThink(ss, snowFlake++);

	if (ss->active && !onTop)
	{
		CompWindow *w;

		for (w = s->windows; w; w = w->next)
		{
			if (w->type & CompWindowTypeDesktopMask)
				addWindowDamage (w);
		}
	}
	else if (ss->active)
		damageScreen (s);

	return TRUE;
}
예제 #15
0
/*
 * Switch current filter
 */
static void
colorFilterSwitchFilter (CompScreen *s)
{
	int id;
	CompFunction *function;
	CompWindow *w;

	FILTER_SCREEN (s);

	/* % (count + 1) because of the cumulative filters mode */
	cfs->currentFilter++;
	if (cfs->currentFilter >= cfs->filtersCount + 1)
		cfs->currentFilter = 0;

	if (cfs->currentFilter == 0)
		compLogMessage ("colorfilter", CompLogLevelInfo,
		                "Cumulative filters mode");
	else
	{
		id = cfs->filtersFunctions[cfs->currentFilter - 1];

		if (id)
		{
			function = findFragmentFunction (s, id);
			compLogMessage ("colorfilter", CompLogLevelInfo,
			                "Single filter mode (using %s filter)",
			                function->name);
		}
		else
		{
			compLogMessage ("colorfilter", CompLogLevelInfo,
			                "Single filter mode (filter loading failure)");
		}
	}

	/* Damage currently filtered windows */
	for (w = s->windows; w; w = w->next)
	{
		FILTER_WINDOW (w);

		if (cfw->isFiltered)
			addWindowDamage (w);
	}
}
예제 #16
0
static void
throwDonePaintScreen (CompScreen *s)
{
    THROW_SCREEN (s);
    CompWindow *w;
    for (w = s->windows; w; w = w->next)
    {
	THROW_WINDOW (w);
	if (tw->moving ||
	    (tw->xVelocity < 0.0f || tw->xVelocity > 0.0f) ||
	    (tw->yVelocity < 0.0f || tw->yVelocity > 0.0f))
	{
	    addWindowDamage (w);
	}
    }

    UNWRAP (ts, s, donePaintScreen);
    (*s->donePaintScreen) (s);
    WRAP (ts, s, donePaintScreen, throwDonePaintScreen);
}
예제 #17
0
파일: move.c 프로젝트: JeffHoogland/ecomp
static Bool
movePaintWindow(CompWindow *w, const WindowPaintAttrib *attrib,
                const CompTransform *transform, Region region, unsigned int mask)
{
   WindowPaintAttrib sAttrib;
   CompScreen *s = w->screen;
   Bool status;

   MOVE_SCREEN (s);

   if (ms->active)
     {
        MOVE_DISPLAY (s->display);

        addWindowDamage(w);

        if (md->w == w && md->moveOpacity != OPAQUE)
          {
             sAttrib = *attrib;
             attrib = &sAttrib;
             sAttrib.opacity = (sAttrib.opacity + ((int)(sAttrib.opacity *
                                                         md->moveOpacity * ms->progress))) >> 16;
          }
예제 #18
0
static void
swapDoWindowDamage (CompWindow *w)
{
    if (w->attrib.map_state == IsViewable || w->shaded)
	addWindowDamage (w);
    else
    {
	BoxRec box;
	if (swapGetPaintRectangle (w, &box, NULL))
	{
	    REGION reg;

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

	    reg.extents.x1 = box.x1 - 2;
	    reg.extents.y1 = box.y1 - 2;
	    reg.extents.x2 = box.x2 + 2;
	    reg.extents.y2 = box.y2 + 2;

	    damageScreenRegion (w->screen, &reg);
	}
    }
}
예제 #19
0
static Bool
scaleaddonPullWindow(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) {
			int x, y, vx, vy;

			defaultViewportForWindow(w, &vx, &vy);

			x = w->attrib.x + (s->x - vx) * s->width;
			y = w->attrib.y + (s->y - vy) * s->height;

			if (scaleaddonGetConstrainPullToScreen(s)) {
				XRectangle workArea;
				CompWindowExtents extents;

				getWorkareaForOutput(s,
						     outputDeviceForWindow(w),
						     &workArea);

				extents.left = x - w->input.left;
				extents.right = x + w->width + w->input.right;
				extents.top = y - w->input.top;
				extents.bottom =
				    y + w->height + w->input.bottom;

				if (extents.left < workArea.x)
					x += workArea.x - extents.left;
				else if (extents.right >
					 workArea.x + workArea.width)
					x += workArea.x + workArea.width -
					    extents.right;

				if (extents.top < workArea.y)
					y += workArea.y - extents.top;
				else if (extents.bottom >
					 workArea.y + workArea.height)
					y += workArea.y + workArea.height -
					    extents.bottom;
			}

			if (x != w->attrib.x || y != w->attrib.y) {
				SCALE_WINDOW(w);

				moveWindowToViewportPosition(w, x, y, TRUE);

				/* Select this window when ending scale */
				(*ss->selectWindow) (w);

				/* stop scaled window dissapearing */
				sw->tx -= (s->x - vx) * s->width;
				sw->ty -= (s->y - vy) * s->height;

				if (scaleaddonGetExitAfterPull(s)) {
					int opt;
					CompAction *action2;
					CompOption o[1];

					SCALE_DISPLAY(d);

					opt = SCALE_DISPLAY_OPTION_INITIATE_KEY;
					action2 = &sd->opt[opt].value.action;

					o[0].type = CompOptionTypeInt;
					o[0].name = "root";
					o[0].value.i = s->root;

					if (action2->terminate)
						(*action2->terminate) (d,
								       action,
								       0, o, 1);
				} else {
					/* provide a simple animation */
					addWindowDamage(w);

					sw->tx -=
					    (sw->slot->x2 - sw->slot->x1) / 20;
					sw->ty -=
					    (sw->slot->y2 - sw->slot->y1) / 20;
					sw->scale *= 1.1f;
					sw->adjust = TRUE;

					ss->state = SCALE_STATE_OUT;
					addWindowDamage(w);
				}

				return TRUE;
			}
		}
	}

	return FALSE;
}
예제 #20
0
파일: minimize.c 프로젝트: jordigh/fusilli
static Bool
minDamageWindowRect (CompWindow *w,
                     Bool       initial,
                     BoxPtr     rect)
{
	Bool status = FALSE;

	MIN_SCREEN (w->screen);
	MIN_WINDOW (w);

	if (mw->ignoreDamage)
		return TRUE;

	if (initial)
	{
		if (mw->state == IconicState)
		{
			mw->state = NormalState;

			if (!w->invisible      &&
			    w->iconGeometrySet &&
			    matchEval (&ms->match, w))
			{
				if (!mw->adjust)
				{
					mw->adjust     = TRUE;
					ms->moreAdjust = TRUE;

					mw->tx     = w->iconGeometry.x - w->serverX;
					mw->ty     = w->iconGeometry.y - w->serverY;
					mw->xScale = (float) w->iconGeometry.width  / w->width;
					mw->yScale = (float) w->iconGeometry.height / w->height;

					addWindowDamage (w);
				}
			}
		}
		else if (mw->region && mw->shade < w->height)
		{
			if (ms->shadeStep && !w->invisible)
			{
				XSubtractRegion (w->region, &emptyRegion, mw->region);
				XOffsetRegion (mw->region, -w->attrib.x, -w->attrib.y);

				/* bind pixmap here so we have something to unshade with */
				if (!w->texture->pixmap && !w->bindFailed)
					bindWindow (w);

				ms->moreAdjust = TRUE;
			}
			else
			{
				mw->shade = MAXSHORT;
			}
		}

		mw->newState = NormalState;
	}
	else if (mw->adjust)
	{
		damageTransformedWindowRect (w,
		                         mw->xScale,
		                         mw->yScale,
		                         mw->tx,
		                         mw->ty,
		                         rect);

		status = TRUE;
	}

	UNWRAP (ms, w->screen, damageWindowRect);
	status |= (*w->screen->damageWindowRect) (w, initial, rect);
	WRAP (ms, w->screen, damageWindowRect, minDamageWindowRect);

	return status;
}
예제 #21
0
파일: minimize.c 프로젝트: jordigh/fusilli
static void
minHandleEvent (XEvent      *event)
{
	CompWindow *w;

	MIN_DISPLAY (&display);

	switch (event->type) {
	case MapNotify:
		w = findWindowAtDisplay (event->xmap.window);
		if (w)
		{
			MIN_WINDOW (w);

			if (mw->adjust)
				mw->state = mw->newState;

			if (mw->region)
				w->height = 0;

			mw->ignoreDamage = TRUE;
			while (mw->unmapCnt)
			{
				unmapWindow (w);
				mw->unmapCnt--;
			}
			mw->ignoreDamage = FALSE;
		}
		break;
	case UnmapNotify:
		w = findWindowAtDisplay (event->xunmap.window);
		if (w)
		{
			MIN_SCREEN (w->screen);

			if (w->pendingUnmaps && onCurrentDesktop (w)) /* Normal -> Iconic */
			{
				MIN_WINDOW (w);

				if (w->shaded)
				{
					if (!mw->region)
						mw->region = XCreateRegion ();

					if (mw->region && ms->shadeStep)
					{
						XSubtractRegion (w->region, &emptyRegion, mw->region);
						XOffsetRegion (mw->region, -w->attrib.x,
						           w->attrib.height +
						           w->attrib.border_width * 2 -
						           w->height - w->attrib.y);

						mw->shade = w->height;

						mw->adjust     = FALSE;
						ms->moreAdjust = TRUE;

						mw->unmapCnt++;
						w->unmapRefCnt++;

						addWindowDamage (w);
					}
				}
				else if (!w->invisible && matchEval (&ms->match, w))
				{
					if (w->iconGeometrySet)
					{
						mw->newState = IconicState;

						mw->xScale = w->paint.xScale;
						mw->yScale = w->paint.yScale;
						mw->tx     = w->attrib.x - w->serverX;
						mw->ty     = w->attrib.y - w->serverY;

						if (mw->region)
						{
							XDestroyRegion (mw->region);
							mw->region = NULL;
						}

						mw->shade = MAXSHORT;

						mw->adjust     = TRUE;
						ms->moreAdjust = TRUE;

						mw->unmapCnt++;
						w->unmapRefCnt++;

						addWindowDamage (w);
					}
				}
			}
			else  /* X -> Withdrawn */
			{
				MIN_WINDOW (w);

				if (mw->adjust)
				{
					mw->adjust = FALSE;
					mw->xScale = mw->yScale = 1.0f;
					mw->tx = mw->ty = 0.0f;
					mw->xVelocity = mw->yVelocity = 0.0f;
					mw->xScaleVelocity = mw->yScaleVelocity = 1.0f;
					mw->shade = MAXSHORT;

					if (mw->region)
					{
						XDestroyRegion (mw->region);
						mw->region = NULL;
					}
				}

				mw->state = NormalState;
			}
		}
	default:
		break;
	}

	UNWRAP (md, &display, handleEvent);
	(*display.handleEvent) (event);
	WRAP (md, &display, handleEvent, minHandleEvent);

	switch (event->type) {
	case MapRequest:
		w = findWindowAtDisplay (event->xmaprequest.window);
		if (w && w->hints && w->hints->initial_state == IconicState)
		{
			MIN_WINDOW (w);
			mw->newState = mw->state = IconicState;
		}
		break;
	default:
		break;
	}
}
예제 #22
0
파일: minimize.c 프로젝트: jordigh/fusilli
static void
minPreparePaintScreen (CompScreen *s,
                       int        msSinceLastPaint)
{
	MIN_SCREEN (s);

	if (ms->moreAdjust)
	{
		CompWindow *w;
		int        steps, h;
		float      amount, chunk;

		const BananaValue *
		option_speed = bananaGetOption (bananaIndex, "speed", s->screenNum);

		amount = msSinceLastPaint * 0.05f * option_speed->f;

		const BananaValue *
		option_timestep = bananaGetOption (bananaIndex,
		                                   "timestep",
		                                   s->screenNum);

		steps  = amount / (0.5f * option_timestep->f);
		if (!steps) steps = 1;
		chunk  = amount / (float) steps;

		while (steps--)
		{
			ms->moreAdjust = 0;

			for (w = s->windows; w; w = w->next)
			{
				MIN_WINDOW (w);

				if (mw->adjust)
				{
					mw->adjust = adjustMinVelocity (w);

					ms->moreAdjust |= mw->adjust;

					mw->tx += mw->xVelocity * chunk;
					mw->ty += mw->yVelocity * chunk;
					mw->xScale += mw->xScaleVelocity * chunk;
					mw->yScale += mw->yScaleVelocity * chunk;

					if (!mw->adjust)
					{
						mw->state = mw->newState;

						mw->ignoreDamage = TRUE;
						while (mw->unmapCnt)
						{
							unmapWindow (w);
							mw->unmapCnt--;
						}
						mw->ignoreDamage = FALSE;
					}
				}
				else if (mw->region && w->damaged)
				{
					if (w->shaded)
					{
						if (mw->shade > 0)
						{
							mw->shade -= (chunk * ms->shadeStep) + 1;

							if (mw->shade > 0)
							{
								ms->moreAdjust = TRUE;
							}
							else
							{
								mw->shade = 0;

								mw->ignoreDamage = TRUE;
								while (mw->unmapCnt)
								{
									unmapWindow (w);
									mw->unmapCnt--;
								}
								mw->ignoreDamage = FALSE;
							}
						}
					}
					else
					{
						h = w->attrib.height + w->attrib.border_width * 2;
						if (mw->shade < h)
						{
							mw->shade += (chunk * ms->shadeStep) + 1;

							if (mw->shade < h)
							{
								ms->moreAdjust = TRUE;
							}
							else
							{
								mw->shade = MAXSHORT;

								minSetShade (w, h);

								XDestroyRegion (mw->region);
								mw->region = NULL;

								addWindowDamage (w);
							}
						}
					}
				}
			}

			if (!ms->moreAdjust)
				break;
		}

		if (ms->moreAdjust)
		{
			for (w = s->windows; w; w = w->next)
			{
				MIN_WINDOW (w);

				if (mw->adjust)
				{
					addWindowDamage (w);
				}
				else if (mw->region && w->damaged)
				{
					h = w->attrib.height + w->attrib.border_width * 2;
					if (mw->shade && mw->shade < h)
					{
						minSetShade (w, mw->shade);
						addWindowDamage (w);
					}
				}
			}
		}
	}

	UNWRAP (ms, s, preparePaintScreen);
	(*s->preparePaintScreen) (s, msSinceLastPaint);
	WRAP (ms, s, preparePaintScreen, minPreparePaintScreen);
}
예제 #23
0
/*
 * Load filters from a list of files for current screen
 */
static int
loadFilters (CompScreen  *s,
             CompTexture *texture)
{
	int i, target, loaded, function, count;
	char *name;
	CompWindow *w;

	FILTER_SCREEN (s);

	cfs->filtersLoaded = TRUE;

	/* Fetch filters filenames */
	const BananaValue *
	option_filters = bananaGetOption (bananaIndex,
	                                  "filters",
	                                  s->screenNum);

	count = option_filters->list.nItem;

	/* The texture target that will be used for some ops */
	if (texture->target == GL_TEXTURE_2D)
		target = COMP_FETCH_TARGET_2D;
	else
		target = COMP_FETCH_TARGET_RECT;

	/* Free previously loaded filters and malloc */
	unloadFilters (s);
	cfs->filtersFunctions = malloc (sizeof (int) * count);

	if (!cfs->filtersFunctions)
		return 0;

	cfs->filtersCount = count;

	/* Load each filter one by one */
	loaded = 0;

	for (i = 0; i < count; i++)
	{
		name = base_name (option_filters->list.item[i].s);
		if (!name || !strlen (name))
		{
			if (name)
				free (name);

			cfs->filtersFunctions[i] = 0;
			continue;
		}

		compLogMessage ("colorfilter", CompLogLevelInfo,
		                "Loading filter %s (item %s).", name,
		                option_filters->list.item[i].s);

		function = loadFragmentProgram (option_filters->list.item[i].s, name, s, target);
		free (name);

		cfs->filtersFunctions[i] = function;

		if (function)
			loaded++;
	}

	/* Warn if there was at least one loading failure */
	if (loaded < count)
		compLogMessage ("colorfilter", CompLogLevelWarn,
		                "Tried to load %d filter(s), %d succeeded.",
		                count, loaded);

	if (!loaded)
		cfs->filtersCount = 0;

	/* Damage currently filtered windows */
	for (w = s->windows; w; w = w->next)
	{
		FILTER_WINDOW (w);

		if (cfw->isFiltered)
			addWindowDamage (w);
	}

	return loaded;
}
예제 #24
0
/*
 * groupGroupWindows
 *
 */
Bool
groupGroupWindows (Window xid)
{
	CompScreen *s;

	s = findScreenAtDisplay (xid);

	if (s)
	{
		GROUP_SCREEN (s);

		if (gs->tmpSel.nWins > 0)
		{
			int i;
			CompWindow     *cw;
			GroupSelection *group = NULL;
			Bool tabbed = FALSE;

			for (i = 0; i < gs->tmpSel.nWins; i++)
			{
				cw = gs->tmpSel.windows[i];
				GROUP_WINDOW (cw);

				if (gw->group)
				{
					if (!tabbed || group->tabBar)
						group = gw->group;

					if (group->tabBar)
						tabbed = TRUE;
				}
			}

			/* we need to do one first to get the pointer of a new group */
			cw = gs->tmpSel.windows[0];
			GROUP_WINDOW (cw);

			if (gw->group && (group != gw->group))
				groupDeleteGroupWindow (cw);
			groupAddWindowToGroup (cw, group, 0);
			addWindowDamage (cw);

			gw->inSelection = FALSE;
			group = gw->group;

			for (i = 1; i < gs->tmpSel.nWins; i++)
			{
				cw = gs->tmpSel.windows[i];
				GROUP_WINDOW (cw);

				if (gw->group && (group != gw->group))
					groupDeleteGroupWindow (cw);
				groupAddWindowToGroup (cw, group, 0);
				addWindowDamage (cw);

				gw->inSelection = FALSE;
			}

			/* exit selection */
			free (gs->tmpSel.windows);
			gs->tmpSel.windows = NULL;
			gs->tmpSel.nWins = 0;
		}
	}

	return FALSE;
}
예제 #25
0
파일: fade.c 프로젝트: zmike/compiz
static void
fadeHandleEvent(CompDisplay *d,
                XEvent *event)
{
   CompWindow *w;

   FADE_DISPLAY(d);

   switch (event->type)
     {
      case DestroyNotify:
        w = findWindowAtDisplay(d, event->xdestroywindow.window);
        if (w)
          {
             FADE_SCREEN(w->screen);

             if (w->texture->pixmap && isFadeWinForOpenClose(w) &&
                 matchEval(&fs->match, w))
               {
                  FADE_WINDOW(w);

                  if (fw->opacity == 0xffff)
                    fw->opacity = 0xfffe;

                  fw->destroyCnt++;
                  w->destroyRefCnt++;

                  fw->fadeOut = TRUE;

                  addWindowDamage(w);
               }

             fadeRemoveDisplayModal(d, w);
          }
        break;

      case UnmapNotify:
        w = findWindowAtDisplay(d, event->xunmap.window);
        if (w)
          {
             FADE_SCREEN(w->screen);
             FADE_WINDOW(w);

             fw->shaded = w->shaded;

             if (fs->opt[FADE_SCREEN_OPTION_MINIMIZE_OPEN_CLOSE].value.b &&
                 !fd->suppressMinimizeOpenClose &&
                 !fw->shaded && w->texture->pixmap &&
                 matchEval(&fs->match, w))
               {
                  if (fw->opacity == 0xffff)
                    fw->opacity = 0xfffe;

                  fw->unmapCnt++;
                  w->unmapRefCnt++;

                  fw->fadeOut = TRUE;

                  addWindowDamage(w);
               }

             fadeRemoveDisplayModal(d, w);
          }
        break;

      case MapNotify:
        w = findWindowAtDisplay(d, event->xmap.window);
        if (w)
          {
             FADE_SCREEN(w->screen);

             if (fs->opt[FADE_SCREEN_OPTION_MINIMIZE_OPEN_CLOSE].value.b &&
                 !fd->suppressMinimizeOpenClose)
               {
                  fadeWindowStop(w);
               }
             if (w->state & CompWindowStateDisplayModalMask)
               fadeAddDisplayModal(d, w);
          }
        break;

      default:
        if (event->type == d->xkbEvent)
          {
             XkbAnyEvent *xkbEvent = (XkbAnyEvent *)event;

             if (xkbEvent->xkb_type == XkbBellNotify)
               {
                  XkbBellNotifyEvent *xkbBellEvent = (XkbBellNotifyEvent *)
                    xkbEvent;

                  w = findWindowAtDisplay(d, xkbBellEvent->window);
                  if (!w)
                    w = findWindowAtDisplay(d, d->activeWindow);

                  if (w)
                    {
                       CompScreen *s = w->screen;

                       FADE_SCREEN(s);

                       if (fs->opt[FADE_SCREEN_OPTION_VISUAL_BELL].value.b)
                         {
                            int option;

                            option = FADE_SCREEN_OPTION_FULLSCREEN_VISUAL_BELL;
                            if (fs->opt[option].value.b)
                              {
                                 for (w = s->windows; w; w = w->next)
                                   {
                                      if (w->destroyed)
                                        continue;

                                      if (w->attrib.map_state != IsViewable)
                                        continue;

                                      if (w->damaged)
                                        {
                                           FADE_WINDOW(w);

                                           fw->brightness = w->paint.brightness / 2;
                                        }
                                   }

                                 damageScreen(s);
                              }
                            else
                              {
                                 FADE_WINDOW(w);

                                 fw->brightness = w->paint.brightness / 2;

                                 addWindowDamage(w);
                              }
                         }
                    }
               }
          }
        break;
     }

   UNWRAP(fd, d, handleEvent);
   (*d->handleEvent)(d, event);
   WRAP(fd, d, handleEvent, fadeHandleEvent);

   switch (event->type)
     {
      case PropertyNotify:
        if (event->xproperty.atom == d->winStateAtom)
          {
             w = findWindowAtDisplay(d, event->xproperty.window);
             if (w && w->attrib.map_state == IsViewable)
               {
                  if (w->state & CompWindowStateDisplayModalMask)
                    fadeAddDisplayModal(d, w);
                  else
                    fadeRemoveDisplayModal(d, w);
               }
          }
        break;

      case ClientMessage:
        if (event->xclient.message_type == d->wmProtocolsAtom &&
            event->xclient.data.l[0] == d->wmPingAtom)
          {
             w = findWindowAtDisplay(d, event->xclient.data.l[2]);
             if (w)
               {
                  FADE_WINDOW(w);

                  if (w->alive != fw->alive)
                    {
                       addWindowDamage(w);
                       fw->alive = w->alive;
                    }
               }
          }
     }
}
예제 #26
0
파일: fade.c 프로젝트: zmike/compiz
static Bool
fadePaintWindow(CompWindow *w,
                const WindowPaintAttrib *attrib,
                const CompTransform *transform,
                Region region,
                unsigned int mask)
{
   CompScreen *s = w->screen;
   Bool status;

   FADE_DISPLAY(s->display);
   FADE_SCREEN(s);
   FADE_WINDOW(w);

   if (!w->screen->canDoSlightlySaturated)
     fw->saturation = attrib->saturation;

   if (!w->alive ||
       fw->destroyCnt ||
       fw->unmapCnt ||
       fw->opacity != attrib->opacity ||
       fw->brightness != attrib->brightness ||
       fw->saturation != attrib->saturation ||
       fd->displayModals)
     {
        WindowPaintAttrib fAttrib = *attrib;
        int mode = fs->opt[FADE_SCREEN_OPTION_FADE_MODE].value.i;

        if (!w->alive && fs->opt[FADE_SCREEN_OPTION_DIM_UNRESPONSIVE].value.b)
          {
             GLuint value;

             value = fs->opt[FADE_SCREEN_OPTION_UNRESPONSIVE_BRIGHTNESS].value.i;
             if (value != 100)
               fAttrib.brightness = fAttrib.brightness * value / 100;

             value = fs->opt[FADE_SCREEN_OPTION_UNRESPONSIVE_SATURATION].value.i;
             if (value != 100 && s->canDoSlightlySaturated)
               fAttrib.saturation = fAttrib.saturation * value / 100;
          }
        else if (fd->displayModals && !fw->dModal)
          {
             fAttrib.brightness = 0xa8a8;
             fAttrib.saturation = 0;
          }

        if (fw->fadeOut)
          fAttrib.opacity = 0;

        if (mode == FADE_MODE_CONSTANTTIME)
          {
             if (fAttrib.opacity != fw->targetOpacity ||
                 fAttrib.brightness != fw->targetBrightness ||
                 fAttrib.saturation != fw->targetSaturation)
               {
                  fw->fadeTime = fs->opt[FADE_SCREEN_OPTION_FADE_TIME].value.i;
                  fw->steps = 1;

                  fw->opacityDiff = fAttrib.opacity - fw->opacity;
                  fw->brightnessDiff = fAttrib.brightness - fw->brightness;
                  fw->saturationDiff = fAttrib.saturation - fw->saturation;

                  fw->targetOpacity = fAttrib.opacity;
                  fw->targetBrightness = fAttrib.brightness;
                  fw->targetSaturation = fAttrib.saturation;
               }
          }

        if (fw->steps)
          {
             GLint opacity = OPAQUE;
             GLint brightness = BRIGHT;
             GLint saturation = COLOR;

             if (mode == FADE_MODE_CONSTANTSPEED)
               {
                  opacity = fw->opacity;
                  if (fAttrib.opacity > fw->opacity)
                    {
                       opacity = fw->opacity + fw->steps;
                       if (opacity > fAttrib.opacity)
                         opacity = fAttrib.opacity;
                    }
                  else if (fAttrib.opacity < fw->opacity)
                    {
                       opacity = fw->opacity - fw->steps;
                       if (opacity < fAttrib.opacity)
                         opacity = fAttrib.opacity;
                    }

                  brightness = fw->brightness;
                  if (fAttrib.brightness > fw->brightness)
                    {
                       brightness = fw->brightness + (fw->steps / 12);
                       if (brightness > fAttrib.brightness)
                         brightness = fAttrib.brightness;
                    }
                  else if (fAttrib.brightness < fw->brightness)
                    {
                       brightness = fw->brightness - (fw->steps / 12);
                       if (brightness < fAttrib.brightness)
                         brightness = fAttrib.brightness;
                    }

                  saturation = fw->saturation;
                  if (fAttrib.saturation > fw->saturation)
                    {
                       saturation = fw->saturation + (fw->steps / 6);
                       if (saturation > fAttrib.saturation)
                         saturation = fAttrib.saturation;
                    }
                  else if (fAttrib.saturation < fw->saturation)
                    {
                       saturation = fw->saturation - (fw->steps / 6);
                       if (saturation < fAttrib.saturation)
                         saturation = fAttrib.saturation;
                    }
               }
             else if (mode == FADE_MODE_CONSTANTTIME)
               {
                  int fadeTime = fs->opt[FADE_SCREEN_OPTION_FADE_TIME].value.i;

                  opacity = fAttrib.opacity -
                    (fw->opacityDiff * fw->fadeTime / fadeTime);
                  brightness = fAttrib.brightness -
                    (fw->brightnessDiff * fw->fadeTime / fadeTime);
                  saturation = fAttrib.saturation -
                    (fw->saturationDiff * fw->fadeTime / fadeTime);
               }

             fw->steps = 0;

             if (opacity > 0)
               {
                  fw->opacity = opacity;
                  fw->brightness = brightness;
                  fw->saturation = saturation;

                  if (opacity != fAttrib.opacity ||
                      brightness != fAttrib.brightness ||
                      saturation != fAttrib.saturation)
                    addWindowDamage(w);
               }
             else
               {
                  fw->opacity = 0;

                  fadeWindowStop(w);
               }
          }

        fAttrib.opacity = fw->opacity;
        fAttrib.brightness = fw->brightness;
        fAttrib.saturation = fw->saturation;

        UNWRAP(fs, s, paintWindow);
        status = (*s->paintWindow)(w, &fAttrib, transform, region, mask);
        WRAP(fs, s, paintWindow, fadePaintWindow);
     }
   else
     {
        UNWRAP(fs, s, paintWindow);
        status = (*s->paintWindow)(w, attrib, transform, region, mask);
        WRAP(fs, s, paintWindow, fadePaintWindow);
     }

   return status;
}
예제 #27
0
static void
swapToWindow (CompScreen *s,
	      Bool       toNext)
{
    CompWindow *w;
    int	       cur, nextIdx;

    SWAP_SCREEN (s);

    if (!ss->grabIndex)
	return;

    for (cur = 0; cur < ss->nWindows; cur++)
    {
	if (ss->windows[cur]->id == ss->selectedWindow)
	    break;
    }

    if (cur == ss->nWindows)
	return;

    if (toNext)
	nextIdx = (cur + 1) % ss->nWindows;
    else
	nextIdx = (cur + ss->nWindows - 1) % ss->nWindows;

    w = ss->windows[nextIdx];

    if (w)
    {
	Window old = ss->selectedWindow;

	if (ss->selection == AllViewports && swapGetAutoChangeVp (s))
	{
	    XEvent xev;
	    int	   x, y;

	    defaultViewportForWindow (w, &x, &y);

	    xev.xclient.type = ClientMessage;
	    xev.xclient.display = s->display->display;
	    xev.xclient.format = 32;

	    xev.xclient.message_type = s->display->desktopViewportAtom;
	    xev.xclient.window = s->root;

	    xev.xclient.data.l[0] = x * s->width;
	    xev.xclient.data.l[1] = y * s->height;
	    xev.xclient.data.l[2] = 0;
	    xev.xclient.data.l[3] = 0;
	    xev.xclient.data.l[4] = 0;

	    XSendEvent (s->display->display, s->root, FALSE,
			SubstructureRedirectMask | SubstructureNotifyMask,
			&xev);
	}

	ss->selectedWindow = w->id;

	if (old != w->id)
	{
	    ss->move = nextIdx;

	    ss->moreAdjust = 1;
	}

	if (ss->popupWindow)
	{
	    CompWindow *popup;

	    popup = findWindowAtScreen (s, ss->popupWindow);
	    if (popup)
		addWindowDamage (popup);

	    swapSetSelectedWindowHint (s);
	}

	swapDoWindowDamage (w);

	if (old)
	{
	    w = findWindowAtScreen (s, old);
	    if (w)
		swapDoWindowDamage (w);
	}
    }
}
예제 #28
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;
}
예제 #29
0
static Bool
smartputInitiate (CompWindow      *w,
		  CompAction      *action,
		  CompActionState state,
		  CompOption	 *option,
		  int             nOption,
		  Bool            undo)
{
    CompDisplay *d;
    if (w)
    {
	CompScreen* s = w->screen;

	SMARTPUT_SCREEN (s);

	if(otherScreenGrabExist (s, "smartput", 0))
	    return FALSE;
	/*
	 * Grab the screen
	 */
	if(!sps->grabIndex)
	    sps->grabIndex = pushScreenGrab (s, s->invisibleCursor, "smartput");
	if(!sps->grabIndex)
	    return FALSE;

	int            width, height;
	unsigned int   mask;
	XWindowChanges *xwc;

	d = s->display;
	SMARTPUT_WINDOW (w);

	if(spw->xwc) free(spw->xwc);
	xwc = malloc(sizeof(XWindowChanges));

	if(undo)
	{
	    if(!(w->id == sps->undoInfo.window) || sps->undoInfo.window == None) return FALSE;
	    mask = smartputUndoResize (s,xwc);
	}
	else if(w->id == sps->undoInfo.window && !(sps->undoInfo.window == None) &&
		sps->undoInfo.newX == w->serverX &&
		sps->undoInfo.newY == w->serverY &&
		sps->undoInfo.newWidth == w->serverWidth &&
		sps->undoInfo.newHeight == w->serverHeight &&
		smartputGetUseTriggerkeyForundo (d))
	{
	    mask = smartputUndoResize (s,xwc);
	    undo = TRUE;
	}
	else
	{
	    mask = smartputComputeResize (w, xwc);
	}

	if (mask)
	{
	    if (constrainNewWindowSize (w, xwc->width, xwc->height,
					&width, &height))
	    {
		mask |= CWWidth | CWHeight;
		xwc->width  = width;
		xwc->height = height;
	    }
	    spw->lastX = w->serverX;
	    spw->lastY = w->serverY;

	    spw->targetX    = xwc->x;
	    spw->targetY    = xwc->y;
	    spw->xwc        = xwc;
	    spw->mask       = mask;
	    sps->lastWindow = w->id;

	    smartputUpdateUndoInfo (s, w, xwc, undo);

	    spw->animation = TRUE;
	    sps->animation = TRUE;

	    addWindowDamage (w);
	}
    }

    return TRUE;

}
void
eventLoop (void)
{
    XEvent	   event;
    struct pollfd  ufd;
    int		   timeDiff;
    struct timeval tv;
    Region	   tmpRegion;
    CompDisplay    *display = compDisplays;
    CompScreen	   *s = display->screens;
    int		   timeToNextRedraw = 0;
    CompWindow	   *move = 0;
    int		   px = 0, py = 0;
    CompTimeout    *t;

    tmpRegion = XCreateRegion ();
    if (!tmpRegion)
    {
	fprintf (stderr, "%s: Couldn't create region\n", programName);
	return;
    }

    ufd.fd = ConnectionNumber (display->display);
    ufd.events = POLLIN;

    for (;;)
    {
	if (display->dirtyPluginList)
	    updatePlugins (display);

	if (restartSignal)
	{
	     execvp (programName, programArgv);
	     exit (1);
	}

	while (XPending (display->display))
	{
	    XNextEvent (display->display, &event);

	    /* translate root window */
	    if (testMode)
	    {
		Window root, child;

		switch (event.type) {
		case ButtonPress:
		    if (!move)
		    {
			px = event.xbutton.x;
			py = event.xbutton.y;

			move = findWindowAt (display, event.xbutton.window,
					     px, py);
			if (move)
			{
			    XRaiseWindow (display->display, move->id);
			    continue;
			}
		    }
		case ButtonRelease:
		    move = 0;

		    root = translateToRootWindow (display,
						  event.xbutton.window);
		    XTranslateCoordinates (display->display,
					   event.xbutton.root, root,
					   event.xbutton.x_root,
					   event.xbutton.y_root,
					   &event.xbutton.x_root,
					   &event.xbutton.y_root,
					   &child);
		    event.xbutton.root = root;
		    break;
		case KeyPress:
		case KeyRelease:
		    root = translateToRootWindow (display, event.xkey.window);
		    XTranslateCoordinates (display->display,
					   event.xkey.root, root,
					   event.xkey.x_root,
					   event.xkey.y_root,
					   &event.xkey.x_root,
					   &event.xkey.y_root,
					   &child);
		    event.xkey.root = root;
		    break;
		case MotionNotify:
		    if (move)
		    {
			XMoveWindow (display->display, move->id,
				     move->attrib.x + event.xbutton.x - px,
				     move->attrib.y + event.xbutton.y - py);

			px = event.xbutton.x;
			py = event.xbutton.y;
			continue;
		    }

		    root = translateToRootWindow (display,
						  event.xmotion.window);
		    XTranslateCoordinates (display->display,
					   event.xmotion.root, root,
					   event.xmotion.x_root,
					   event.xmotion.y_root,
					   &event.xmotion.x_root,
					   &event.xmotion.y_root,
					   &child);
		    event.xmotion.root = root;
		default:
		    break;
		}
	    }

	    /* add virtual modifiers */
	    switch (event.type) {
	    case ButtonPress:
		event.xbutton.state |= CompPressMask;
		event.xbutton.state =
		    realToVirtualModMask (display, event.xbutton.state);
		break;
	    case ButtonRelease:
		event.xbutton.state |= CompReleaseMask;
		event.xbutton.state =
		    realToVirtualModMask (display, event.xbutton.state);
		break;
	    case KeyPress:
		event.xkey.state |= CompPressMask;
		event.xkey.state = realToVirtualModMask (display,
							 event.xkey.state);
		break;
	    case KeyRelease:
		event.xkey.state |= CompReleaseMask;
		event.xkey.state = realToVirtualModMask (display,
							 event.xkey.state);
		break;
	    case MotionNotify:
		event.xmotion.state =
		    realToVirtualModMask (display, event.xmotion.state);
		break;
	    default:
		break;
	    }

	    (*display->handleEvent) (display, &event);
	}

	if (s->allDamaged || REGION_NOT_EMPTY (s->damage))
	{
	    if (timeToNextRedraw == 0)
	    {
		/* wait for X drawing requests to finish
		   glXWaitX (); */

		gettimeofday (&tv, 0);

		timeDiff = TIMEVALDIFF (&tv, &s->lastRedraw);

		(*s->preparePaintScreen) (s, timeDiff);

		if (s->allDamaged)
		{
		    EMPTY_REGION (s->damage);
		    s->allDamaged = 0;

		    (*s->paintScreen) (s,
				       &defaultScreenPaintAttrib,
				       &defaultWindowPaintAttrib,
				       &s->region,
				       PAINT_SCREEN_REGION_MASK |
				       PAINT_SCREEN_FULL_MASK);

		    glXSwapBuffers (s->display->display, s->root);
		}
		else
		{
		    XIntersectRegion (s->damage, &s->region, tmpRegion);

		    EMPTY_REGION (s->damage);

		    if ((*s->paintScreen) (s,
					   &defaultScreenPaintAttrib,
					   &defaultWindowPaintAttrib,
					   tmpRegion,
					   PAINT_SCREEN_REGION_MASK))
		    {
			BoxPtr pBox;
			int    nBox, y;

			glEnable (GL_SCISSOR_TEST);
			glDrawBuffer (GL_FRONT);

			pBox = tmpRegion->rects;
			nBox = tmpRegion->numRects;
			while (nBox--)
			{
			    y = s->height - pBox->y2;

			    glBitmap (0, 0, 0, 0,
				      pBox->x1 - s->rasterX, y - s->rasterY,
				      NULL);

			    s->rasterX = pBox->x1;
			    s->rasterY = y;

			    glScissor (pBox->x1, y,
				       pBox->x2 - pBox->x1,
				       pBox->y2 - pBox->y1);

			    glCopyPixels (pBox->x1, y,
					  pBox->x2 - pBox->x1,
					  pBox->y2 - pBox->y1,
					  GL_COLOR);

			    pBox++;
			}

			glDrawBuffer (GL_BACK);
			glDisable (GL_SCISSOR_TEST);
			glFlush ();
		    }
		    else
		    {
			(*s->paintScreen) (s,
					   &defaultScreenPaintAttrib,
					   &defaultWindowPaintAttrib,
					   &s->region,
					   PAINT_SCREEN_FULL_MASK);

			glXSwapBuffers (s->display->display, s->root);
		    }
		}

		s->lastRedraw = tv;

		(*s->donePaintScreen) (s);

		/* remove destroyed windows */
		while (s->pendingDestroys)
		{
		    CompWindow *w;

		    for (w = s->windows; w; w = w->next)
		    {
			if (w->destroyed)
			{
			    addWindowDamage (w);
			    removeWindow (w);
			    break;
			}
		    }

		    s->pendingDestroys--;
		}
	    }

	    timeToNextRedraw = getTimeToNextRedraw (s, &s->lastRedraw);
	    if (timeToNextRedraw)
		timeToNextRedraw = poll (&ufd, 1, timeToNextRedraw);
	}
	else
	{
	    if (timeouts)
	    {
		if (timeouts->left > 0)
		    poll (&ufd, 1, timeouts->left);

		gettimeofday (&tv, 0);

		timeDiff = TIMEVALDIFF (&tv, &lastTimeout);

		for (t = timeouts; t; t = t->next)
		    t->left -= timeDiff;

		while (timeouts && timeouts->left <= 0)
		{
		    t = timeouts;
		    if ((*t->callBack) (t->closure))
		    {
			timeouts = t->next;
			addTimeout (t);
		    }
		    else
		    {
			timeouts = t->next;
			free (t);
		    }
		}

		s->lastRedraw = lastTimeout = tv;
	    }
	    else
	    {
		poll (&ufd, 1, 1000);
		gettimeofday (&s->lastRedraw, 0);
	    }

	    /* just redraw immediately */
	    timeToNextRedraw = 0;
	}
    }
}