예제 #1
0
파일: x11_shadow.c 프로젝트: DavBfr/FreeRDP
int x11_shadow_subsystem_process_message(x11ShadowSubsystem* subsystem, wMessage* message)
{
	switch(message->id)
	{
		case SHADOW_MSG_IN_REFRESH_REQUEST_ID:
			shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem);
			break;
		default:
			WLog_ERR(TAG, "Unknown message id: %u", message->id);
			break;
	}

	if (message->Free)
		message->Free(message);

	return 1;
}
예제 #2
0
파일: x11_shadow.c 프로젝트: DavBfr/FreeRDP
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;

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

	XLockDisplay(subsystem->display);

	/*
	 * Ignore BadMatch error during image capture. The screen size may be 
	 * changed outside. We will resize to correct resolution at next frame
	 */
	XSetErrorHandler(x11_shadow_error_handler_for_capture);

	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);

		if (!image)
		{
			/*
			 * BadMatch error happened. The size may have been changed again.
			 * Give up this frame and we will resize again in next frame 
			 */
			goto fail_capture;
		}

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

	/* Restore the default error handler */
	XSetErrorHandler(NULL);

	XSync(subsystem->display, False);

	XUnlockDisplay(subsystem->display);

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

	if (!region16_is_empty(&(surface->invalidRegion)))
	{
		extents = region16_extents(&(surface->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);

		shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem);

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

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

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

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

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

	return 1;

fail_capture:
	XSetErrorHandler(NULL);
	XSync(subsystem->display, False);
	XUnlockDisplay(subsystem->display);
	return 0;
}
예제 #3
0
파일: win_shadow.c 프로젝트: jat255/FreeRDP
int win_shadow_surface_copy(winShadowSubsystem* subsystem)
{
	int x, y;
	int width;
	int height;
	int count;
	int status = 1;
	int nDstStep = 0;
	DWORD DstFormat;
	BYTE* pDstData = NULL;
	rdpShadowServer* server;
	rdpShadowSurface* surface;
	RECTANGLE_16 surfaceRect;
	RECTANGLE_16 invalidRect;
	const RECTANGLE_16* extents;
	server = subsystem->server;
	surface = server->surface;

	if (ArrayList_Count(server->clients) < 1)
	{
		region16_clear(&(surface->invalidRegion));
		return 1;
	}

	surfaceRect.left = surface->x;
	surfaceRect.top = surface->y;
	surfaceRect.right = surface->x + surface->width;
	surfaceRect.bottom = surface->y + surface->height;
	region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion),
	                        &surfaceRect);

	if (region16_is_empty(&(surface->invalidRegion)))
		return 1;

	extents = region16_extents(&(surface->invalidRegion));
	CopyMemory(&invalidRect, extents, sizeof(RECTANGLE_16));
	shadow_capture_align_clip_rect(&invalidRect, &surfaceRect);
	x = invalidRect.left;
	y = invalidRect.top;
	width = invalidRect.right - invalidRect.left;
	height = invalidRect.bottom - invalidRect.top;

	if (0)
	{
		x = 0;
		y = 0;
		width = surface->width;
		height = surface->height;
	}

	WLog_INFO(TAG,
	          "SurfaceCopy x: %d y: %d width: %d height: %d right: %d bottom: %d",
	          x, y, width, height, x + width, y + height);
#if defined(WITH_WDS_API)
	{
		rdpGdi* gdi;
		shwContext* shw;
		rdpContext* context;
		shw = subsystem->shw;
		context = (rdpContext*) shw;
		gdi = context->gdi;
		pDstData = gdi->primary_buffer;
		nDstStep = gdi->width * 4;
		DstFormat = gdi->dstFormat;
	}
#elif defined(WITH_DXGI_1_2)
	DstFormat = PIXEL_FORMAT_BGRX32;
	status = win_shadow_dxgi_fetch_frame_data(subsystem, &pDstData, &nDstStep, x, y,
	         width, height);
#endif

	if (status <= 0)
		return status;

	freerdp_image_copy(surface->data, surface->format,
	                   surface->scanline, x - surface->x, y - surface->y, width, height,
	                   pDstData, DstFormat, nDstStep, 0, 0, NULL, FREERDP_FLIP_NONE);
	ArrayList_Lock(server->clients);
	count = ArrayList_Count(server->clients);
	shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
	ArrayList_Unlock(server->clients);
	region16_clear(&(surface->invalidRegion));
	return 1;
}