Example #1
0
/* lpStruct - (REGION32) Destination Region */
DWORD
DrvRegionsXORRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	XXorRegion((Region)dwParm1, (Region)dwParm2, (Region)lpStruct);
	return (DWORD)(XEmptyRegion((Region)lpStruct)?
				NULLREGION:COMPLEXREGION);
}
Example #2
0
static PyObject *
region_EmptyRegion(PaxRegionObject *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, ""))
	return NULL;
    return PyInt_FromLong(XEmptyRegion(self->region));
}
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);
}
Example #4
0
bool wxRegion::IsEmpty() const
{
    if (!m_refData)
        return true;

    return XEmptyRegion( M_REGIONDATA->m_region ) == True;
}
Example #5
0
// Return true if region is empty
FXbool FXRegion::empty() const {
#ifdef WIN32
  return OffsetRgn((HRGN)region,0,0)==NULLREGION;
#else
  return XEmptyRegion((Region)region);
#endif
  }
Example #6
0
/* lpStruct - Destination Region */
DWORD
DrvRegionsDiffRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	XSubtractRegion((Region)dwParm1, (Region)dwParm2, (Region)lpStruct);
	return (DWORD)(XEmptyRegion((Region)lpStruct)?
				NULLREGION:COMPLEXREGION);
}
Example #7
0
bool wxRegion::Empty() const
{
    if (!m_refData)
        return TRUE;
#if 0
    return XEmptyRegion( M_REGIONDATA->m_region );
#endif
}
Example #8
0
EAPI Eina_Bool
ecore_x_xregion_is_empty(Ecore_X_XRegion *region)
{
   if (!region)
      return EINA_TRUE;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   return XEmptyRegion((Region)region) ? EINA_TRUE : EINA_FALSE;
} /* ecore_x_xregion_is_empty */
Example #9
0
/* dwParm2 - Destination Region */
DWORD
DrvRegionsCopyRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	static Region EmptyRegion;

	if (EmptyRegion == None)
		EmptyRegion = XCreateRegion();
	XUnionRegion((Region)dwParm1, EmptyRegion,(Region)dwParm2);
	return (DWORD)(XEmptyRegion((Region)dwParm2)?
			NULLREGION:COMPLEXREGION);
}
Example #10
0
/* lpStruct - Pointer to RECT */
DWORD
DrvRegionsUnionRectWithRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	LPRECT lpRect;
	XRectangle xRect;

	if (!(lpRect = (LPRECT)lpStruct))
		return (DWORD)ERROR;
	xRect.x = lpRect->left;
	xRect.y = lpRect->top;
	xRect.width = lpRect->right - lpRect->left;
	xRect.height = lpRect->bottom - lpRect->top;

	XUnionRectWithRegion(&xRect, (Region)dwParm1, (Region)dwParm1);

	return (DWORD)(XEmptyRegion((Region)dwParm1)?
			NULLREGION:COMPLEXREGION);
}
int
TkScrollWindow(
    Tk_Window tkwin,		/* The window to be scrolled. */
    GC gc,			/* GC for window to be scrolled. */
    int x, int y, int width, int height,
				/* Position rectangle to be scrolled. */
    int dx, int dy,		/* Distance rectangle should be moved. */
    TkRegion damageRgn)		/* Region to accumulate damage in. */
{
    Tk_RestrictProc *oldProc;
    ClientData oldArg, dummy;
    ScrollInfo info;

    XCopyArea(Tk_Display(tkwin), Tk_WindowId(tkwin), Tk_WindowId(tkwin), gc,
	    x, y, (unsigned) width, (unsigned) height, x+dx, y+dy);

    info.done = 0;
    info.window = Tk_WindowId(tkwin);
    info.display = Tk_Display(tkwin);
    info.region = damageRgn;
    info.dx = dx;
    info.dy = dy;

    /*
     * Sync the event stream so all of the expose events will be on the Tk
     * event queue before we start filtering. This avoids busy waiting while
     * we filter events.
     */

    TkpSync(info.display);
    oldProc = Tk_RestrictEvents(ScrollRestrictProc, (ClientData) &info,
	    &oldArg);
    while (!info.done) {
	Tcl_ServiceEvent(TCL_WINDOW_EVENTS);
    }
    Tk_RestrictEvents(oldProc, oldArg, &dummy);

    if (XEmptyRegion((Region) damageRgn)) {
	return 0;
    } else {
	return 1;
    }
}
Example #12
0
/* Walk through all windows, skip until we've passed the active
 * window, skip if it's invisible, hidden or minimized, skip if
 * it's not a window type we're looking for.
 * Dim it if it intersects.
 *
 * Returns number of changed windows.
 */
static int
passiveWindows (CompScreen *s,
                Region     region)
{
	CompWindow *w;
	Bool flag = FALSE;
	int i = 0;

	OPACIFY_SCREEN (s);

	for (w = s->windows; w; w = w->next)
	{
		if (w->id == os->active)
		{
			flag = TRUE;
			continue;
		}

		if (!flag)
			continue;

		if (!matchEval (&os->window_match, w))
			continue;

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

		XIntersectRegion (w->region, region, os->intersect);
		if (!XEmptyRegion (os->intersect))
		{
			dimWindow (w);
			i++;
		}
	}

	return i;
}
*/ static void process_gobs(REBCMP_CTX* ctx, REBGOB* gob)
/*
**	Recursively process and compose gob and its children.
**
** NOTE: this function is used internally by rebcmp_compose() call only.
**
***********************************************************************/
{
	//RL_Print("process_gobs: %x\n", gob);

	REBINT x = ROUND_TO_INT(ctx->absOffset.x);
	REBINT y = ROUND_TO_INT(ctx->absOffset.y);
	REBYTE* color;
	Region saved_win_region = XCreateRegion();

	if (GET_GOB_STATE(gob, GOBS_NEW)){
		//reset old-offset and old-size if newly added
		GOB_XO(gob) = GOB_LOG_X(gob);
		GOB_YO(gob) = GOB_LOG_Y(gob);
		GOB_WO(gob) = GOB_LOG_W(gob);
		GOB_HO(gob) = GOB_LOG_H(gob);

		CLR_GOB_STATE(gob, GOBS_NEW);
	}

	//intersect gob dimensions with actual window clip region
	REBOOL valid_intersection = 1;

	
	//------------------------------
	//Put backend specific code here
	//------------------------------
	XRectangle rect;
	rect.x = x;
	rect.y = y;
	rect.width = GOB_LOG_W(gob);
	rect.height = GOB_LOG_H(gob);
	/*
	RL_Print("gob        , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 rect.x,
			 rect.y,
			 rect.x + rect.width,
			 rect.y + rect.height);
	*/

	Region reg = XCreateRegion();
	XUnionRectWithRegion(&rect, reg, reg);
	/*
	XClipBox(ctx->Win_Region, &rect);
	RL_Print("Win Region , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 rect.x,
			 rect.y,
			 rect.x + rect.width,
			 rect.y + rect.height);
	*/
	XUnionRegion(saved_win_region, ctx->Win_Region, saved_win_region);
	XIntersectRegion(reg, ctx->Win_Region, ctx->Win_Region);
	XClipBox(ctx->Win_Region, &rect);
	/*
	RL_Print("Win and Gob, left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 rect.x,
			 rect.y,
			 rect.x + rect.width,
			 rect.y + rect.height);
			 */

	//get the current Window clip box
	REBRECT gob_clip = {
		rect.x, //left
		rect.y, //top
		rect.width + rect.x, //right
		rect.height + rect.y //bottom
			/*
		GOB_LOG_X(gob), //left
		GOB_LOG_Y(gob), //top
		GOB_LOG_W(gob) + GOB_LOG_X(gob), //right
		GOB_LOG_H(gob) + GOB_LOG_Y(gob), //bottom
		*/
	};

	//RL_Print("Window_Buffer: 0x%x\n", ctx->Window_Buffer);
	/*
	RL_Print("gob clip   , left: %d,\ttop: %d,\tright: %d,\tbottom: %d\n",
			 gob_clip.left,
			 gob_clip.top,
			 gob_clip.right,
			 gob_clip.bottom);
			 */
	if (!XEmptyRegion(ctx->Win_Region))
	//if (valid_intersection)
	{
		//render GOB content
		switch (GOB_TYPE(gob)) {
			case GOBT_COLOR:
				//------------------------------
				//Put backend specific code here
				//------------------------------
				// or use the similar draw api call:
				//RL_Print("Draw Color at: %d, %d\n", x, y);
				rebdrw_gob_color(gob, ctx->Window_Buffer, ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				break;

			case GOBT_IMAGE:
				{
				//RL_Print("Draw Image\n");
					//------------------------------
					//Put backend specific code here
					//------------------------------
					// or use the similar draw api call:
					rebdrw_gob_image(gob, ctx->Window_Buffer, ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				}
				break;

			case GOBT_DRAW:
				{
				//RL_Print("Draw Draw at: %d, %d\n", x, y);
					//------------------------------
					//Put backend specific code here
					//------------------------------
					// or use the similar draw api call:
					rebdrw_gob_draw(gob, ctx->Window_Buffer ,ctx->winBufSize, (REBXYI){x,y}, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				}
				break;

			case GOBT_TEXT:
			case GOBT_STRING:
				//RL_Print("Draw Text at: %d, %d\n", x, y);
				//------------------------------
				//Put backend specific code here
				//------------------------------
				// or use the similar draw api call:
				rt_gob_text(gob, ctx->Window_Buffer ,ctx->winBufSize,ctx->absOffset, (REBXYI){gob_clip.left, gob_clip.top}, (REBXYI){gob_clip.right, gob_clip.bottom});
				break;

			case GOBT_EFFECT:
				//RL_Print("Draw Effect\n");
				//not yet implemented
				break;
		}


		//recursively process sub GOBs
		if (GOB_PANE(gob)) {
			REBINT n;
			REBINT len = GOB_TAIL(gob);
			REBGOB **gp = GOB_HEAD(gob);

			for (n = 0; n < len; n++, gp++) {
				REBINT g_x = GOB_LOG_X(*gp);
				REBINT g_y = GOB_LOG_Y(*gp);

				//restore the "parent gob" clip region
				//------------------------------
				//Put backend specific code here
				//------------------------------

				ctx->absOffset.x += g_x;
				ctx->absOffset.y += g_y;

				process_gobs(ctx, *gp);

				ctx->absOffset.x -= g_x;
				ctx->absOffset.y -= g_y;
			}
		}
	}
	XDestroyRegion(reg);
	XDestroyRegion(ctx->Win_Region);
	ctx->Win_Region = saved_win_region;
}
Example #14
0
/*
 * groupHandleButtonReleaseEvent
 *
 */
static void
groupHandleButtonReleaseEvent (CompScreen *s,
                               XEvent     *event)
{
	GroupSelection *group;
	int vx, vy;
	Region newRegion;
	Bool inserted = FALSE;
	Bool wasInTabBar = FALSE;

	GROUP_SCREEN (s);

	if (event->xbutton.button != 1)
		return;

	if (!gs->draggedSlot)
		return;

	if (!gs->dragged)
	{
		groupChangeTab (gs->draggedSlot, RotateUncertain);
		gs->draggedSlot = NULL;

		if (gs->grabState == ScreenGrabTabDrag)
			groupGrabScreen (s, ScreenGrabNone);

		return;
	}

	GROUP_WINDOW (gs->draggedSlot->window);

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

	XUnionRegion (newRegion, gs->draggedSlot->region, newRegion);

	groupGetDrawOffsetForSlot (gs->draggedSlot, &vx, &vy);
	XOffsetRegion (newRegion, vx, vy);

	for (group = gs->groups; group; group = group->next)
	{
		Bool inTabBar;
		Region clip, buf;
		GroupTabBarSlot *slot;

		if (!group->tabBar || !HAS_TOP_WIN (group))
			continue;

		/* create clipping region */
		clip = groupGetClippingRegion (TOP_TAB (group));
		if (!clip)
			continue;

		buf = XCreateRegion ();
		if (!buf)
		{
			XDestroyRegion (clip);
			continue;
		}

		XIntersectRegion (newRegion, group->tabBar->region, buf);
		XSubtractRegion (buf, clip, buf);
		XDestroyRegion (clip);

		inTabBar = !XEmptyRegion (buf);
		XDestroyRegion (buf);

		if (!inTabBar)
			continue;

		wasInTabBar = TRUE;

		for (slot = group->tabBar->slots; slot; slot = slot->next)
		{
			GroupTabBarSlot *tmpDraggedSlot;
			GroupSelection  *tmpGroup;
			Region slotRegion, buf;
			XRectangle rect;
			Bool inSlot;

			if (slot == gs->draggedSlot)
				continue;

			slotRegion = XCreateRegion ();
			if (!slotRegion)
				continue;

			if (slot->prev && slot->prev != gs->draggedSlot)
			{
				rect.x = slot->prev->region->extents.x2;
			}
			else if (slot->prev && slot->prev == gs->draggedSlot &&
			         gs->draggedSlot->prev)
			{
				rect.x = gs->draggedSlot->prev->region->extents.x2;
			}
			else
				rect.x = group->tabBar->region->extents.x1;

			rect.y = slot->region->extents.y1;

			if (slot->next && slot->next != gs->draggedSlot)
			{
				rect.width = slot->next->region->extents.x1 - rect.x;
			}
			else if (slot->next && slot->next == gs->draggedSlot &&
			         gs->draggedSlot->next)
			{
				rect.width = gs->draggedSlot->next->region->extents.x1 - rect.x;
			}
			else
				rect.width = group->tabBar->region->extents.x2;

			rect.height = slot->region->extents.y2 - slot->region->extents.y1;

			XUnionRectWithRegion (&rect, slotRegion, slotRegion);

			buf = XCreateRegion ();
			if (!buf)
				continue;

			XIntersectRegion (newRegion, slotRegion, buf);
			inSlot = !XEmptyRegion (buf);

			XDestroyRegion (buf);
			XDestroyRegion (slotRegion);

			if (!inSlot)
				continue;

			tmpDraggedSlot = gs->draggedSlot;

			if (group != gw->group)
			{
				CompWindow     *w = gs->draggedSlot->window;
				GroupSelection *tmpGroup = gw->group;
				int oldPosX = WIN_CENTER_X (w);
				int oldPosY = WIN_CENTER_Y (w);

				/* if the dragged window is not the top tab,
				   move it onscreen */
				if (tmpGroup->topTab && !IS_TOP_TAB (w, tmpGroup))
				{
					CompWindow *tw = TOP_TAB (tmpGroup);

					oldPosX = WIN_CENTER_X (tw) + gw->mainTabOffset.x;
					oldPosY = WIN_CENTER_Y (tw) + gw->mainTabOffset.y;

					groupSetWindowVisibility (w, TRUE);
				}

				/* Change the group. */
				groupDeleteGroupWindow (gs->draggedSlot->window);
				groupAddWindowToGroup (gs->draggedSlot->window, group, 0);

				/* we saved the original center position in oldPosX/Y before -
				   now we should apply that to the new main tab offset */
				if (HAS_TOP_WIN (group))
				{
					CompWindow *tw = TOP_TAB (group);
					gw->mainTabOffset.x = oldPosX - WIN_CENTER_X (tw);
					gw->mainTabOffset.y = oldPosY - WIN_CENTER_Y (tw);
				}
			}
			else
				groupUnhookTabBarSlot (group->tabBar, gs->draggedSlot, TRUE);

			gs->draggedSlot = NULL;
			gs->dragged = FALSE;
			inserted = TRUE;

			if ((tmpDraggedSlot->region->extents.x1 +
			     tmpDraggedSlot->region->extents.x2 + (2 * vx)) / 2 >
			    (slot->region->extents.x1 + slot->region->extents.x2) / 2)
			{
				groupInsertTabBarSlotAfter (group->tabBar,
				                            tmpDraggedSlot, slot);
			}
			else
				groupInsertTabBarSlotBefore (group->tabBar,
				                             tmpDraggedSlot, slot);

			groupDamageTabBarRegion (group);

			/* Hide tab-bars. */
			for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			{
				if (group == tmpGroup)
					groupTabSetVisibility (tmpGroup, TRUE, 0);
				else
					groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);
			}

			break;
		}

		if (inserted)
			break;
	}

	XDestroyRegion (newRegion);

	if (!inserted)
	{
		CompWindow     *draggedSlotWindow = gs->draggedSlot->window;
		GroupSelection *tmpGroup;

		for (tmpGroup = gs->groups; tmpGroup; tmpGroup = tmpGroup->next)
			groupTabSetVisibility (tmpGroup, FALSE, PERMANENT);

		gs->draggedSlot = NULL;
		gs->dragged = FALSE;

		const BananaValue *
		option_dnd_ungroup_window = bananaGetOption (bananaIndex,
		                                             "dnd_ungroup_window",
		                                             s->screenNum);

		if (option_dnd_ungroup_window->b && !wasInTabBar)
		{
			groupRemoveWindowFromGroup (draggedSlotWindow);
		}
		else if (gw->group && gw->group->topTab)
		{
			groupRecalcTabBarPos (gw->group,
			                      (gw->group->tabBar->region->extents.x1 +
			                       gw->group->tabBar->region->extents.x2) / 2,
			                      gw->group->tabBar->region->extents.x1,
			                      gw->group->tabBar->region->extents.x2);
		}

		/* to remove the painted slot */
		damageScreen (s);
	}

	if (gs->grabState == ScreenGrabTabDrag)
		groupGrabScreen (s, ScreenGrabNone);

	if (gs->dragHoverTimeoutHandle)
	{
		compRemoveTimeout (gs->dragHoverTimeoutHandle);
		gs->dragHoverTimeoutHandle = 0;
	}
}
Example #15
0
/* dwParm1 - dwParm1 - (REGION32) Region */
DWORD
DrvRegionsIsEmptyRegion(LPARAM dwParm1, LPARAM dwParm2, LPVOID lpStruct)
{
	return (DWORD)XEmptyRegion((Region)dwParm1);
}
Example #16
0
static void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h)
{
	XTransform transform;
	Picture windowPicture;
	Picture primaryPicture;
	XRenderPictureAttributes pa;
	XRenderPictFormat* picFormat;
	double xScalingFactor;
	double yScalingFactor;
	int x2;
	int y2;

	if (xfc->scaledWidth <= 0 || xfc->scaledHeight <= 0)
	{
		WLog_ERR(TAG, "the current window dimensions are invalid");
		return;
	}

	if (xfc->sessionWidth <= 0 || xfc->sessionHeight <= 0)
	{
		WLog_ERR(TAG, "the window dimensions are invalid");
		return;
	}

	xScalingFactor = xfc->sessionWidth / (double)xfc->scaledWidth;
	yScalingFactor = xfc->sessionHeight / (double)xfc->scaledHeight;

	XSetFillStyle(xfc->display, xfc->gc, FillSolid);
	XSetForeground(xfc->display, xfc->gc, 0);

	/* Black out possible space between desktop and window borders */
	{
		XRectangle box1 = { 0, 0, xfc->window->width, xfc->window->height };
		XRectangle box2 = { xfc->offset_x, xfc->offset_y, xfc->scaledWidth, xfc->scaledHeight };
		Region reg1 = XCreateRegion();
		Region reg2 = XCreateRegion();
		XUnionRectWithRegion(&box1, reg1, reg1);
		XUnionRectWithRegion(&box2, reg2, reg2);

		if (XSubtractRegion(reg1, reg2, reg1) && !XEmptyRegion(reg1))
		{
			XSetRegion(xfc->display, xfc->gc, reg1);
			XFillRectangle(xfc->display, xfc->window->handle, xfc->gc, 0, 0, xfc->window->width, xfc->window->height);
			XSetClipMask(xfc->display, xfc->gc, None);
		}

		XDestroyRegion(reg1);
		XDestroyRegion(reg2);
	}

	picFormat = XRenderFindVisualFormat(xfc->display, xfc->visual);

	pa.subwindow_mode = IncludeInferiors;
	primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa);
	windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa);

	XRenderSetPictureFilter(xfc->display, primaryPicture, FilterBilinear, 0, 0);

	transform.matrix[0][0] = XDoubleToFixed(xScalingFactor);
	transform.matrix[0][1] = XDoubleToFixed(0.0);
	transform.matrix[0][2] = XDoubleToFixed(0.0);
	transform.matrix[1][0] = XDoubleToFixed(0.0);
	transform.matrix[1][1] = XDoubleToFixed(yScalingFactor);
	transform.matrix[1][2] = XDoubleToFixed(0.0);
	transform.matrix[2][0] = XDoubleToFixed(0.0);
	transform.matrix[2][1] = XDoubleToFixed(0.0);
	transform.matrix[2][2] = XDoubleToFixed(1.0);

	/* calculate and fix up scaled coordinates */
	x2 = x + w;
	y2 = y + h;
	x = floor(x / xScalingFactor) - 1;
	y = floor(y / yScalingFactor) - 1;
	w = ceil(x2 / xScalingFactor) + 1 - x;
	h = ceil(y2 / yScalingFactor) + 1 - y;

	XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
	XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, x, y, 0, 0, xfc->offset_x + x, xfc->offset_y + y, w, h);
	XRenderFreePicture(xfc->display, primaryPicture);
	XRenderFreePicture(xfc->display, windowPicture);
}
Example #17
0
Bool
apc_region_is_empty( Handle self)
{
	return XEmptyRegion( REGION );
}
Example #18
0
sBool sXUpdateEmpty()
{
  return XEmptyRegion(UpdateRegion) != 0;
}
/*
 * Loop on outputDevs and add the extents as edges
 * Note that left side is a right edge, right side a left edge,
 * top side a bottom edge and bottom side a top edge,
 * since they will be snapped as the right/left/bottom/top edge of a window
 */
static void snapUpdateScreenEdges(CompWindow * w)
{
	CompWindow *c = NULL;
	Edge *e = NULL, *next = NULL;

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

	XRectangle area;
	int i;

	for (i = 0; i < w->screen->nOutputDev; i++)
	{
		snapScreenGetOutputDevRect(w->screen, i, &area);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.y, area.x, area.x + area.width - 1, BottomEdge, TRUE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.y + area.height, area.x,
					area.x + area.width - 1, TopEdge, TRUE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.x, area.y, area.y + area.height - 1, RightEdge, TRUE);
		snapAddEdge(&sw->edges, &sw->reverseEdges, 0,
					area.x + area.width, area.y,
					area.y + area.height - 1, LeftEdge, TRUE);
	}

	// Drop screen edges parts that are under struts, basically apply the
	// same strategy than for windows edges visibility
	for (c = w->screen->windows; c; c = c->next)
	{
		if (c == w || !c->struts)
			continue;
		for (e = sw->edges; e; e = next)
		{
			if (!e->screenEdge)
			{
				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;
			}
			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);
		}
	}
}
Example #20
0
bool
CompRegion::isEmpty () const
{
    return XEmptyRegion (handle ());
}
*/ void rebcmp_compose(REBCMP_CTX* ctx, REBGOB* winGob, REBGOB* gob, REBOOL only)
/*
**	Compose content of the specified gob. Main compositing function.
**
**  If the ONLY arg is TRUE then the specified gob area will be
**  rendered to the buffer at 0x0 offset.(used by TO-IMAGE)
**
***********************************************************************/
{
	REBINT max_depth = 1000; // avoid infinite loops
	REBD32 abs_x = 0;
	REBD32 abs_y = 0;
	REBD32 abs_ox;
	REBD32 abs_oy;
	REBGOB* parent_gob = gob;
	REBINT x = GOB_LOG_X_INT(gob);
	REBINT y = GOB_LOG_Y_INT(gob);
	REBINT w = GOB_LOG_W_INT(gob);
	REBINT h = GOB_LOG_H_INT(gob);
	/*
	RL_Print("Composing gob: %x (%dx%d, %dx%d) in wingob %x\n", 
			 gob,
			 (int)GOB_LOG_X(gob),
			 (int)GOB_LOG_Y(gob),
			 GOB_W_INT(gob),
			 GOB_H_INT(gob),
			 winGob);
			 */

	//reset clip region to window area
	if (ctx->Win_Region != NULL){
		XDestroyRegion(ctx->Win_Region);
	}
	ctx->Win_Region = XCreateRegion();

	//calculate absolute offset of the gob
	while (GOB_PARENT(parent_gob) && (max_depth-- > 0) && !GET_GOB_FLAG(parent_gob, GOBF_WINDOW))
	{
		abs_x += GOB_LOG_X(parent_gob);
		abs_y += GOB_LOG_Y(parent_gob);
		parent_gob = GOB_PARENT(parent_gob);
	}

	assert(max_depth > 0);

	//the offset is shifted to render given gob at offset 0x0 (used by TO-IMAGE)
	if (only){
		ctx->absOffset.x = -abs_x;
		ctx->absOffset.y = -abs_y;
		abs_x = 0;
		abs_y = 0;
	} else {
		ctx->absOffset.x = 0;
		ctx->absOffset.y = 0;
	}

	ctx->New_Clip.x = abs_x;
	ctx->New_Clip.y = abs_y;
	ctx->New_Clip.width = GOB_LOG_W_INT(gob);
	ctx->New_Clip.height = GOB_LOG_H_INT(gob);

	//handle newly added gob case
	if (!GET_GOB_STATE(gob, GOBS_NEW)){
		//calculate absolute old offset of the gob
		abs_ox = abs_x + (GOB_XO(gob) - GOB_LOG_X(gob));
		abs_oy = abs_y + (GOB_YO(gob) - GOB_LOG_Y(gob));

		//set region with old gob location and dimensions
		ctx->Old_Clip.x = abs_ox;
		ctx->Old_Clip.y = abs_oy;
		ctx->Old_Clip.width = GOB_WO_INT(gob);
		ctx->Old_Clip.height = GOB_HO_INT(gob);
		XUnionRectWithRegion(&ctx->Old_Clip, ctx->Win_Region, ctx->Win_Region);
		//RL_Print("OLD: %dx%d %dx%d\n",(REBINT)abs_ox, (REBINT)abs_oy, (REBINT)abs_ox + GOB_WO_INT(gob), (REBINT)abs_oy + GOB_HO_INT(gob));
	}
	//RL_Print("NEW: %dx%d %dx%d\n",(REBINT)abs_x, (REBINT)abs_y, (REBINT)abs_x + GOB_LOG_W_INT(gob), (REBINT)abs_y + GOB_LOG_H_INT(gob));

	//Create union of "new" and "old" gob location
	XUnionRectWithRegion(&ctx->New_Clip, ctx->Win_Region, ctx->Win_Region);
	/*
	XClipBox(ctx->Win_Region, &win_rect);
	RL_Print("Old+New, %dx%d,%dx%d\n",
			 win_rect.x,
			 win_rect.y,
			 win_rect.x + win_rect.width,
			 win_rect.y + win_rect.height);
			 */

	if (!XEmptyRegion(ctx->Win_Region))
	{
		swap_buffer(ctx);
		ctx->Window_Buffer = rebcmp_get_buffer(ctx);
		if (gob == winGob) {
			memset(ctx->Window_Buffer, 0, ctx->pixbuf_len);
		}

		//redraw gobs
		process_gobs(ctx, winGob);

		rebcmp_release_buffer(ctx);

		ctx->Window_Buffer = NULL;
	}

	//update old GOB area
	GOB_XO(gob) = GOB_LOG_X(gob);
	GOB_YO(gob) = GOB_LOG_Y(gob);
	GOB_WO(gob) = GOB_LOG_W(gob);
	GOB_HO(gob) = GOB_LOG_H(gob);
}
/*
 * 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);
		}
	}
}