Esempio n. 1
0
static BOOL xf_gdi_update_screen(xfContext* xfc,
                                 const SURFACE_BITS_COMMAND* cmd,
                                 const BYTE* pSrcData)
{
	BOOL ret;
	XImage* image;

	if (!xfc || !pSrcData)
		return FALSE;

	XSetFunction(xfc->display, xfc->gc, GXcopy);
	XSetFillStyle(xfc->display, xfc->gc, FillSolid);
	image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
	                     (char*) pSrcData, cmd->width, cmd->height, xfc->scanline_pad, 0);

	if (image)
	{
		XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
		          cmd->destLeft, cmd->destTop, cmd->width, cmd->height);
		XFree(image);
		ret = xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width,
		                                  cmd->height);
	}

	XSetClipMask(xfc->display, xfc->gc, None);
	return ret;
}
Esempio n. 2
0
static BOOL xf_gdi_update_screen(xfContext* xfc, const BYTE* pSrcData,
                                 UINT32 scanline, const REGION16* pRegion)
{
	BOOL ret = FALSE;
	XImage* image;
	UINT32 i, nbRects;
	const RECTANGLE_16* rects;
	UINT32 bpp;

	if (!xfc || !pSrcData)
		return FALSE;

	if (!(rects = region16_rects(pRegion, &nbRects)))
		return TRUE;

	if (xfc->depth > 16)
		bpp = 4;
	else if (xfc->depth > 8)
		bpp = 2;
	else
		bpp = 1;

	XSetFunction(xfc->display, xfc->gc, GXcopy);
	XSetFillStyle(xfc->display, xfc->gc, FillSolid);

	for (i = 0; i < nbRects; i++)
	{
		UINT32 left = rects[i].left;
		UINT32 top = rects[i].top;
		UINT32 width = rects[i].right - rects[i].left;
		UINT32 height = rects[i].bottom - rects[i].top;
		const BYTE* src = pSrcData + top * scanline + bpp * left;
		image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
		                     (char*) src, width, height, xfc->scanline_pad, scanline);

		if (!image)
			break;

		image->byte_order = LSBFirst;
		image->bitmap_bit_order = LSBFirst;
		XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, left, top, width, height);
		image->data = NULL;
		XDestroyImage(image);
		ret = xf_gdi_surface_update_frame(xfc, left, top, width, height);
	}

	XSetClipMask(xfc->display, xfc->gc, None);
	return ret;
}
Esempio n. 3
0
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
{
	int i, tx, ty;
	XImage* image;
	RFX_MESSAGE* message;
	xfInfo* xfi = ((xfContext*) context)->xfi;
	RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context;
	NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context;

	if (surface_bits_command->codecID == RDP_CODEC_ID_REMOTEFX)
	{
		message = rfx_process_message(rfx_context,
				surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);

		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		XSetClipRectangles(xfi->display, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				(XRectangle*) message->rects, message->num_rects, YXBanded);

		/* Draw the tiles to primary surface, each is 64x64. */
		for (i = 0; i < message->num_tiles; i++)
		{
			image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
				(char*) message->tiles[i]->data, 64, 64, 32, 0);

			tx = message->tiles[i]->x + surface_bits_command->destLeft;
			ty = message->tiles[i]->y + surface_bits_command->destTop;

			XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64);
			XFree(image);
		}

		/* Copy the updated region from backstore to the window. */
		for (i = 0; i < message->num_rects; i++)
		{
			tx = message->rects[i].x + surface_bits_command->destLeft;
			ty = message->rects[i].y + surface_bits_command->destTop;

			xf_gdi_surface_update_frame(xfi, tx, ty, message->rects[i].width, message->rects[i].height);
		}

		XSetClipMask(xfi->display, xfi->gc, None);
		rfx_message_free(rfx_context, message);
	}
	else if (surface_bits_command->codecID == RDP_CODEC_ID_NSCODEC)
	{
		nsc_process_message(nsc_context, surface_bits_command->bpp, surface_bits_command->width, surface_bits_command->height,
			surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		xfi->bmp_codec_nsc = (BYTE*) realloc(xfi->bmp_codec_nsc,
				surface_bits_command->width * surface_bits_command->height * 4);

		freerdp_image_flip(nsc_context->bmpdata, xfi->bmp_codec_nsc,
				surface_bits_command->width, surface_bits_command->height, 32);

		image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
			(char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0);

		XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);
		XFree(image);

		xf_gdi_surface_update_frame(xfi,
			surface_bits_command->destLeft, surface_bits_command->destTop,
			surface_bits_command->width, surface_bits_command->height);

		XSetClipMask(xfi->display, xfi->gc, None);
	}
	else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
	{
		XSetFunction(xfi->display, xfi->gc, GXcopy);
		XSetFillStyle(xfi->display, xfi->gc, FillSolid);

		/* Validate that the data received is large enough */
		if( surface_bits_command->width * surface_bits_command->height * surface_bits_command->bpp / 8 <= surface_bits_command->bitmapDataLength )
		{
			xfi->bmp_codec_none = (BYTE*) realloc(xfi->bmp_codec_none,
					surface_bits_command->width * surface_bits_command->height * 4);

			freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none,
					surface_bits_command->width, surface_bits_command->height, 32);

			image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0,
				(char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0);

			XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0,
					surface_bits_command->destLeft, surface_bits_command->destTop,
					surface_bits_command->width, surface_bits_command->height);
			XFree(image);

			xf_gdi_surface_update_frame(xfi,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height);

			XSetClipMask(xfi->display, xfi->gc, None);
		} else {
			printf("Invalid bitmap size - data is %d bytes for %dx%d\n update", surface_bits_command->bitmapDataLength, surface_bits_command->width, surface_bits_command->height);
		}
	}
	else
	{
		printf("Unsupported codecID %d\n", surface_bits_command->codecID);
	}
}
Esempio n. 4
0
void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
{
	int i, tx, ty;
	XImage* image;
	BYTE* pSrcData;
	BYTE* pDstData;
	RFX_MESSAGE* message;
	xfContext* xfc = (xfContext*) context;

	xf_lock_x11(xfc, FALSE);

	if (cmd->codecID == RDP_CODEC_ID_REMOTEFX)
	{
		freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_REMOTEFX);

		message = rfx_process_message(xfc->codecs->rfx, cmd->bitmapData, cmd->bitmapDataLength);

		XSetFunction(xfc->display, xfc->gc, GXcopy);
		XSetFillStyle(xfc->display, xfc->gc, FillSolid);

		XSetClipRectangles(xfc->display, xfc->gc, cmd->destLeft, cmd->destTop,
				(XRectangle*) message->rects, message->numRects, YXBanded);

		if (xfc->bitmap_size < (64 * 64 * 4))
		{
			xfc->bitmap_size = 64 * 64 * 4;
			xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);

			if (!xfc->bitmap_buffer)
				return;
		}

		/* Draw the tiles to primary surface, each is 64x64. */
		for (i = 0; i < message->numTiles; i++)
		{
			pSrcData = message->tiles[i]->data;
			pDstData = pSrcData;

			if ((xfc->depth != 24) || (xfc->depth != 32))
			{
				pDstData = xfc->bitmap_buffer;

				freerdp_image_copy(pDstData, xfc->format, -1, 0, 0,
						64, 64, pSrcData, PIXEL_FORMAT_XRGB32, -1, 0, 0, xfc->palette);
			}

			image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
				(char*) pDstData, 64, 64, xfc->scanline_pad, 0);

			tx = message->tiles[i]->x + cmd->destLeft;
			ty = message->tiles[i]->y + cmd->destTop;

			XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0, tx, ty, 64, 64);
			XFree(image);
		}

		/* Copy the updated region from backstore to the window. */
		for (i = 0; i < message->numRects; i++)
		{
			tx = message->rects[i].x + cmd->destLeft;
			ty = message->rects[i].y + cmd->destTop;

			if (!xfc->remote_app)
			{
				XCopyArea(xfc->display, xfc->primary, xfc->drawable, xfc->gc,
						tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
			}

			xf_gdi_surface_update_frame(xfc, tx, ty, message->rects[i].width, message->rects[i].height);
		}

		XSetClipMask(xfc->display, xfc->gc, None);
		rfx_message_free(xfc->codecs->rfx, message);
	}
	else if (cmd->codecID == RDP_CODEC_ID_NSCODEC)
	{
		freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_NSCODEC);

		nsc_process_message(xfc->codecs->nsc, cmd->bpp, cmd->width, cmd->height, cmd->bitmapData, cmd->bitmapDataLength);

		XSetFunction(xfc->display, xfc->gc, GXcopy);
		XSetFillStyle(xfc->display, xfc->gc, FillSolid);

		if (xfc->bitmap_size < (cmd->width * cmd->height * 4))
		{
			xfc->bitmap_size = cmd->width * cmd->height * 4;
			xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);

			if (!xfc->bitmap_buffer)
				return;
		}

		pSrcData = xfc->codecs->nsc->BitmapData;
		pDstData = xfc->bitmap_buffer;

		freerdp_image_copy(pDstData, xfc->format, -1, 0, 0,
					cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette);

		image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
				(char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0);

		XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
				cmd->destLeft, cmd->destTop, cmd->width, cmd->height);

		XFree(image);

		if (!xfc->remote_app)
		{
			XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, 
					cmd->destLeft, cmd->destTop, cmd->width, cmd->height,
					cmd->destLeft, cmd->destTop);
		}

		xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height);

		XSetClipMask(xfc->display, xfc->gc, None);
	}
	else if (cmd->codecID == RDP_CODEC_ID_NONE)
	{
		XSetFunction(xfc->display, xfc->gc, GXcopy);
		XSetFillStyle(xfc->display, xfc->gc, FillSolid);

		if (xfc->bitmap_size < (cmd->width * cmd->height * 4))
		{
			xfc->bitmap_size = cmd->width * cmd->height * 4;
			xfc->bitmap_buffer = (BYTE*) _aligned_realloc(xfc->bitmap_buffer, xfc->bitmap_size, 16);

			if (!xfc->bitmap_buffer)
				return;
		}

		pSrcData = cmd->bitmapData;
		pDstData = xfc->bitmap_buffer;

		freerdp_image_copy(pDstData, xfc->format, -1, 0, 0,
				cmd->width, cmd->height, pSrcData, PIXEL_FORMAT_XRGB32_VF, -1, 0, 0, xfc->palette);

		image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
			(char*) pDstData, cmd->width, cmd->height, xfc->scanline_pad, 0);

		XPutImage(xfc->display, xfc->primary, xfc->gc, image, 0, 0,
				cmd->destLeft, cmd->destTop,
				cmd->width, cmd->height);
		XFree(image);

		if (!xfc->remote_app)
		{
			XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc,
					cmd->destLeft, cmd->destTop,
					cmd->width, cmd->height, cmd->destLeft, cmd->destTop);
		}

		xf_gdi_surface_update_frame(xfc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height);

		XSetClipMask(xfc->display, xfc->gc, None);
	}
	else
	{
		WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID);
	}

	xf_unlock_x11(xfc, FALSE);
}