/* Generates a region containing free space (here the
 * active window counts as free space). The region argument
 * is the start-region (ie: the output dev).
 */
static Region
smartputEmptyRegion (CompWindow *window,
		     Region     region)
{
    CompScreen *s = window->screen;
    CompWindow *w;
    Region     newRegion, tmpRegion;
    XRectangle tmpRect;

    newRegion = XCreateRegion ();
    if (!newRegion)
	return NULL;

    tmpRegion = XCreateRegion ();
    if (!tmpRegion)
    {
	XDestroyRegion (newRegion);
	return NULL;
    }

    XUnionRegion (region, newRegion, newRegion);

    for (w = s->windows; w; w = w->next)
    {
	EMPTY_REGION (tmpRegion);
        if (w->id == window->id)
            continue;

        if (w->invisible || w->hidden || w->minimized)
            continue;

	if (w->wmType & CompWindowTypeDesktopMask)
	    continue;

	if (w->wmType & CompWindowTypeDockMask)
	{
	    if (w->struts)
	    {
		XUnionRectWithRegion (&w->struts->left, tmpRegion, tmpRegion);
		XUnionRectWithRegion (&w->struts->right, tmpRegion, tmpRegion);
		XUnionRectWithRegion (&w->struts->top, tmpRegion, tmpRegion);
		XUnionRectWithRegion (&w->struts->bottom, tmpRegion, tmpRegion);
		XSubtractRegion (newRegion, tmpRegion, newRegion);
	    }
	    continue;
	}

	tmpRect.x = w->serverX - w->input.left;
	tmpRect.y = w->serverY - w->input.top;
	tmpRect.width  = w->serverWidth + w->input.right + w->input.left;
	tmpRect.height = w->serverHeight + w->input.top +
	                 w->input.bottom;
	XUnionRectWithRegion (&tmpRect, tmpRegion, tmpRegion);
	XSubtractRegion (newRegion, tmpRegion, newRegion);
    }

    XDestroyRegion (tmpRegion);

    return newRegion;
}
示例#2
0
static void
minSetShade (CompWindow *w,
             int        shade)
{
	REGION rect;
	int    h = w->attrib.height + w->attrib.border_width * 2;

	MIN_WINDOW (w);

	EMPTY_REGION (w->region);

	rect.rects = &rect.extents;
	rect.numRects = rect.size = 1;

	w->height = shade;

	rect.extents.x1 = 0;
	rect.extents.y1 = h - shade;
	rect.extents.x2 = w->width;
	rect.extents.y2 = h;

	XIntersectRegion (mw->region, &rect, w->region);
	XOffsetRegion (w->region, w->attrib.x, w->attrib.y - (h - shade));

	w->matrix = w->texture->matrix;
	w->matrix.x0 -= (w->attrib.x * w->matrix.xx);
	w->matrix.y0 -= ((w->attrib.y - (h - shade)) * w->matrix.yy);

	(*w->screen->windowResizeNotify) (w, 0, 0, 0, 0);
}
示例#3
0
/*
 *           REGION_FrameRgn
 * Create a region that is a frame around another region.
 * Expand all rectangles by +/- x and y, then subtract original region.
 */
BOOL
REGION_FrameRgn( HRGN hDest, HRGN hSrc, INT x, INT y )
{
    BOOL bRet;
    MWRGNOBJ *srcObj = (MWRGNOBJ*) GDI_GetObjPtr( hSrc, OBJ_REGION );

    if (srcObj->rgn->numRects != 0) 
    {
	MWRGNOBJ* destObj = (MWRGNOBJ*) GDI_GetObjPtr( hDest, OBJ_REGION );
	RECT *pRect, *pEndRect;
	RECT tempRect;

	EMPTY_REGION( destObj->rgn );
	
	pEndRect = srcObj->rgn->rects + srcObj->rgn->numRects;
	for(pRect = srcObj->rgn->rects; pRect < pEndRect; pRect++)
	{
	    tempRect.left = pRect->left - x;        
	    tempRect.top = pRect->top - y;
	    tempRect.right = pRect->right + x;
	    tempRect.bottom = pRect->bottom + y;
	    GdUnionRectWithRegion( &tempRect, destObj->rgn );
	}
	GdSubtractRegion( destObj->rgn, destObj->rgn, srcObj->rgn );
	bRet = TRUE;
    }
    else
	bRet = FALSE;
    return bRet;
}
示例#4
0
void reg_SetRectRegion(RegionBase *RegionBase, ClipRegion *rgn, INT32 left, INT32 top, INT32 right, INT32 bottom)
{
	if (left != right && top != bottom) {
		rgn->rects->left = rgn->extents.left = left;
		rgn->rects->top = rgn->extents.top = top;
		rgn->rects->right = rgn->extents.right = right;
		rgn->rects->bottom = rgn->extents.bottom = bottom;
		rgn->numRects = 1;
		rgn->type = REGION_SIMPLE;
	} else
		EMPTY_REGION(rgn);
}
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;
	}
    }
}