Esempio n. 1
0
void
test_message(void)
{
	RFX_CONTEXT * context;
	uint8 buffer[1024000];
	int size;
	int i, j;
	RFX_RECT rect = {0, 0, 100, 80};
	RFX_MESSAGE * message;

	rgb_data = (uint8 *) malloc(100 * 80 * 3);
	for (i = 0; i < 80; i++)
		memcpy(rgb_data + i * 100 * 3, rgb_scanline_data, 100 * 3);

	context = rfx_context_new();
	context->mode = RLGR3;
	context->width = 800;
	context->height = 600;
	rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_RGB);

	size = rfx_compose_message_header(context, buffer, sizeof(buffer));
	/*hexdump(buffer, size);*/
	message = rfx_process_message(context, buffer, size);
	rfx_message_free(context, message);

	for (i = 0; i < 1000; i++)
	{
		size = rfx_compose_message_data(context, buffer, sizeof(buffer),
			&rect, 1, rgb_data, 100, 80, 100 * 3);
		/*hexdump(buffer, size);*/
		message = rfx_process_message(context, buffer, size);
		if (i == 0)
		{
			for (j = 0; j < message->num_tiles; j++)
			{
				dump_ppm_image(message->tiles[j]->data);
			}
		}
		rfx_message_free(context, message);
	}

	rfx_context_free(context);
	free(rgb_data);
}
Esempio n. 2
0
File: rfx.c Progetto: C4rt/FreeRDP
RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
		BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize)
{
	RFX_MESSAGE* message;
	RFX_MESSAGE* messageList;

	if (!(message = rfx_encode_message(context, rects, numRects, data, width, height, scanline)))
		return NULL;

	if (!(messageList = rfx_split_message(context, message, numMessages, maxDataSize)))
	{
		message->freeRects = TRUE;
		rfx_message_free(context, message);
		return NULL;
	}

	rfx_message_free(context, message);
	return messageList;
}
Esempio n. 3
0
void rfx_compose_message(RFX_CONTEXT* context, wStream* s,
	const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline)
{
	RFX_MESSAGE* message;

 	message = rfx_encode_message(context, rects, numRects, data, width, height, scanline);

	rfx_write_message(context, s, message);

	rfx_message_free(context, message);
}
Esempio n. 4
0
RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
		BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize)
{
	RFX_MESSAGE* message;
	RFX_MESSAGE* messages;

	message = rfx_encode_message(context, rects, numRects, data, width, height, scanline);
	messages = rfx_split_message(context, message, numMessages, maxDataSize);
	rfx_message_free(context, message);

	return messages;
}
Esempio n. 5
0
static void
xf_decode_frame(xfInfo * xfi, int x, int y, uint8 * bitmapData, uint32 bitmapDataLength)
{
    int i;
    int tx, ty;
    XImage * image;
    RFX_MESSAGE * message;

    switch (xfi->codec)
    {
    case XF_CODEC_REMOTEFX:

        message = rfx_process_message((RFX_CONTEXT *) xfi->rfx_context, bitmapData, bitmapDataLength);

        /* Clip the updated region based on the union of rects, so that pixels outside of the region will not be drawn. */
        XSetFunction(xfi->display, xfi->gc, GXcopy);
        XSetFillStyle(xfi->display, xfi->gc, FillSolid);
        XSetClipRectangles(xfi->display, xfi->gc, x, y, (XRectangle*)message->rects, message->num_rects, YXBanded);

        /* Draw the tiles to backstore, 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 + x;
            ty = message->tiles[i]->y + y;
            XPutImage(xfi->display, xfi->backstore, 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 + x;
            ty = message->rects[i].y + y;
            XCopyArea(xfi->display, xfi->backstore, xfi->wnd, xfi->gc_default,
                      tx, ty, message->rects[i].width, message->rects[i].height, tx, ty);
        }
        rfx_message_free(xfi->rfx_context, message);

        XSetClipMask(xfi->display, xfi->gc, None);

        break;

    default:
        printf("xf_decode_frame: no codec defined.\n");
        break;
    }
}
Esempio n. 6
0
File: rfx.c Progetto: C4rt/FreeRDP
BOOL rfx_compose_message(RFX_CONTEXT* context, wStream* s,
	const RFX_RECT* rects, int numRects, BYTE* data, int width, int height, int scanline)
{
	RFX_MESSAGE* message;
	BOOL ret = TRUE;

	if (!(message = rfx_encode_message(context, rects, numRects, data, width, height, scanline)))
		return FALSE;

	ret = rfx_write_message(context, s, message);

	message->freeRects = TRUE;
	rfx_message_free(context, message);

	return ret;
}
Esempio n. 7
0
void test_message(void)
{
	RFX_CONTEXT* context;
	STREAM* s;
	int i, j;
	RFX_RECT rect = {0, 0, 100, 80};
	RFX_MESSAGE * message;

	rgb_data = (BYTE *) malloc(100 * 80 * 3);
	for (i = 0; i < 80; i++)
		memcpy(rgb_data + i * 100 * 3, rgb_scanline_data, 100 * 3);

	s = stream_new(65536);
	stream_clear(s);

	context = rfx_context_new();
	context->mode = RLGR3;
	context->width = 800;
	context->height = 600;
	rfx_context_set_pixel_format(context, RDP_PIXEL_FORMAT_R8G8B8);

	for (i = 0; i < 1000; i++)
	{
		s = stream_new(65536);
		stream_clear(s);
		rfx_compose_message(context, s,
			&rect, 1, rgb_data, 100, 80, 100 * 3);
		stream_seal(s);
		/*hexdump(buffer, size);*/
		stream_set_pos(s, 0);
		message = rfx_process_message(context, s->p, s->size);
		if (i == 0)
		{
			for (j = 0; j < message->num_tiles; j++)
			{
				dump_ppm_image(message->tiles[j]->data);
			}
		}
		rfx_message_free(context, message);
		stream_free(s);
	}

	rfx_context_free(context);
	free(rgb_data);
}
Esempio n. 8
0
void rf_object_free(RemminaProtocolWidget* gp, RemminaPluginRdpUiObject* obj)
{
    rfContext* rfi;

    rfi = GET_DATA(gp);

    switch (obj->type)
    {
    case REMMINA_RDP_UI_RFX:
        rfx_message_free(rfi->rfx_context, obj->rfx.message);
        break;

    case REMMINA_RDP_UI_NOCODEC:
        free(obj->nocodec.bitmap);
        break;

    default:
        break;
    }

    g_free(obj);
}
Esempio n. 9
0
int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
	int j;
	UINT16 i;
	RFX_RECT* rect;
	RFX_TILE* tile;
	int nXDst, nYDst;
	int nWidth, nHeight;
	int nbUpdateRects;
	RFX_MESSAGE* message;
	gdiGfxSurface* surface;
	REGION16 updateRegion;
	RECTANGLE_16 updateRect;
	RECTANGLE_16* updateRects;
	REGION16 clippingRects;
	RECTANGLE_16 clippingRect;

	freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX);

	surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);

	if (!surface)
		return -1;

	message = rfx_process_message(gdi->codecs->rfx, cmd->data, cmd->length);

	if (!message)
		return -1;

	region16_init(&clippingRects);

	for (i = 0; i < message->numRects; i++)
	{
		rect = &(message->rects[i]);

		clippingRect.left = cmd->left + rect->x;
		clippingRect.top = cmd->top + rect->y;
		clippingRect.right = clippingRect.left + rect->width;
		clippingRect.bottom = clippingRect.top + rect->height;

		region16_union_rect(&clippingRects, &clippingRects, &clippingRect);
	}

	for (i = 0; i < message->numTiles; i++)
	{
		tile = message->tiles[i];

		updateRect.left = cmd->left + tile->x;
		updateRect.top = cmd->top + tile->y;
		updateRect.right = updateRect.left + 64;
		updateRect.bottom = updateRect.top + 64;

		region16_init(&updateRegion);
		region16_intersect_rect(&updateRegion, &clippingRects, &updateRect);
		updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects);

		for (j = 0; j < nbUpdateRects; j++)
		{
			nXDst = updateRects[j].left;
			nYDst = updateRects[j].top;
			nWidth = updateRects[j].right - updateRects[j].left;
			nHeight = updateRects[j].bottom - updateRects[j].top;

			freerdp_image_copy(surface->data, surface->format, surface->scanline,
					nXDst, nYDst, nWidth, nHeight,
					tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL);

			region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &updateRects[j]);
		}

		region16_uninit(&updateRegion);
	}

	rfx_message_free(gdi->codecs->rfx, message);

	if (!gdi->inGfxFrame)
		gdi_OutputUpdate(gdi);

	return 1;
}
Esempio n. 10
0
void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_command)
{
	int i, j;
	int tx, ty;
	char* tile_bitmap;
	RFX_MESSAGE* message;
	BITMAPINFO bitmap_info;

	RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfc->rfx_context;
	NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfc->nsc_context;

	tile_bitmap = (char*) malloc(32);
	ZeroMemory(tile_bitmap, 32);

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

		/* blit each tile */
		for (i = 0; i < message->numTiles; i++)
		{
			tx = message->tiles[i]->x + surface_bits_command->destLeft;
			ty = message->tiles[i]->y + surface_bits_command->destTop;

			freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv);

			for (j = 0; j < message->numRects; j++)
			{
				wf_set_clip_rgn(wfc,
					surface_bits_command->destLeft + message->rects[j].x,
					surface_bits_command->destTop + message->rects[j].y,
					message->rects[j].width, message->rects[j].height);

				BitBlt(wfc->primary->hdc, tx, ty, 64, 64, wfc->tile->hdc, 0, 0, SRCCOPY);
			}
		}

		wf_set_null_clip_rgn(wfc);

		/* invalidate regions */
		for (i = 0; i < message->numRects; i++)
		{
			tx = surface_bits_command->destLeft + message->rects[i].x;
			ty = surface_bits_command->destTop + message->rects[i].y;
			wf_invalidate_region(wfc, tx, ty, message->rects[i].width, message->rects[i].height);
		}

		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);
		ZeroMemory(&bitmap_info, sizeof(bitmap_info));
		bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bitmap_info.bmiHeader.biWidth = surface_bits_command->width;
		bitmap_info.bmiHeader.biHeight = surface_bits_command->height;
		bitmap_info.bmiHeader.biPlanes = 1;
		bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp;
		bitmap_info.bmiHeader.biCompression = BI_RGB;
		SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
			surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
			nsc_context->BitmapData, &bitmap_info, DIB_RGB_COLORS);
		wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
			surface_bits_command->width, surface_bits_command->height);
	}
	else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)
	{
		ZeroMemory(&bitmap_info, sizeof(bitmap_info));
		bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bitmap_info.bmiHeader.biWidth = surface_bits_command->width;
		bitmap_info.bmiHeader.biHeight = surface_bits_command->height;
		bitmap_info.bmiHeader.biPlanes = 1;
		bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp;
		bitmap_info.bmiHeader.biCompression = BI_RGB;
		SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
			surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
			surface_bits_command->bitmapData, &bitmap_info, DIB_RGB_COLORS);
		wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
			surface_bits_command->width, surface_bits_command->height);
	}
	else
	{
		fprintf(stderr, "Unsupported codecID %d\n", surface_bits_command->codecID);
	}

	if (tile_bitmap != NULL)
		free(tile_bitmap);
}
Esempio n. 11
0
/**
 * Function description
 *
 * @return TRUE on success
 */
static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, 
		BYTE* pSrcData, int nSrcStep, int nXSrc, int nYSrc, int nWidth, int nHeight)
{
	BOOL ret = TRUE;
	int i;
	BOOL first;
	BOOL last;
	wStream* s;
	int numMessages;
	UINT32 frameId = 0;
	rdpUpdate* update;
	rdpContext* context;
	rdpSettings* settings;
	rdpShadowServer* server;
	rdpShadowEncoder* encoder;
	SURFACE_BITS_COMMAND cmd;

	context = (rdpContext*) client;
	update = context->update;
	settings = context->settings;

	server = client->server;
	encoder = client->encoder;

	if (encoder->frameAck)
		frameId = shadow_encoder_create_frame_id(encoder);

	if (settings->RemoteFxCodec)
	{
		RFX_RECT rect;
		RFX_MESSAGE* messages;
		RFX_RECT *messageRects = NULL;

		if (shadow_encoder_prepare(encoder, FREERDP_CODEC_REMOTEFX) < 0)
		{
			WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_REMOTEFX");
			return FALSE;
		}

		s = encoder->bs;

		rect.x = nXSrc;
		rect.y = nYSrc;
		rect.width = nWidth;
		rect.height = nHeight;

		if (!(messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData,
				settings->DesktopWidth, settings->DesktopHeight, nSrcStep, &numMessages,
				settings->MultifragMaxRequestSize)))
		{
			WLog_ERR(TAG, "rfx_encode_messages failed");
			return FALSE;
		}

		cmd.codecID = settings->RemoteFxCodecId;

		cmd.destLeft = 0;
		cmd.destTop = 0;
		cmd.destRight = settings->DesktopWidth;
		cmd.destBottom = settings->DesktopHeight;

		cmd.bpp = 32;
		cmd.width = settings->DesktopWidth;
		cmd.height = settings->DesktopHeight;
		cmd.skipCompression = TRUE;

		if (numMessages > 0)
			messageRects = messages[0].rects;

		for (i = 0; i < numMessages; i++)
		{
			Stream_SetPosition(s, 0);
			if (!rfx_write_message(encoder->rfx, s, &messages[i]))
			{
				while (i < numMessages)
				{
					rfx_message_free(encoder->rfx, &messages[i++]);
				}
				WLog_ERR(TAG, "rfx_write_message failed");
				ret = FALSE;
				break;
			}
			rfx_message_free(encoder->rfx, &messages[i]);

			cmd.bitmapDataLength = Stream_GetPosition(s);
			cmd.bitmapData = Stream_Buffer(s);

			first = (i == 0) ? TRUE : FALSE;
			last = ((i + 1) == numMessages) ? TRUE : FALSE;

			if (!encoder->frameAck)
				IFCALLRET(update->SurfaceBits, ret, update->context, &cmd);
			else
				IFCALLRET(update->SurfaceFrameBits, ret, update->context, &cmd, first, last, frameId);

			if (!ret)
			{
				WLog_ERR(TAG, "Send surface bits(RemoteFxCodec) failed");
				break;
			}
		}

		free(messageRects);
		free(messages);
	}
	else if (settings->NSCodec)
	{
		if (shadow_encoder_prepare(encoder, FREERDP_CODEC_NSCODEC) < 0)
		{
			WLog_ERR(TAG, "Failed to prepare encoder FREERDP_CODEC_NSCODEC");
			return FALSE;
		}

		s = encoder->bs;
		Stream_SetPosition(s, 0);

		pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];

		nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep);

		cmd.bpp = 32;
		cmd.codecID = settings->NSCodecId;
		cmd.destLeft = nXSrc;
		cmd.destTop = nYSrc;
		cmd.destRight = cmd.destLeft + nWidth;
		cmd.destBottom = cmd.destTop + nHeight;
		cmd.width = nWidth;
		cmd.height = nHeight;

		cmd.bitmapDataLength = Stream_GetPosition(s);
		cmd.bitmapData = Stream_Buffer(s);

		first = TRUE;
		last = TRUE;

		if (!encoder->frameAck)
			IFCALLRET(update->SurfaceBits, ret, update->context, &cmd);
		else
			IFCALLRET(update->SurfaceFrameBits, ret, update->context, &cmd, first, last, frameId);

		if (!ret)
		{
			WLog_ERR(TAG, "Send surface bits(NSCodec) failed");
		}
	}

	return ret;
}
Esempio n. 12
0
int freerds_send_surface_bits(rdsConnection* connection, int bpp, RDS_MSG_PAINT_RECT* msg)
{
	int i;
	BYTE* data;
	wStream* s;
	int scanline;
	int numMessages;
	int bytesPerPixel;
	SURFACE_BITS_COMMAND cmd;
	rdpUpdate* update = ((rdpContext*) connection)->update;

	if (!msg->framebuffer->fbAttached)
		return 0;

	if ((bpp == 24) || (bpp == 32))
	{
		bytesPerPixel = 4;
	}
	else
	{
		printf("%s: unsupported bpp: %d\n", __FUNCTION__, bpp);
		return -1;
	}

	if (msg->fbSegmentId)
	{
		bpp = msg->framebuffer->fbBitsPerPixel;
		data = msg->framebuffer->fbSharedMemory;
		scanline = msg->framebuffer->fbScanline;
	}
	else
	{
		data = msg->bitmapData;
		scanline = bytesPerPixel * msg->nWidth;
	}

	//printf("%s: bpp: %d x: %d y: %d width: %d height: %d\n", __FUNCTION__,
	//		bpp, msg->nLeftRect, msg->nTopRect, msg->nWidth, msg->nHeight);

	if (connection->settings->RemoteFxCodec)
	{
		RFX_RECT rect;
		RFX_MESSAGE* messages;

		s = connection->encoder->rfx_s;

		rect.x = msg->nLeftRect;
		rect.y = msg->nTopRect;
		rect.width = msg->nWidth;
		rect.height = msg->nHeight;

		messages = rfx_encode_messages(connection->encoder->rfx_context, &rect, 1, data,
				msg->nWidth, msg->nHeight, scanline, &numMessages,
				connection->settings->MultifragMaxRequestSize);

		cmd.codecID = connection->settings->RemoteFxCodecId;

		cmd.destLeft = msg->nLeftRect;
		cmd.destTop = msg->nTopRect;
		cmd.destRight = msg->nLeftRect + msg->nWidth;
		cmd.destBottom = msg->nTopRect + msg->nHeight;

		cmd.bpp = 32;
		cmd.width = msg->nWidth;
		cmd.height = msg->nHeight;

		for (i = 0; i < numMessages; i++)
		{
			Stream_SetPosition(s, 0);
			rfx_write_message(connection->encoder->rfx_context, s, &messages[i]);
			rfx_message_free(connection->encoder->rfx_context, &messages[i]);

			cmd.bitmapDataLength = Stream_GetPosition(s);
			cmd.bitmapData = Stream_Buffer(s);

			IFCALL(update->SurfaceBits, update->context, &cmd);
		}

		free(messages);

		return 0;
	}
	else if (connection->settings->NSCodec)
	{
		NSC_MESSAGE* messages;

		s = connection->encoder->nsc_s;

		messages = nsc_encode_messages(connection->encoder->nsc_context, data,
				msg->nLeftRect, msg->nTopRect, msg->nWidth, msg->nHeight,
				scanline, &numMessages, connection->settings->MultifragMaxRequestSize);

		cmd.bpp = 32;
		cmd.codecID = connection->settings->NSCodecId;

		for (i = 0; i < numMessages; i++)
		{
			Stream_SetPosition(s, 0);

			nsc_write_message(connection->encoder->nsc_context, s, &messages[i]);
			nsc_message_free(connection->encoder->nsc_context, &messages[i]);

			cmd.destLeft = messages[i].x;
			cmd.destTop = messages[i].y;
			cmd.destRight = messages[i].x + messages[i].width;
			cmd.destBottom = messages[i].y + messages[i].height;
			cmd.width = messages[i].width;
			cmd.height = messages[i].height;

			cmd.bitmapDataLength = Stream_GetPosition(s);
			cmd.bitmapData = Stream_Buffer(s);

			IFCALL(update->SurfaceBits, update->context, &cmd);
		}

		free(messages);

		return 0;
	}
	else
	{
		printf("%s: no codecs available!\n", __FUNCTION__);
		return -1;
	}

	return 0;
}
Esempio n. 13
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);
}
Esempio n. 14
0
int shadow_client_send_surface_bits(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight)
{
	int i;
	BOOL first;
	BOOL last;
	wStream* s;
	int nSrcStep;
	BYTE* pSrcData;
	int numMessages;
	UINT32 frameId = 0;
	rdpUpdate* update;
	rdpContext* context;
	rdpSettings* settings;
	rdpShadowServer* server;
	rdpShadowEncoder* encoder;
	SURFACE_BITS_COMMAND cmd;

	context = (rdpContext*) client;
	update = context->update;
	settings = context->settings;

	server = client->server;
	encoder = client->encoder;

	pSrcData = surface->data;
	nSrcStep = surface->scanline;

	if (server->shareSubRect)
	{
		int subX, subY;
		int subWidth, subHeight;

		subX = server->subRect.left;
		subY = server->subRect.top;
		subWidth = server->subRect.right - server->subRect.left;
		subHeight = server->subRect.bottom - server->subRect.top;

		nXSrc -= subX;
		nYSrc -= subY;
		pSrcData = &pSrcData[(subY * nSrcStep) + (subX * 4)];
	}

	if (encoder->frameAck)
		frameId = shadow_encoder_create_frame_id(encoder);

	if (settings->RemoteFxCodec)
	{
		RFX_RECT rect;
		RFX_MESSAGE* messages;
		RFX_RECT *messageRects = NULL;

		shadow_encoder_prepare(encoder, FREERDP_CODEC_REMOTEFX);

		s = encoder->bs;

		rect.x = nXSrc;
		rect.y = nYSrc;
		rect.width = nWidth;
		rect.height = nHeight;

		if (!(messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData,
				settings->DesktopWidth, settings->DesktopHeight, nSrcStep, &numMessages,
				settings->MultifragMaxRequestSize)))
		{
			return 0;
		}

		cmd.codecID = settings->RemoteFxCodecId;

		cmd.destLeft = 0;
		cmd.destTop = 0;
		cmd.destRight = settings->DesktopWidth;
		cmd.destBottom = settings->DesktopHeight;

		cmd.bpp = 32;
		cmd.width = settings->DesktopWidth;
		cmd.height = settings->DesktopHeight;
		cmd.skipCompression = TRUE;

		if (numMessages > 0)
			messageRects = messages[0].rects;

		for (i = 0; i < numMessages; i++)
		{
			Stream_SetPosition(s, 0);
			if (!rfx_write_message(encoder->rfx, s, &messages[i]))
			{
				while (i < numMessages)
				{
					rfx_message_free(encoder->rfx, &messages[i++]);
				}
				break;
			}
			rfx_message_free(encoder->rfx, &messages[i]);

			cmd.bitmapDataLength = Stream_GetPosition(s);
			cmd.bitmapData = Stream_Buffer(s);

			first = (i == 0) ? TRUE : FALSE;
			last = ((i + 1) == numMessages) ? TRUE : FALSE;

			if (!encoder->frameAck)
				IFCALL(update->SurfaceBits, update->context, &cmd);
			else
				IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId);
		}

		free(messageRects);
		free(messages);
	}
	else if (settings->NSCodec)
	{
		shadow_encoder_prepare(encoder, FREERDP_CODEC_NSCODEC);

		s = encoder->bs;
		Stream_SetPosition(s, 0);

		pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];

		nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep);

		cmd.bpp = 32;
		cmd.codecID = settings->NSCodecId;
		cmd.destLeft = nXSrc;
		cmd.destTop = nYSrc;
		cmd.destRight = cmd.destLeft + nWidth;
		cmd.destBottom = cmd.destTop + nHeight;
		cmd.width = nWidth;
		cmd.height = nHeight;

		cmd.bitmapDataLength = Stream_GetPosition(s);
		cmd.bitmapData = Stream_Buffer(s);

		first = TRUE;
		last = TRUE;

		if (!encoder->frameAck)
			IFCALL(update->SurfaceBits, update->context, &cmd);
		else
			IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId);
	}

	return 1;
}
Esempio n. 15
0
void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
{
	int i, tx, ty;
	XImage* image;
	RFX_MESSAGE* message;
	xfInfo* xfi = GET_XFI(update);
	RFX_CONTEXT* context = (RFX_CONTEXT*) xfi->rfx_context;
	NSC_CONTEXT* ncontext = (NSC_CONTEXT*) xfi->nsc_context;

	if (surface_bits_command->codecID == CODEC_ID_REMOTEFX)
	{
		message = rfx_process_message(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;

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

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

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

		xfi->bmp_codec_nsc = (uint8*) xrealloc(xfi->bmp_codec_nsc,
				surface_bits_command->width * surface_bits_command->height * 4);

		freerdp_image_flip(ncontext->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);

		if (xfi->remote_app != True)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height,
				surface_bits_command->destLeft, surface_bits_command->destTop);
		}

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

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

		xfi->bmp_codec_none = (uint8*) xrealloc(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);

		if (xfi->remote_app != True)
		{
			XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc,
				surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height,
				surface_bits_command->destLeft, surface_bits_command->destTop);
		}

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

		XSetClipMask(xfi->display, xfi->gc, None);
	}
	else
	{
		printf("Unsupported codecID %d\n", surface_bits_command->codecID);
	}
}
Esempio n. 16
0
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
		BYTE* data, int width, int height, int bpp, int length,
		BOOL compressed, int codecId)
{
	BOOL status;
	UINT16 size;
	BYTE* src;
	BYTE* dst;
	int yindex;
	int xindex;
	rdpGdi* gdi;
	RFX_MESSAGE* msg;

	size = width * height * ((bpp + 7) / 8);

	if (!bitmap->data)
		bitmap->data = (BYTE*) malloc(size);
	else
		bitmap->data = (BYTE*) realloc(bitmap->data, size);

	switch (codecId)
	{
		case RDP_CODEC_ID_NSCODEC:
			gdi = context->gdi;
			nsc_process_message(gdi->nsc_context, bpp, width, height, data, length);
			freerdp_image_flip(((NSC_CONTEXT*) gdi->nsc_context)->BitmapData, bitmap->data, width, height, bpp);
			break;

		case RDP_CODEC_ID_REMOTEFX:
			gdi = context->gdi;
			rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
			msg = rfx_process_message(gdi->rfx_context, data, length);
			if (!msg)
			{
				fprintf(stderr, "gdi_Bitmap_Decompress: rfx Decompression Failed\n");
			}
			else
			{
				for (yindex = 0; yindex < height; yindex++)
				{
					src = msg->tiles[0]->data + yindex * 64 * 4;
					dst = bitmap->data + yindex * width * 3;
					for (xindex = 0; xindex < width; xindex++)
					{
						*(dst++) = *(src++);
						*(dst++) = *(src++);
						*(dst++) = *(src++);
						src++;
					}
				}
				rfx_message_free(gdi->rfx_context, msg);
			}
			break;
		case RDP_CODEC_ID_JPEG:
#ifdef WITH_JPEG
			if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
			{
				fprintf(stderr, "gdi_Bitmap_Decompress: jpeg Decompression Failed\n");
			}
#endif
			break;
		default:
			if (compressed)
			{
				status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);

				if (!status)
				{
					fprintf(stderr, "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n");
				}
			}
			else
			{
				freerdp_image_flip(data, bitmap->data, width, height, bpp);
			}
			break;
	}

	bitmap->width = width;
	bitmap->height = height;
	bitmap->compressed = FALSE;
	bitmap->length = size;
	bitmap->bpp = bpp;
}
Esempio n. 17
0
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
		BYTE* data, int width, int height, int bpp, int length,
		BOOL compressed, int codec_id)
{
	UINT16 size;
	BYTE* src;
	BYTE* dst;
	int yindex;
	int xindex;
	BOOL status;
	RFX_MESSAGE* msg;
	xfContext* xfc = (xfContext*) context;

	size = width * height * ((bpp + 7) / 8);

	if (!bitmap->data)
		bitmap->data = (BYTE*) _aligned_malloc(size, 16);
	else
		bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16);

	switch (codec_id)
	{
		case RDP_CODEC_ID_NSCODEC:
			DEBUG_WARN( "xf_Bitmap_Decompress: nsc not done\n");
			break;

		case RDP_CODEC_ID_REMOTEFX:
			rfx_context_set_pixel_format(xfc->rfx, RDP_PIXEL_FORMAT_B8G8R8A8);
			msg = rfx_process_message(xfc->rfx, data, length);

			if (!msg)
			{
				DEBUG_WARN( "xf_Bitmap_Decompress: rfx Decompression Failed\n");
			}
			else
			{
				for (yindex = 0; yindex < height; yindex++)
				{
					src = msg->tiles[0]->data + yindex * 64 * 4;
					dst = bitmap->data + yindex * width * 3;
					for (xindex = 0; xindex < width; xindex++)
					{
						*(dst++) = *(src++);
						*(dst++) = *(src++);
						*(dst++) = *(src++);
						src++;
					}
				}
				rfx_message_free(xfc->rfx, msg);
			}
			break;

		case RDP_CODEC_ID_JPEG:
			if (!jpeg_decompress(data, bitmap->data, width, height, length, bpp))
			{
				DEBUG_WARN( "xf_Bitmap_Decompress: jpeg Decompression Failed\n");
			}
			break;

		default:
			if (compressed)
			{
				status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);

				if (!status)
				{
					DEBUG_WARN( "xf_Bitmap_Decompress: Bitmap Decompression Failed\n");
				}
			}
			else
			{
				freerdp_image_flip(data, bitmap->data, width, height, bpp);
			}
			break;
	}

	bitmap->compressed = FALSE;
	bitmap->length = size;
	bitmap->bpp = bpp;
}
Esempio n. 18
0
void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
{
	int i, j;
	int tx, ty;
	char* tile_bitmap;
	RFX_MESSAGE* message;
	wfInfo* wfi = ((wfContext*) context)->wfi;

	RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfi->rfx_context;
	NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfi->nsc_context;

	tile_bitmap = (char*) xzalloc(32);

	if (surface_bits_command->codecID == CODEC_ID_REMOTEFX)
	{
		RECTANGLE_16 dest_rect;

		dest_rect.left = surface_bits_command->destLeft;
		dest_rect.top = surface_bits_command->destTop;
		dest_rect.right = surface_bits_command->destRight;
		dest_rect.bottom = surface_bits_command->destBottom;

		message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength, &dest_rect);

		/* blit each tile */
		for (i = 0; i < message->num_tiles; i++)
		{
			tx = message->tiles[i]->x + surface_bits_command->destLeft;
			ty = message->tiles[i]->y + surface_bits_command->destTop;

			freerdp_image_convert(message->tiles[i]->data, wfi->tile->pdata, 64, 64, 32, 32, wfi->clrconv);

			for (j = 0; j < message->num_rects; j++)
			{
				wf_set_clip_rgn(wfi,
					surface_bits_command->destLeft + message->rects[j].x,
					surface_bits_command->destTop + message->rects[j].y,
					message->rects[j].width, message->rects[j].height);

				BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, SRCCOPY);
			}
		}

		wf_set_null_clip_rgn(wfi);

		/* invalidate regions */
		for (i = 0; i < message->num_rects; i++)
		{
			tx = surface_bits_command->destLeft + message->rects[i].x;
			ty = surface_bits_command->destTop + message->rects[i].y;
			wf_invalidate_region(wfi, tx, ty, message->rects[i].width, message->rects[i].height);
		}

		rfx_message_free(rfx_context, message);
	}
	else if (surface_bits_command->codecID == 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);
		wfi->image->_bitmap.width = surface_bits_command->width;
		wfi->image->_bitmap.height = surface_bits_command->height;
		wfi->image->_bitmap.bpp = surface_bits_command->bpp;
		wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data, wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4);
		freerdp_image_flip(nsc_context->bmpdata, wfi->image->_bitmap.data, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32);
		BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, GDI_SRCCOPY);
	} 
	else if (surface_bits_command->codecID == CODEC_ID_NONE)
	{
		wfi->image->_bitmap.width = surface_bits_command->width;
		wfi->image->_bitmap.height = surface_bits_command->height;
		wfi->image->_bitmap.bpp = surface_bits_command->bpp;

		wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data,
				wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4);

		if ((surface_bits_command->bpp != 32) || (wfi->clrconv->alpha == true))
		{
			uint8* temp_image;

			freerdp_image_convert(surface_bits_command->bitmapData, wfi->image->_bitmap.data,
				wfi->image->_bitmap.width, wfi->image->_bitmap.height,
				wfi->image->_bitmap.bpp, 32, wfi->clrconv);

			surface_bits_command->bpp = 32;
			surface_bits_command->bitmapData = wfi->image->_bitmap.data;

			temp_image = (uint8*) xmalloc(wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4);
			freerdp_image_flip(wfi->image->_bitmap.data, temp_image, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32);
			xfree(wfi->image->_bitmap.data);
			wfi->image->_bitmap.data = temp_image;
		}
		else
		{
			freerdp_image_flip(surface_bits_command->bitmapData, wfi->image->_bitmap.data,
					wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32);
		}

		BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
				surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, SRCCOPY);
	}
	else
	{
		printf("Unsupported codecID %d\n", surface_bits_command->codecID);
	}

	if (tile_bitmap != NULL)
		xfree(tile_bitmap);
}
Esempio n. 19
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
	int j;
	UINT16 i;
	RFX_RECT* rect;
	RFX_TILE* tile;
	int nXDst, nYDst;
	int nWidth, nHeight;
	int nbUpdateRects;
	RFX_MESSAGE* message;
	xfGfxSurface* surface;
	REGION16 updateRegion;
	RECTANGLE_16 updateRect;
	RECTANGLE_16* updateRects;
	REGION16 clippingRects;
	RECTANGLE_16 clippingRect;

	surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);

	if (!surface)
		return ERROR_INTERNAL_ERROR;

	if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_REMOTEFX,
									   surface->width, surface->height))
		return ERROR_INTERNAL_ERROR;

	if (!(message = rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length)))
	{
		WLog_ERR(TAG, "Failed to process RemoteFX message");
		return ERROR_INTERNAL_ERROR;
	}

	region16_init(&clippingRects);

	for (i = 0; i < message->numRects; i++)
	{
		rect = &(message->rects[i]);

		clippingRect.left = cmd->left + rect->x;
		clippingRect.top = cmd->top + rect->y;
		clippingRect.right = clippingRect.left + rect->width;
		clippingRect.bottom = clippingRect.top + rect->height;

		region16_union_rect(&clippingRects, &clippingRects, &clippingRect);
	}

	for (i = 0; i < message->numTiles; i++)
	{
		tile = message->tiles[i];

		updateRect.left = cmd->left + tile->x;
		updateRect.top = cmd->top + tile->y;
		updateRect.right = updateRect.left + 64;
		updateRect.bottom = updateRect.top + 64;

		region16_init(&updateRegion);
		region16_intersect_rect(&updateRegion, &clippingRects, &updateRect);
		updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects);

		for (j = 0; j < nbUpdateRects; j++)
		{
			nXDst = updateRects[j].left;
			nYDst = updateRects[j].top;
			nWidth = updateRects[j].right - updateRects[j].left;
			nHeight = updateRects[j].bottom - updateRects[j].top;

			freerdp_image_copy(surface->data, surface->format, surface->scanline,
					nXDst, nYDst, nWidth, nHeight,
					tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL);

			region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]);
		}

		region16_uninit(&updateRegion);
	}

	rfx_message_free(surface->codecs->rfx, message);

	region16_uninit(&clippingRects);

	if (!xfc->inGfxFrame)
		xf_UpdateSurfaces(xfc);

	return CHANNEL_RC_OK;
}
Esempio n. 20
0
File: rfx.c Progetto: C4rt/FreeRDP
RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
		BYTE* data, int width, int height, int scanline)
{
	int i, maxNbTiles, maxTilesX, maxTilesY;
	int xIdx, yIdx, regionNbRects;
	int gridRelX, gridRelY, ax, ay, bytesPerPixel;
	RFX_TILE* tile;
	RFX_RECT* rfxRect;
	RFX_MESSAGE* message = NULL;
	PTP_WORK* workObject = NULL;
	RFX_TILE_COMPOSE_WORK_PARAM *workParam = NULL;
	BOOL success = FALSE;

	REGION16 rectsRegion, tilesRegion;
	RECTANGLE_16 currentTileRect;
	const RECTANGLE_16 *regionRect;
	const RECTANGLE_16 *extents;

	assert(data);
	assert(rects);
	assert(numRects > 0);
	assert(width > 0);
	assert(height > 0);
	assert(scanline > 0);

	if (!(message = (RFX_MESSAGE*)calloc(1, sizeof(RFX_MESSAGE))))
		return NULL;

	region16_init(&tilesRegion);
	region16_init(&rectsRegion);

	if (context->state == RFX_STATE_SEND_HEADERS)
		rfx_update_context_properties(context);

	message->frameIdx = context->frameIdx++;

	if (!context->numQuant)
	{
		if (!(context->quants = (UINT32*) malloc(sizeof(rfx_default_quantization_values))))
			goto skip_encoding_loop;

		CopyMemory(context->quants, &rfx_default_quantization_values, sizeof(rfx_default_quantization_values));
		context->numQuant = 1;
		context->quantIdxY = 0;
		context->quantIdxCb = 0;
		context->quantIdxCr = 0;
	}

	message->numQuant = context->numQuant;
	message->quantVals = context->quants;

	bytesPerPixel = (context->bits_per_pixel / 8);

	if (!computeRegion(rects, numRects, &rectsRegion, width, height))
		goto skip_encoding_loop;

	extents = region16_extents(&rectsRegion);
	assert(extents->right - extents->left > 0);
	assert(extents->bottom - extents->top > 0);

	maxTilesX = 1 + TILE_NO(extents->right - 1) - TILE_NO(extents->left);
	maxTilesY = 1 + TILE_NO(extents->bottom - 1) - TILE_NO(extents->top);
	maxNbTiles = maxTilesX * maxTilesY;

	if (!(message->tiles = calloc(maxNbTiles, sizeof(RFX_TILE*))))
		goto skip_encoding_loop;

	if (!setupWorkers(context, maxNbTiles))
		goto skip_encoding_loop;

	if (context->priv->UseThreads)
	{
		workObject = context->priv->workObjects;
		workParam = context->priv->tileWorkParams;
	}

	regionRect = region16_rects(&rectsRegion, &regionNbRects);

	if (!(message->rects = calloc(regionNbRects, sizeof(RFX_RECT))))
		goto skip_encoding_loop;

	message->numRects = regionNbRects;

	for (i = 0, rfxRect = message->rects; i < regionNbRects; i++, regionRect++, rfxRect++)
	{
		int startTileX = regionRect->left / 64;
		int endTileX = (regionRect->right - 1) / 64;

		int startTileY = regionRect->top / 64;
		int endTileY = (regionRect->bottom - 1) / 64;

		rfxRect->x = regionRect->left;
		rfxRect->y = regionRect->top;
		rfxRect->width = (regionRect->right - regionRect->left);
		rfxRect->height = (regionRect->bottom - regionRect->top);


		for (yIdx = startTileY, gridRelY = startTileY * 64; yIdx <= endTileY; yIdx++, gridRelY += 64 )
		{
			int tileHeight = 64;

			if ((yIdx == endTileY) && (gridRelY + 64 > height))
				tileHeight = height - gridRelY;

			currentTileRect.top = gridRelY;
			currentTileRect.bottom = gridRelY + tileHeight;

			for (xIdx = startTileX, gridRelX = startTileX * 64; xIdx <= endTileX; xIdx++, gridRelX += 64)
			{
				int tileWidth = 64;

				if ((xIdx == endTileX) && (gridRelX + 64 > width))
					tileWidth = width - gridRelX;

				currentTileRect.left = gridRelX;
				currentTileRect.right = gridRelX + tileWidth;

				/* checks if this tile is already treated */
				if (region16_intersects_rect(&tilesRegion, &currentTileRect))
					continue;

				if (!(tile = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool)))
					goto skip_encoding_loop;

				tile->xIdx = xIdx;
				tile->yIdx = yIdx;
				tile->x = gridRelX;
				tile->y = gridRelY;
				tile->scanline = scanline;
				tile->width = tileWidth;
				tile->height = tileHeight;

				ax = gridRelX;
				ay = gridRelY;

				if (tile->data && tile->allocated)
				{
					free(tile->data);
					tile->allocated = FALSE;
				}
				tile->data = &data[(ay * scanline) + (ax * bytesPerPixel)];

				tile->quantIdxY = context->quantIdxY;
				tile->quantIdxCb = context->quantIdxCb;
				tile->quantIdxCr = context->quantIdxCr;

				tile->YLen = tile->CbLen = tile->CrLen = 0;

				if (!(tile->YCbCrData = (BYTE *)BufferPool_Take(context->priv->BufferPool, -1)))
					goto skip_encoding_loop;

				tile->YData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 0) + 16]);
				tile->CbData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 1) + 16]);
				tile->CrData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 2) + 16]);

				message->tiles[message->numTiles] = tile;
				message->numTiles++;

				if (context->priv->UseThreads)
				{
					workParam->context = context;
					workParam->tile = tile;

					if (!(*workObject = CreateThreadpoolWork(
							(PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback,
							(void*) workParam,
							&context->priv->ThreadPoolEnv)))
					{
						goto skip_encoding_loop;
					}

					SubmitThreadpoolWork(*workObject);

					workObject++;
					workParam++;
				}
				else
				{
					rfx_encode_rgb(context, tile);
				}

				if (!region16_union_rect(&tilesRegion, &tilesRegion, &currentTileRect))
					goto skip_encoding_loop;
			} /* xIdx */
		}  /* yIdx */
	}  /* rects */

	success = TRUE;

skip_encoding_loop:

	if (success && message->numTiles != maxNbTiles)
	{
		void* pmem = realloc((void*) message->tiles, sizeof(RFX_TILE*) * message->numTiles);

		if (pmem)
			message->tiles = (RFX_TILE**) pmem;
		else
			success = FALSE;
	}

	/* when using threads ensure all computations are done */
	message->tilesDataSize = 0;
	workObject = context->priv->workObjects;

	for (i = 0; i < message->numTiles; i++)
	{
		tile = message->tiles[i];
		if (context->priv->UseThreads)
		{
			if (*workObject)
			{
				WaitForThreadpoolWorkCallbacks(*workObject, FALSE);
				CloseThreadpoolWork(*workObject);
			}
			workObject++;
		}

		message->tilesDataSize += rfx_tile_length(tile);
	}

	region16_uninit(&tilesRegion);
	region16_uninit(&rectsRegion);

	if (success)
		return message;

	WLog_ERR(TAG, "%s: failed", __FUNCTION__);

	message->freeRects = TRUE;
	rfx_message_free(context, message);
	return NULL;
}
Esempio n. 21
0
int freerds_send_surface_bits(rdsConnection* connection, int bpp, RDS_MSG_PAINT_RECT* msg)
{
    int i;
    BOOL first;
    BOOL last;
    int nXSrc;
    int nYSrc;
    int nWidth;
    int nHeight;
    wStream* s;
    int nSrcStep;
    BYTE* pSrcData;
    int numMessages;
    UINT32 frameId = 0;
    rdpUpdate* update;
    rdpContext* context;
    rdpSettings* settings;
    rdsEncoder* encoder;
    SURFACE_BITS_COMMAND cmd;

    WLog_VRB(TAG, "%s", __FUNCTION__);

    nXSrc = msg->nLeftRect;
    nYSrc = msg->nTopRect;
    nWidth = msg->nWidth;
    nHeight = msg->nHeight;

    context = (rdpContext*) connection;
    update = context->update;

    settings = connection->settings;
    encoder = connection->encoder;

    pSrcData = msg->framebuffer->fbSharedMemory;
    nSrcStep = msg->framebuffer->fbScanline;

    if (encoder->frameAck)
        frameId = (UINT32) freerds_encoder_create_frame_id(encoder);

    if (settings->RemoteFxCodec)
    {
        RFX_RECT rect;
        RFX_MESSAGE* messages;

        freerds_encoder_prepare(encoder, FREERDP_CODEC_REMOTEFX);

        s = encoder->bs;

        rect.x = nXSrc;
        rect.y = nYSrc;
        rect.width = nWidth;
        rect.height = nHeight;

        messages = rfx_encode_messages(encoder->rfx, &rect, 1, pSrcData,
                                       msg->framebuffer->fbWidth, msg->framebuffer->fbHeight,
                                       nSrcStep, &numMessages, settings->MultifragMaxRequestSize);

        cmd.codecID = settings->RemoteFxCodecId;

        cmd.destLeft = 0;
        cmd.destTop = 0;
        cmd.destRight = msg->framebuffer->fbWidth;
        cmd.destBottom = msg->framebuffer->fbHeight;

        cmd.bpp = 32;
        cmd.width = msg->framebuffer->fbWidth;
        cmd.height = msg->framebuffer->fbHeight;

        for (i = 0; i < numMessages; i++)
        {
            Stream_SetPosition(s, 0);
            rfx_write_message(encoder->rfx, s, &messages[i]);
            rfx_message_free(encoder->rfx, &messages[i]);

            cmd.bitmapDataLength = Stream_GetPosition(s);
            cmd.bitmapData = Stream_Buffer(s);

            first = (i == 0) ? TRUE : FALSE;
            last = ((i + 1) == numMessages) ? TRUE : FALSE;

            if (!encoder->frameAck)
                IFCALL(update->SurfaceBits, update->context, &cmd);
            else
                IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId);
        }

        free(messages);
    }
    else if (settings->NSCodec)
    {
        freerds_encoder_prepare(encoder, FREERDP_CODEC_NSCODEC);

        s = encoder->bs;
        Stream_SetPosition(s, 0);

        pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];

        nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep);

        cmd.bpp = 32;
        cmd.codecID = settings->NSCodecId;
        cmd.destLeft = nXSrc;
        cmd.destTop = nYSrc;
        cmd.destRight = cmd.destLeft + nWidth;
        cmd.destBottom = cmd.destTop + nHeight;
        cmd.width = nWidth;
        cmd.height = nHeight;

        cmd.bitmapDataLength = Stream_GetPosition(s);
        cmd.bitmapData = Stream_Buffer(s);

        first = TRUE;
        last = TRUE;

        if (!encoder->frameAck)
            IFCALL(update->SurfaceBits, update->context, &cmd);
        else
            IFCALL(update->SurfaceFrameBits, update->context, &cmd, first, last, frameId);
    }

    return 1;
}
Esempio n. 22
0
File: rfx.c Progetto: C4rt/FreeRDP
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length)
{
	int pos;
	UINT32 blockLen;
	UINT32 blockType;
	RFX_MESSAGE* message = NULL;
	wStream* s = NULL;
	BOOL ok = TRUE;
	UINT16 expectedDataBlockType = WBT_FRAME_BEGIN;

	if (!context || !data || !length)
		goto fail;

	if (!(s = Stream_New(data, length)))
		goto fail;

	if (!(message = (RFX_MESSAGE*) calloc(1, sizeof(RFX_MESSAGE))))
		goto fail;

	message->freeRects = TRUE;

	while (ok && Stream_GetRemainingLength(s) > 6)
	{
		/* RFX_BLOCKT */
		Stream_Read_UINT16(s, blockType); /* blockType (2 bytes) */
		Stream_Read_UINT32(s, blockLen); /* blockLen (4 bytes) */

		WLog_Print(context->priv->log, WLOG_DEBUG, "blockType 0x%X blockLen %d", blockType, blockLen);

		if (blockLen == 0)
		{
			WLog_ERR(TAG, "zero blockLen");
			goto fail;
		}

		if (Stream_GetRemainingLength(s) < blockLen - 6)
		{
			WLog_ERR(TAG, "%s: packet too small for blocklen=%d", __FUNCTION__, blockLen);
			goto fail;
		}

		pos = Stream_GetPosition(s) - 6 + blockLen;

		if (blockType > WBT_CONTEXT && context->decodedHeaderBlocks != _RFX_DECODED_HEADERS)
		{
			WLog_ERR(TAG, "%s: incomplete header blocks processing", __FUNCTION__);
			goto fail;
		}

		if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION)
		{
			/* RFX_CODEC_CHANNELT */
			UINT8 codecId;
			UINT8 channelId;

			if (Stream_GetRemainingLength(s) < 2)
				goto fail;

			Stream_Read_UINT8(s, codecId); /* codecId (1 byte) must be set to 0x01 */
			Stream_Read_UINT8(s, channelId); /* channelId (1 byte) 0xFF or 0x00, see below */

			if (codecId != 0x01)
			{
				WLog_ERR(TAG, "%s: invalid codecId 0x%02X", __FUNCTION__, codecId);
				goto fail;
			}

			if (blockType == WBT_CONTEXT)
			{
				/* If the blockType is set to WBT_CONTEXT, then channelId MUST be set to 0xFF.*/
				if (channelId != 0xFF)
				{
					WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType 0x%04X", __FUNCTION__, channelId, blockType);
					goto fail;
				}
			}
			else
			{
				/* For all other values of blockType, channelId MUST be set to 0x00. */
				if (channelId != 0x00)
				{
					WLog_ERR(TAG, "%s: invalid channelId 0x%02X for blockType WBT_CONTEXT", __FUNCTION__, channelId);
					goto fail;
				}
			}
		}


		switch (blockType)
		{
			/* Header messages:
			 * The stream MUST start with the header messages and any of these headers can appear
			 * in the stream at a later stage. The header messages can be repeated.
			 */

			case WBT_SYNC:
				ok = rfx_process_message_sync(context, s);
				break;

			case WBT_CONTEXT:
				ok = rfx_process_message_context(context, s);
				break;

			case WBT_CODEC_VERSIONS:
				ok = rfx_process_message_codec_versions(context, s);
				break;

			case WBT_CHANNELS:
				ok = rfx_process_message_channels(context, s);
				break;

			/* Data messages:
			 * The data associated with each encoded frame or image is always bracketed by the
			 * TS_RFX_FRAME_BEGIN (section 2.2.2.3.1) and TS_RFX_FRAME_END (section 2.2.2.3.2) messages.
			 * There MUST only be one TS_RFX_REGION (section 2.2.2.3.3) message per frame and one TS_RFX_TILESET
			 * (section 2.2.2.3.4) message per TS_RFX_REGION.
			 */

			case WBT_FRAME_BEGIN:
				ok = rfx_process_message_frame_begin(context, message, s, &expectedDataBlockType);
				break;

			case WBT_REGION:
				ok = rfx_process_message_region(context, message, s, &expectedDataBlockType);
				break;

			case WBT_EXTENSION:
				ok = rfx_process_message_tileset(context, message, s, &expectedDataBlockType);
				break;

			case WBT_FRAME_END:
				ok = rfx_process_message_frame_end(context, message, s, &expectedDataBlockType);
				break;

			default:
				WLog_ERR(TAG, "%s: unknown blockType 0x%X", __FUNCTION__, blockType);
				goto fail;
		}

		Stream_SetPosition(s, pos);
	}

	if (ok)
	{
		Stream_Free(s, FALSE);
		return message;
	}

fail:
	Stream_Free(s, FALSE);
	rfx_message_free(context, message);

	return NULL;
}
Esempio n. 23
0
File: gdi.c Progetto: AMV007/FreeRDP
static void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
{
	int i, j;
	int tx, ty;
	BYTE* pSrcData;
	BYTE* pDstData;
	RFX_MESSAGE* message;
	rdpGdi* gdi = context->gdi;

	DEBUG_GDI("destLeft %d destTop %d destRight %d destBottom %d "
		"bpp %d codecID %d width %d height %d length %d",
		cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom,
		cmd->bpp, cmd->codecID, cmd->width, cmd->height, cmd->bitmapDataLength);

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

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

		/* blit each tile */
		for (i = 0; i < message->numTiles; i++)
		{
			tx = message->tiles[i]->x + cmd->destLeft;
			ty = message->tiles[i]->y + cmd->destTop;

			pSrcData = message->tiles[i]->data;
			pDstData = gdi->tile->bitmap->data;

			if (!gdi->invert && (gdi->dstBpp == 32))
			{
				gdi->tile->bitmap->data = pSrcData;
			}
			else
			{
				freerdp_image_copy(pDstData, gdi->format, -1, 0, 0,
						64, 64, pSrcData, PIXEL_FORMAT_XRGB32, -1, 0, 0, gdi->palette);
			}

			for (j = 0; j < message->numRects; j++)
			{
				gdi_SetClipRgn(gdi->primary->hdc,
					cmd->destLeft + message->rects[j].x,
					cmd->destTop + message->rects[j].y,
					message->rects[j].width, message->rects[j].height);

				gdi_BitBlt(gdi->primary->hdc, tx, ty, 64, 64, gdi->tile->hdc, 0, 0, GDI_SRCCOPY);
			}

			gdi->tile->bitmap->data = pDstData;
		}

		gdi_SetNullClipRgn(gdi->primary->hdc);
		rfx_message_free(gdi->codecs->rfx, message);
	}
	else if (cmd->codecID == RDP_CODEC_ID_NSCODEC)
	{
		freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_NSCODEC);

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

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

			if (!gdi->bitmap_buffer)
				return;
		}

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

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

		gdi->image->bitmap->width = cmd->width;
		gdi->image->bitmap->height = cmd->height;
		gdi->image->bitmap->bitsPerPixel = cmd->bpp;
		gdi->image->bitmap->bytesPerPixel = cmd->bpp / 8;
		gdi->image->bitmap->data = gdi->bitmap_buffer;

		gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
	} 
	else if (cmd->codecID == RDP_CODEC_ID_NONE)
	{
		if (gdi->bitmap_size < (cmd->width * cmd->height * 4))
		{
			gdi->bitmap_size = cmd->width * cmd->height * 4;
			gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16);

			if (!gdi->bitmap_buffer)
				return;
		}

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

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

		gdi->image->bitmap->width = cmd->width;
		gdi->image->bitmap->height = cmd->height;
		gdi->image->bitmap->bitsPerPixel = cmd->bpp;
		gdi->image->bitmap->bytesPerPixel = cmd->bpp / 8;
		gdi->image->bitmap->data = gdi->bitmap_buffer;

		gdi_BitBlt(gdi->primary->hdc, cmd->destLeft, cmd->destTop, cmd->width, cmd->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
	}
	else
	{
		WLog_ERR(TAG, "Unsupported codecID %d", cmd->codecID);
	}
}
Esempio n. 24
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);
	}
}