Exemple #1
0
TLIBAPI TBOOL region_subregion(struct RectPool *pool, struct Region *dregion,
	struct Region *sregion)
{
	TBOOL success = TTRUE;
	struct TNode *next, *node = sregion->rg_Rects.rl_List.tlh_Head;
	for (; success && (next = node->tln_Succ); node = next)
	{
		struct RectNode *rn = (struct RectNode *) node;
		success = region_subrect(pool, dregion, rn->rn_Rect);
	}
	/* note: if unsucessful, dregion is of no use anymore */
	return success;
}
Exemple #2
0
LOCAL void rfb_flush_clients(struct rfb_Display *mod, TBOOL also_external)
{
	TAPTR TExecBase = mod->rfb_ExecBase;
	struct RectPool *pool = &mod->rfb_RectPool;

	/* flush windows to buffer */

	/* screen mask: */
	struct Rect s;

	REGION_RECT_SET(&s, 0, 0, mod->rfb_Width - 1, mod->rfb_Height - 1);
	struct Region S;

	if (region_init(pool, &S, s.r))
	{
		struct TNode *next, *node = mod->rfb_VisualList.tlh_Head.tln_Succ;

		for (; (next = node->tln_Succ); node = next)
		{
			struct rfb_Window *v = (struct rfb_Window *) node;

			if (v->rfbw_Flags & RFBWFL_DIRTY)
			{
				struct Region *R = &v->rfbw_DirtyRegion;
				TINT sx = v->rfbw_ScreenRect.r[0];
				TINT sy = v->rfbw_ScreenRect.r[1];

				region_shift(R, sx, sy);
				region_andregion(pool, R, &S);
				struct TNode *rnext, *rnode = 
					R->rg_Rects.rl_List.tlh_Head.tln_Succ;

				for (; (rnext = rnode->tln_Succ); rnode = rnext)
				{
					struct RectNode *r = (struct RectNode *) rnode;
					TINT x0 = r->rn_Rect[0];
					TINT y0 = r->rn_Rect[1];
					TINT x1 = r->rn_Rect[2];
					TINT y1 = r->rn_Rect[3];

					pixconv_convert(&v->rfbw_PixBuf, &mod->rfb_PixBuf,
						x0, y0, x1, y1, x0 - sx, y0 - sy, TFALSE, TFALSE);

					region_orrect(pool, &mod->rfb_DirtyRegion, r->rn_Rect,
						TTRUE);
					mod->rfb_Flags |= RFBFL_DIRTY;
				}
				region_free(pool, R);
				v->rfbw_Flags &= ~RFBWFL_DIRTY;
			}
			/* subtract this window from screenmask: */
			region_subrect(pool, &S, v->rfbw_ScreenRect.r);
		}
		region_free(pool, &S);
	}

	/* flush buffer to device(s) */
	if (mod->rfb_Flags & RFBFL_DIRTY)
	{
		struct Region *D = &mod->rfb_DirtyRegion;
		struct TNode *next, *node;

#if defined(ENABLE_VNCSERVER)
		if (also_external && mod->rfb_VNCTask)
			rfb_vnc_flush(mod, D);
#endif
		/* flush to sub pixbuf: */
		if (mod->rfb_Flags & RFBFL_BUFFER_DEVICE)
		{
			node = D->rg_Rects.rl_List.tlh_Head.tln_Succ;
			for (; (next = node->tln_Succ); node = next)
			{
				struct RectNode *r = (struct RectNode *) node;
				TINT x0 = r->rn_Rect[0];
				TINT y0 = r->rn_Rect[1];
				TINT x1 = r->rn_Rect[2];
				TINT y1 = r->rn_Rect[3];

				pixconv_convert(&mod->rfb_PixBuf, &mod->rfb_DevBuf,
					x0, y0, x1, y1, x0, y0, TFALSE, TFALSE);
			}
		}

		/* flush to sub device: */
		if (mod->rfb_RndDevice)
		{
			TTAGITEM tags[2];

			tags[0].tti_Tag = TVisual_PixelFormat;
			tags[0].tti_Value = mod->rfb_PixBuf.tpb_Format;
			tags[1].tti_Tag = TTAG_DONE;

			/* NOTE: do multiple flushes asynchronously? */

			struct TVRequest *req = mod->rfb_RndRequest;

			req->tvr_Req.io_Command = TVCMD_DRAWBUFFER;
			req->tvr_Op.DrawBuffer.Window = mod->rfb_RndInstance;
			req->tvr_Op.DrawBuffer.Tags = tags;
			req->tvr_Op.DrawBuffer.TotWidth = mod->rfb_Width;

			node = D->rg_Rects.rl_List.tlh_Head.tln_Succ;
			for (; (next = node->tln_Succ); node = next)
			{
				struct RectNode *r = (struct RectNode *) node;
				TINT x0 = r->rn_Rect[0];
				TINT y0 = r->rn_Rect[1];
				TINT x1 = r->rn_Rect[2];
				TINT y1 = r->rn_Rect[3];

				req->tvr_Op.DrawBuffer.RRect[0] = x0;
				req->tvr_Op.DrawBuffer.RRect[1] = y0;
				req->tvr_Op.DrawBuffer.RRect[2] = x1 - x0 + 1;
				req->tvr_Op.DrawBuffer.RRect[3] = y1 - y0 + 1;
				req->tvr_Op.DrawBuffer.Buf =
					TVPB_GETADDRESS(&mod->rfb_PixBuf, x0, y0);
				TDoIO(&req->tvr_Req);
			}

			req->tvr_Req.io_Command = TVCMD_FLUSH;
			req->tvr_Op.Flush.Window = mod->rfb_RndInstance;
			req->tvr_Op.Flush.Rect[0] = 0;
			req->tvr_Op.Flush.Rect[1] = 0;
			req->tvr_Op.Flush.Rect[2] = -1;
			req->tvr_Op.Flush.Rect[3] = -1;
			TDoIO(&req->tvr_Req);
		}

		region_free(&mod->rfb_RectPool, D);
		mod->rfb_Flags &= ~RFBFL_DIRTY;
	}
}
Exemple #3
0
LOCAL TBOOL rfb_damage(struct rfb_Display *mod, TINT drect[],
	struct rfb_Window *v)
{
	TAPTR TExecBase = TGetExecBase(mod);
	struct RectPool *pool = &mod->rfb_RectPool;
	struct Region A, B;

	if (!region_init(pool, &A, drect))
		return TFALSE;

	TDBPRINTF(TDB_TRACE, ("incoming damage: %d %d %d %d\n",
			drect[0], drect[1], drect[2], drect[3]));

	/* traverse window stack; refresh B where A and B overlap ; A = A - B */

	struct TNode *next, *node = mod->rfb_VisualList.tlh_Head.tln_Succ;
	TBOOL success = TTRUE;
	TBOOL below = TFALSE;

	TLock(mod->rfb_InstanceLock);

	for (; success && !region_isempty(pool, &A) &&
		(next = node->tln_Succ); node = next)
	{
		struct rfb_Window *bv = (struct rfb_Window *) node;

		if (v && !below)
		{
			if (bv == v)
				below = TTRUE;
			else
				/* above: subtract current from rect to be damaged: */
				success = region_subrect(pool, &A, bv->rfbw_ScreenRect.r);
			continue;
		}

		success = TFALSE;
		if (region_init(pool, &B, bv->rfbw_ScreenRect.r))
		{
			if (region_andregion(pool, &B, &A))
			{
				region_shift(&B,
					bv->rfbw_WinRect.r[0] - bv->rfbw_ScreenRect.r[0],
					bv->rfbw_WinRect.r[1] - bv->rfbw_ScreenRect.r[1]);

				struct TNode *next, 
					*node = B.rg_Rects.rl_List.tlh_Head.tln_Succ;

				for (; (next = node->tln_Succ); node = next)
				{
					struct RectNode *r = (struct RectNode *) node;

					if (bv->rfbw_Flags & RFBWFL_BACKBUFFER)
					{
						rfb_markdirty(mod, bv, r->rn_Rect);
					}
					else if (bv->rfbw_InputMask & TITYPE_REFRESH)
					{
						TIMSG *imsg;

						if (rfb_getimsg(mod, bv, &imsg, TITYPE_REFRESH))
						{
							TDBPRINTF(TDB_TRACE, ("send refresh %d %d %d %d\n",
									r->rn_Rect[0], r->rn_Rect[1],
									r->rn_Rect[2], r->rn_Rect[3]));
							imsg->timsg_X = r->rn_Rect[0];
							imsg->timsg_Y = r->rn_Rect[1];
							imsg->timsg_Width =
								r->rn_Rect[2] - r->rn_Rect[0] + 1;
							imsg->timsg_Height =
								r->rn_Rect[3] - r->rn_Rect[1] + 1;
							imsg->timsg_X -= bv->rfbw_ScreenRect.r[0];
							imsg->timsg_Y -= bv->rfbw_ScreenRect.r[1];
							TPutMsg(bv->rfbw_IMsgPort, TNULL, imsg);
						}
					}
				}
				success = TTRUE;
			}
			region_free(pool, &B);
		}

		if (success)
			success = region_subrect(pool, &A, bv->rfbw_ScreenRect.r);
	}

	TUnlock(mod->rfb_InstanceLock);

	region_free(pool, &A);

	return success;
}