Exemplo n.º 1
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT xf_CreateSurface(RdpgfxClientContext* context,
                             const RDPGFX_CREATE_SURFACE_PDU* createSurface)
{
	size_t size;
	xfGfxSurface* surface;
	rdpGdi* gdi = (rdpGdi*)context->custom;
	xfContext* xfc = (xfContext*) gdi->context;
	surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface));

	if (!surface)
		return CHANNEL_RC_NO_MEMORY;

	surface->gdi.codecs = codecs_new(gdi->context);

	if (!surface->gdi.codecs)
	{
		free(surface);
		return CHANNEL_RC_NO_MEMORY;
	}

	if (!freerdp_client_codecs_prepare(surface->gdi.codecs, FREERDP_CODEC_ALL,
	                                   createSurface->width, createSurface->height))
	{
		free(surface);
		return ERROR_INTERNAL_ERROR;
	}

	surface->gdi.surfaceId = createSurface->surfaceId;
	surface->gdi.width = (UINT32) createSurface->width;
	surface->gdi.height = (UINT32) createSurface->height;

	switch (createSurface->pixelFormat)
	{
		case GFX_PIXEL_FORMAT_ARGB_8888:
			surface->gdi.format = PIXEL_FORMAT_BGRA32;
			break;

		case GFX_PIXEL_FORMAT_XRGB_8888:
			surface->gdi.format = PIXEL_FORMAT_BGRX32;
			break;

		default:
			free(surface);
			return ERROR_INTERNAL_ERROR;
	}

	surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel(
	                            surface->gdi.format);
	surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad);
	size = surface->gdi.scanline * surface->gdi.height;
	surface->gdi.data = (BYTE*) _aligned_malloc(size, 16);

	if (!surface->gdi.data)
	{
		free(surface);
		return CHANNEL_RC_NO_MEMORY;
	}

	ZeroMemory(surface->gdi.data, size);

	if (gdi->dstFormat == surface->gdi.format)
	{
		surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
		                              (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height,
		                              xfc->scanline_pad, surface->gdi.scanline);
	}
	else
	{
		UINT32 width = surface->gdi.width;
		UINT32 bytes = GetBytesPerPixel(gdi->dstFormat);
		surface->stageScanline = width * bytes;
		surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad);
		size = surface->stageScanline * surface->gdi.height;
		surface->stage = (BYTE*) _aligned_malloc(size, 16);

		if (!surface->stage)
		{
			_aligned_free(surface->gdi.data);
			free(surface);
			return CHANNEL_RC_NO_MEMORY;
		}

		ZeroMemory(surface->stage, size);
		surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
		                              ZPixmap, 0, (char*) surface->stage,
		                              surface->gdi.width, surface->gdi.height,
		                              xfc->scanline_pad, surface->gdi.scanline);
	}

	surface->gdi.outputMapped = FALSE;
	region16_init(&surface->gdi.invalidRegion);
	context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface);
	return CHANNEL_RC_OK;
}
Exemplo n.º 2
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT xf_CreateSurface(RdpgfxClientContext* context,
                             const RDPGFX_CREATE_SURFACE_PDU* createSurface)
{
	UINT ret = CHANNEL_RC_NO_MEMORY;
	size_t size;
	xfGfxSurface* surface;
	rdpGdi* gdi = (rdpGdi*)context->custom;
	xfContext* xfc = (xfContext*) gdi->context;
	surface = (xfGfxSurface*) calloc(1, sizeof(xfGfxSurface));

	if (!surface)
		return CHANNEL_RC_NO_MEMORY;

	surface->gdi.codecs = gdi->context->codecs;

	if (!surface->gdi.codecs)
	{
		WLog_ERR(TAG, "%s: global GDI codecs aren't set", __FUNCTION__);
		goto out_free;
	}

	surface->gdi.surfaceId = createSurface->surfaceId;
	surface->gdi.width = (UINT32) createSurface->width;
	surface->gdi.height = (UINT32) createSurface->height;

	switch (createSurface->pixelFormat)
	{
		case GFX_PIXEL_FORMAT_ARGB_8888:
			surface->gdi.format = PIXEL_FORMAT_BGRA32;
			break;

		case GFX_PIXEL_FORMAT_XRGB_8888:
			surface->gdi.format = PIXEL_FORMAT_BGRX32;
			break;

		default:
			WLog_ERR(TAG, "%s: unknown pixelFormat 0x%"PRIx32"", __FUNCTION__, createSurface->pixelFormat);
			ret = ERROR_INTERNAL_ERROR;
			goto out_free;
	}

	surface->gdi.scanline = surface->gdi.width * GetBytesPerPixel(surface->gdi.format);
	surface->gdi.scanline = x11_pad_scanline(surface->gdi.scanline, xfc->scanline_pad);
	size = surface->gdi.scanline * surface->gdi.height;
	surface->gdi.data = (BYTE*)_aligned_malloc(size, 16);

	if (!surface->gdi.data)
	{
		WLog_ERR(TAG, "%s: unable to allocate GDI data", __FUNCTION__);
		goto out_free;
	}

	ZeroMemory(surface->gdi.data, size);

	if (AreColorFormatsEqualNoAlpha(gdi->dstFormat, surface->gdi.format))
	{
		surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
		                              (char*) surface->gdi.data, surface->gdi.width, surface->gdi.height,
		                              xfc->scanline_pad, surface->gdi.scanline);
	}
	else
	{
		UINT32 width = surface->gdi.width;
		UINT32 bytes = GetBytesPerPixel(gdi->dstFormat);
		surface->stageScanline = width * bytes;
		surface->stageScanline = x11_pad_scanline(surface->stageScanline, xfc->scanline_pad);
		size = surface->stageScanline * surface->gdi.height;
		surface->stage = (BYTE*) _aligned_malloc(size, 16);

		if (!surface->stage)
		{
			WLog_ERR(TAG, "%s: unable to allocate stage buffer", __FUNCTION__);
			goto out_free_gdidata;
		}

		ZeroMemory(surface->stage, size);
		surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
		                              ZPixmap, 0, (char*) surface->stage,
		                              surface->gdi.width, surface->gdi.height,
		                              xfc->scanline_pad, surface->stageScanline);
	}

	if (!surface->image)
	{
		WLog_ERR(TAG, "%s: an error occurred when creating the XImage", __FUNCTION__);
		goto error_surface_image;
	}

	surface->image->byte_order = LSBFirst;
	surface->image->bitmap_bit_order = LSBFirst;
	surface->gdi.outputMapped = FALSE;
	region16_init(&surface->gdi.invalidRegion);

	if (context->SetSurfaceData(context, surface->gdi.surfaceId, (void*) surface) != CHANNEL_RC_OK)
	{
		WLog_ERR(TAG, "%s: an error occurred during SetSurfaceData", __FUNCTION__);
		goto error_set_surface_data;
	}

	return CHANNEL_RC_OK;
error_set_surface_data:
	surface->image->data = NULL;
	XDestroyImage(surface->image);
error_surface_image:
	_aligned_free(surface->stage);
out_free_gdidata:
	_aligned_free(surface->gdi.data);
out_free:
	free(surface);
	return ret;
}