Exemple #1
0
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
{
	int count;
	int status;
	int x, y;
	int width, height;
	XImage* image;
	rdpShadowScreen* screen;
	rdpShadowServer* server;
	rdpShadowSurface* surface;
	RECTANGLE_16 invalidRect;
	RECTANGLE_16 surfaceRect;
	const RECTANGLE_16 *extents;

	server = subsystem->server;
	surface = server->surface;
	screen = server->screen;

	count = ArrayList_Count(server->clients);

	if (count < 1)
		return 1;

	if ((count == 1) && subsystem->suppressOutput)
		return 1;

	surfaceRect.left = 0;
	surfaceRect.top = 0;
	surfaceRect.right = surface->width;
	surfaceRect.bottom = surface->height;

	XLockDisplay(subsystem->display);

	if (subsystem->use_xshm)
	{
		image = subsystem->fb_image;

		XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
				subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);

		status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
				(BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect);
	}
	else
	{
		image = XGetImage(subsystem->display, subsystem->root_window,
					surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap);

		status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
				(BYTE*) image->data, image->bytes_per_line, &invalidRect);
	}

	XSync(subsystem->display, False);

	XUnlockDisplay(subsystem->display);

	region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);
	region16_intersect_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &surfaceRect);

	if (!region16_is_empty(&(subsystem->invalidRegion)))
	{
		extents = region16_extents(&(subsystem->invalidRegion));

		x = extents->left;
		y = extents->top;
		width = extents->right - extents->left;
		height = extents->bottom - extents->top;

		freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
				surface->scanline, x, y, width, height,
				(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
				image->bytes_per_line, x, y, NULL);

		//x11_shadow_blend_cursor(subsystem);

		count = ArrayList_Count(server->clients);

		InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);

		SetEvent(subsystem->updateEvent);

		EnterSynchronizationBarrier(&(subsystem->barrier), 0);

		DeleteSynchronizationBarrier(&(subsystem->barrier));

		if (count == 1)
		{
			rdpShadowClient* client;

			client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0);

			if (client)
			{
				subsystem->captureFrameRate = client->encoder->fps;
			}
		}

		ResetEvent(subsystem->updateEvent);

		region16_clear(&(subsystem->invalidRegion));
	}

	if (!subsystem->use_xshm)
		XDestroyImage(image);

	return 1;
}
Exemple #2
0
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
{
	int count;
	int status;
	int x, y;
	int width, height;
	XImage* image;
	rdpShadowScreen* screen;
	rdpShadowServer* server;
	rdpShadowSurface* surface;
	RECTANGLE_16 invalidRect;

	server = subsystem->server;
	surface = server->surface;
	screen = server->screen;

	count = ArrayList_Count(server->clients);

	if (count < 1)
		return 1;

	if (subsystem->use_xshm)
	{
		XLockDisplay(subsystem->display);

		XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap,
				subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);

		XSync(subsystem->display, False);

		XUnlockDisplay(subsystem->display);

		image = subsystem->fb_image;

		status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
				(BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect);

		if (status > 0)
		{
			x = invalidRect.left;
			y = invalidRect.top;
			width = invalidRect.right - invalidRect.left;
			height = invalidRect.bottom - invalidRect.top;

			freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
					surface->scanline, x - surface->x, y - surface->y, width, height,
					(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
					image->bytes_per_line, x, y, NULL);

			region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);

			x11_shadow_blend_cursor(subsystem);

			count = ArrayList_Count(server->clients);

			InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);

			SetEvent(subsystem->updateEvent);

			EnterSynchronizationBarrier(&(subsystem->barrier), 0);

			DeleteSynchronizationBarrier(&(subsystem->barrier));

			ResetEvent(subsystem->updateEvent);

			region16_clear(&(subsystem->invalidRegion));
		}
	}
	else
	{
		XLockDisplay(subsystem->display);

		image = XGetImage(subsystem->display, subsystem->root_window,
				surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap);

		XUnlockDisplay(subsystem->display);

		status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height,
				(BYTE*) image->data, image->bytes_per_line, &invalidRect);

		if (status > 0)
		{
			x = invalidRect.left;
			y = invalidRect.top;
			width = invalidRect.right - invalidRect.left;
			height = invalidRect.bottom - invalidRect.top;

			freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
					surface->scanline, x, y, width, height,
					(BYTE*) image->data, PIXEL_FORMAT_XRGB32,
					image->bytes_per_line, x, y, NULL);

			region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect);

			x11_shadow_blend_cursor(subsystem);

			count = ArrayList_Count(server->clients);

			InitializeSynchronizationBarrier(&(subsystem->barrier), count + 1, -1);

			SetEvent(subsystem->updateEvent);

			EnterSynchronizationBarrier(&(subsystem->barrier), 0);

			DeleteSynchronizationBarrier(&(subsystem->barrier));

			ResetEvent(subsystem->updateEvent);

			region16_clear(&(subsystem->invalidRegion));
		}

		XDestroyImage(image);
	}

	return 1;
}