Beispiel #1
0
void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap,
		BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codecId)
{
	int status;
	UINT16 size;
	BYTE* pSrcData;
	BYTE* pDstData;
	UINT32 SrcSize;
	UINT32 SrcFormat;
	UINT32 bytesPerPixel;

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

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

	pSrcData = data;
	SrcSize = (UINT32) length;
	pDstData = bitmap->data;

	if (compressed)
	{
		if (bpp < 32)
		{
			if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED))
				return;

			status = interleaved_decompress(wfc->codecs->interleaved, pSrcData, SrcSize, bpp,
					&pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, NULL);
		}
		else
		{
			if (!freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR))
				return;

			status = planar_decompress(wfc->codecs->planar, pSrcData, SrcSize, &pDstData,
					PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height, TRUE);
		}

		if (status < 0)
		{
			WLog_ERR(TAG, "Bitmap Decompression Failed");
			return;
		}
	}
	else
	{
		SrcFormat = gdi_get_pixel_format(bpp, TRUE);

		status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0,
				width, height, pSrcData, SrcFormat, width * bytesPerPixel, 0, 0, NULL);
	}

	bitmap->compressed = FALSE;
	bitmap->length = size;
	bitmap->bpp = 32;
}
Beispiel #2
0
static Pixmap xf_brush_new(xfContext* xfc, UINT32 width, UINT32 height,
                           UINT32 bpp,
                           BYTE* data)
{
	GC gc;
	Pixmap bitmap;
	BYTE* cdata;
	XImage* image;
	rdpGdi* gdi;
	UINT32 brushFormat;
	gdi = xfc->context.gdi;
	bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, xfc->depth);

	if (data)
	{
		brushFormat = gdi_get_pixel_format(bpp);
		cdata = (BYTE*) _aligned_malloc(width * height * 4, 16);
		freerdp_image_copy(cdata, gdi->dstFormat, 0, 0, 0,
		                   width, height, data, brushFormat, 0, 0, 0,
		                   &xfc->context.gdi->palette, FREERDP_FLIP_NONE);
		image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
		                     ZPixmap, 0, (char*) cdata, width, height, xfc->scanline_pad, 0);
		gc = XCreateGC(xfc->display, xfc->drawable, 0, NULL);
		XPutImage(xfc->display, bitmap, gc, image, 0, 0, 0, 0, width, height);
		XFree(image);

		if (cdata != data)
			_aligned_free(cdata);

		XFreeGC(xfc->display, gc);
	}

	return bitmap;
}
Beispiel #3
0
BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
		BYTE* data, int width, int height, int bpp, int length,
		BOOL compressed, int codecId)
{
	int status;
	UINT16 size;
	BYTE* pSrcData;
	BYTE* pDstData;
	UINT32 SrcSize;
	UINT32 SrcFormat;
	UINT32 bytesPerPixel;
	rdpGdi* gdi = context->gdi;

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

	bitmap->data = (BYTE*) _aligned_malloc(size, 16);

	pSrcData = data;
	SrcSize = (UINT32) length;
	pDstData = bitmap->data;

	if (compressed)
	{
		if (bpp < 32)
		{
			if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_INTERLEAVED))
				return FALSE;

			status = interleaved_decompress(gdi->codecs->interleaved, pSrcData, SrcSize, bpp,
					&pDstData, gdi->format, -1, 0, 0, width, height, gdi->palette);
		}
		else
		{
			if (!freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_PLANAR))
				return FALSE;

			status = planar_decompress(gdi->codecs->planar, pSrcData, SrcSize, &pDstData,
					gdi->format, -1, 0, 0, width, height, TRUE);
		}

		if (status < 0)
		{
			WLog_ERR(TAG, "Bitmap Decompression Failed");
			return FALSE;
		}
	}
	else
	{
		SrcFormat = gdi_get_pixel_format(bpp, TRUE);

		status = freerdp_image_copy(pDstData, gdi->format, -1, 0, 0,
				width, height, pSrcData, SrcFormat, -1, 0, 0, gdi->palette);
	}

	bitmap->compressed = FALSE;
	bitmap->length = size;
	bitmap->bpp = gdi->dstBpp;
	return TRUE;
}
Beispiel #4
0
Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data)
{
	GC gc;
	Pixmap bitmap;
	BYTE* cdata;
	XImage* image;
	UINT32 brushFormat;

	bitmap = XCreatePixmap(xfc->display, xfc->drawable, width, height, xfc->depth);

	if (data)
	{
		brushFormat = gdi_get_pixel_format(bpp, FALSE);

		cdata = (BYTE*) _aligned_malloc(width * height * 4, 16);

		freerdp_image_copy(cdata, xfc->format, -1, 0, 0,
				width, height, data, brushFormat, -1, 0, 0, xfc->palette);

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

		gc = XCreateGC(xfc->display, xfc->drawable, 0, NULL);
		XPutImage(xfc->display, bitmap, gc, image, 0, 0, 0, 0, width, height);
		XFree(image);

		if (cdata != data)
			_aligned_free(cdata);

		XFreeGC(xfc->display, gc);
	}

	return bitmap;
}
Beispiel #5
0
BOOL gdi_init_ex(freerdp* instance, UINT32 format, UINT32 stride, BYTE* buffer,
                 void (*pfree)(void*))
{
	UINT32 SrcFormat = gdi_get_pixel_format(instance->settings->ColorDepth);
	rdpGdi* gdi = (rdpGdi*) calloc(1, sizeof(rdpGdi));
	rdpContext* context = instance->context;

	if (!gdi)
		goto fail;

	instance->context->gdi = gdi;
	gdi->log = WLog_Get(TAG);

	if (!gdi->log)
		goto fail;

	gdi->context = instance->context;
	gdi->width = instance->settings->DesktopWidth;
	gdi->height = instance->settings->DesktopHeight;
	gdi->dstFormat = format;
	/* default internal buffer format */
	WLog_Print(gdi->log, WLOG_INFO, "Local framebuffer format  %s",
	           GetColorFormatName(gdi->dstFormat));
	WLog_Print(gdi->log, WLOG_INFO, "Remote framebuffer format %s",
	           GetColorFormatName(SrcFormat));

	if (!(gdi->hdc = gdi_GetDC()))
		goto fail;

	gdi->hdc->format = gdi->dstFormat;

	if (!gdi_init_primary(gdi, stride, gdi->dstFormat, buffer, pfree))
		goto fail;

	if (!(context->cache = cache_new(instance->settings)))
		goto fail;

	if (!freerdp_client_codecs_prepare(context->codecs, FREERDP_CODEC_ALL,
	                                   gdi->width, gdi->height))
		goto fail;

	gdi_register_update_callbacks(instance->update);
	brush_cache_register_callbacks(instance->update);
	glyph_cache_register_callbacks(instance->update);
	bitmap_cache_register_callbacks(instance->update);
	offscreen_cache_register_callbacks(instance->update);
	palette_cache_register_callbacks(instance->update);

	if (!gdi_register_graphics(instance->context->graphics))
		goto fail;

	return TRUE;
fail:
	gdi_free(instance);
	WLog_ERR(TAG,  "failed to initialize gdi");
	return FALSE;
}
Beispiel #6
0
static HBRUSH wf_create_brush(wfContext* wfc, rdpBrush* brush, UINT32 color,
                              UINT32 bpp)
{
	UINT32 i;
	HBRUSH br;
	LOGBRUSH lbr;
	BYTE* cdata;
	BYTE ipattern[8];
	HBITMAP pattern = NULL;
	lbr.lbStyle = brush->style;

	if (lbr.lbStyle == BS_DIBPATTERN || lbr.lbStyle == BS_DIBPATTERN8X8
	    || lbr.lbStyle == BS_DIBPATTERNPT)
		lbr.lbColor = DIB_RGB_COLORS;
	else
		lbr.lbColor = color;

	if (lbr.lbStyle == BS_PATTERN || lbr.lbStyle == BS_PATTERN8X8)
	{
		if (brush->bpp > 1)
		{
			UINT32 format = gdi_get_pixel_format(bpp);
			pattern = wf_create_dib(wfc, 8, 8, format, brush->data, NULL);
			lbr.lbHatch = (ULONG_PTR) pattern;
		}
		else
		{
			for (i = 0; i != 8; i++)
				ipattern[7 - i] = brush->data[i];

			cdata = wf_glyph_convert(wfc, 8, 8, ipattern);
			pattern = CreateBitmap(8, 8, 1, 1, cdata);
			lbr.lbHatch = (ULONG_PTR) pattern;
			free(cdata);
		}
	}
	else if (lbr.lbStyle == BS_HATCHED)
	{
		lbr.lbHatch = brush->hatch;
	}
	else
	{
		lbr.lbHatch = 0;
	}

	br = CreateBrushIndirect(&lbr);
	SetBrushOrgEx(wfc->drawing->hdc, brush->x, brush->y, NULL);

	if (pattern != NULL)
		DeleteObject(pattern);

	return br;
}
Beispiel #7
0
static BOOL gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
                                  const BYTE* pSrcData, UINT32 DstWidth, UINT32 DstHeight,
                                  UINT32 bpp, UINT32 length, BOOL compressed,
                                  UINT32 codecId)
{
    UINT32 SrcSize = length;
    UINT32 SrcFormat;
    UINT32 bytesPerPixel;
    rdpGdi* gdi = context->gdi;
    bitmap->compressed = FALSE;
    bitmap->format = gdi->dstFormat;
    bitmap->length = DstWidth * DstHeight * GetBytesPerPixel(bitmap->format);
    bytesPerPixel = GetBytesPerPixel(bpp);
    bitmap->data = (BYTE*) _aligned_malloc(bitmap->length, 16);

    if (!bitmap->data)
        return FALSE;

    if (compressed)
    {
        if (bpp < 32)
        {
            if (!interleaved_decompress(context->codecs->interleaved,
                                        pSrcData, SrcSize,
                                        DstWidth, DstHeight,
                                        bpp,
                                        bitmap->data, bitmap->format,
                                        0, 0, 0, DstWidth, DstHeight,
                                        &gdi->palette))
                return FALSE;
        }
        else
        {
            if (!planar_decompress(context->codecs->planar, pSrcData, SrcSize,
                                   DstWidth, DstHeight,
                                   bitmap->data, bitmap->format, 0, 0, 0,
                                   DstWidth, DstHeight, TRUE))
                return FALSE;
        }
    }
    else
    {
        SrcFormat = gdi_get_pixel_format(bpp);

        if (!freerdp_image_copy(bitmap->data, bitmap->format, 0, 0, 0,
                                DstWidth, DstHeight, pSrcData, SrcFormat,
                                0, 0, 0, &gdi->palette, FREERDP_FLIP_VERTICAL))
            return FALSE;
    }

    return TRUE;
}
Beispiel #8
0
BOOL xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
{
	int depth;
	BYTE* data;
	Pixmap pixmap;
	XImage* image;
	UINT32 SrcFormat;
	xfContext* xfc = (xfContext*) context;

	xf_lock_x11(xfc, FALSE);

	data = bitmap->data;
	depth = (bitmap->bpp >= 24) ? 24 : bitmap->bpp;

	pixmap = XCreatePixmap(xfc->display, xfc->drawable, bitmap->width, bitmap->height, xfc->depth);

	if (bitmap->data)
	{
		XSetFunction(xfc->display, xfc->gc, GXcopy);

		if (depth != xfc->depth)
		{
			if (!(data = _aligned_malloc(bitmap->width * bitmap->height * 4, 16)))
			{
				xf_unlock_x11(xfc, FALSE);
				return FALSE;
			}

			SrcFormat = gdi_get_pixel_format(bitmap->bpp, TRUE);

			freerdp_image_copy(data, xfc->format, -1, 0, 0,
				bitmap->width, bitmap->height, bitmap->data, SrcFormat, -1, 0, 0, xfc->palette);

			_aligned_free(bitmap->data);
			bitmap->data = data;

			bitmap->bpp = (xfc->depth >= 24) ? 32 : xfc->depth;
		}

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

		XPutImage(xfc->display, pixmap, xfc->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height);

		XFree(image);
	}

	((xfBitmap*) bitmap)->pixmap = pixmap;

	xf_unlock_x11(xfc, FALSE);
	return TRUE;
}
Beispiel #9
0
static BOOL wf_decode_color(wfContext* wfc, const UINT32 srcColor,
                            COLORREF* color, UINT32* format)
{
	rdpGdi* gdi;
	rdpSettings* settings;
	UINT32 SrcFormat, DstFormat;

	if (!wfc)
		return FALSE;

	gdi = wfc->context.gdi;
	settings = wfc->context.settings;

	if (!gdi || !settings)
		return FALSE;

	SrcFormat = gdi_get_pixel_format(gdi->context->settings->ColorDepth,
	                                 FALSE);

	if (format)
		*format = SrcFormat;

	switch (GetBitsPerPixel(gdi->dstFormat))
	{
		case 32:
			DstFormat = PIXEL_FORMAT_ABGR32;
			break;

		case 24:
			DstFormat = PIXEL_FORMAT_BGR24;
			break;

		case 16:
			DstFormat = PIXEL_FORMAT_RGB16;
			break;

		default:
			return FALSE;
	}

	*color = ConvertColor(srcColor, SrcFormat,
	                      DstFormat, &gdi->palette);
	return TRUE;
}
Beispiel #10
0
BOOL xf_decode_color(rdpGdi* gdi, const UINT32 srcColor,
                     UINT32* color, UINT32* format)
{
	xfContext* xfc;
	UINT32 DstFormat;
	UINT32 SrcFormat;

	if (!gdi || !gdi->context || !gdi->context->settings)
		return FALSE;

	xfc = (xfContext*)gdi->context;
	SrcFormat = gdi_get_pixel_format(gdi->context->settings->ColorDepth);

	if (format)
		*format = SrcFormat;

	DstFormat = xf_get_local_color_format(xfc, FALSE);
	*color = ConvertColor(srcColor, SrcFormat,
	                      DstFormat, &gdi->palette);
	return TRUE;
}
Beispiel #11
0
static void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
	BYTE* data;
	rdpBrush* brush;
	UINT32 foreColor;
	UINT32 backColor;
	gdiBitmap* bitmap;
	GDI_COLOR originalColor;
	HGDI_BRUSH originalBrush;
	rdpGdi* gdi = context->gdi;

	brush = &mem3blt->brush;
	bitmap = (gdiBitmap*) mem3blt->bitmap;

	foreColor = freerdp_convert_gdi_order_color(mem3blt->foreColor, gdi->srcBpp, gdi->format, gdi->palette);
	backColor = freerdp_convert_gdi_order_color(mem3blt->backColor, gdi->srcBpp, gdi->format, gdi->palette);

	originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor);

	if (brush->style == GDI_BS_SOLID)
	{
		originalBrush = gdi->drawing->hdc->brush;
		gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor);

		gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
				mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
				mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop));

		gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
		gdi->drawing->hdc->brush = originalBrush;
	}
	else if (brush->style == GDI_BS_PATTERN)
	{
		HGDI_BITMAP hBmp;
		UINT32 brushFormat;

		if (brush->bpp > 1)
		{
			brushFormat = gdi_get_pixel_format(brush->bpp, FALSE);

			data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);

			freerdp_image_copy(data, gdi->format, -1, 0, 0,
					8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette);
		}
		else
		{
			data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);

			freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8,
					brush->data, backColor, foreColor, gdi->palette);
		}

		hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);

		originalBrush = gdi->drawing->hdc->brush;
		gdi->drawing->hdc->brush = gdi_CreatePatternBrush(hBmp);

		gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
				mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
				mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop));

		gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
		gdi->drawing->hdc->brush = originalBrush;
	}
	else
	{
		WLog_ERR(TAG,  "Mem3Blt unimplemented brush style:%d", brush->style);
	}

	gdi_SetTextColor(gdi->drawing->hdc, originalColor);
}
Beispiel #12
0
void xf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
	int status;
	int nXDst;
	int nYDst;
	int nXSrc;
	int nYSrc;
	int nWidth;
	int nHeight;
	UINT32 index;
	XImage* image;
	BYTE* pSrcData;
	BYTE* pDstData;
	UINT32 SrcSize;
	BOOL compressed;
	UINT32 SrcFormat;
	UINT32 bitsPerPixel;
	UINT32 bytesPerPixel;
	BITMAP_DATA* bitmap;
	rdpCodecs* codecs = context->codecs;
	xfContext* xfc = (xfContext*) context;

	for (index = 0; index < bitmapUpdate->number; index++)
	{
		bitmap = &(bitmapUpdate->rectangles[index]);

		nXSrc = 0;
		nYSrc = 0;

		nXDst = bitmap->destLeft;
		nYDst = bitmap->destTop;

		nWidth = bitmap->width;
		nHeight = bitmap->height;

		pSrcData = bitmap->bitmapDataStream;
		SrcSize = bitmap->bitmapLength;

		compressed = bitmap->compressed;
		bitsPerPixel = bitmap->bitsPerPixel;
		bytesPerPixel = (bitsPerPixel + 7) / 8;

		SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);

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

			if (!xfc->bitmap_buffer)
				return;
		}

		if (compressed)
		{
			pDstData = xfc->bitmap_buffer;

			if (bitsPerPixel < 32)
			{
				freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);

				status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
						&pDstData, xfc->format, -1, 0, 0, nWidth, nHeight, xfc->palette);
			}
			else
			{
				freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);

				status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
						xfc->format, -1, 0, 0, nWidth, nHeight, TRUE);
			}

			if (status < 0)
			{
				WLog_ERR(TAG, "bitmap decompression failure");
				return;
			}

			pSrcData = xfc->bitmap_buffer;
		}
		else
		{
			pDstData = xfc->bitmap_buffer;

			status = freerdp_image_copy(pDstData, xfc->format, -1, 0, 0,
						nWidth, nHeight, pSrcData, SrcFormat, -1, 0, 0, xfc->palette);

			pSrcData = xfc->bitmap_buffer;
		}

		xf_lock_x11(xfc, FALSE);

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

		image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
				(char*) pSrcData, nWidth, nHeight, xfc->scanline_pad, 0);

		nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */
		nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */

		XPutImage(xfc->display, xfc->primary, xfc->gc,
				image, 0, 0, nXDst, nYDst, nWidth, nHeight);

		XFree(image);

		gdi_InvalidateRegion(xfc->hdc, nXDst, nYDst, nWidth, nHeight);

		xf_unlock_x11(xfc, FALSE);
	}
}
Beispiel #13
0
static void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
	int status;
	int nXDst;
	int nYDst;
	int nXSrc;
	int nYSrc;
	int nWidth;
	int nHeight;
	int nSrcStep;
	int nDstStep;
	UINT32 index;
	BYTE* pSrcData;
	BYTE* pDstData;
	UINT32 SrcSize;
	BOOL compressed;
	UINT32 SrcFormat;
	UINT32 bitsPerPixel;
	BITMAP_DATA* bitmap;
	rdpGdi* gdi = context->gdi;
	rdpCodecs* codecs = context->codecs;

	for (index = 0; index < bitmapUpdate->number; index++)
	{
		bitmap = &(bitmapUpdate->rectangles[index]);

		nXSrc = 0;
		nYSrc = 0;

		nXDst = bitmap->destLeft;
		nYDst = bitmap->destTop;

		nWidth = bitmap->width;
		nHeight = bitmap->height;

		pSrcData = bitmap->bitmapDataStream;
		SrcSize = bitmap->bitmapLength;

		compressed = bitmap->compressed;
		bitsPerPixel = bitmap->bitsPerPixel;

		if (gdi->bitmap_size < (nWidth * nHeight * 4))
		{
			gdi->bitmap_size = nWidth * nHeight * 4;
			gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16);

			if (!gdi->bitmap_buffer)
				return;
		}

		if (compressed)
		{
			pDstData = gdi->bitmap_buffer;

			if (bitsPerPixel < 32)
			{
				freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED);

				status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel,
						&pDstData, gdi->format, -1, 0, 0, nWidth, nHeight, gdi->palette);
			}
			else
			{
				freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR);

				status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData,
						gdi->format, -1, 0, 0, nWidth, nHeight, TRUE);
			}

			if (status < 0)
			{
				WLog_ERR(TAG, "bitmap decompression failure");
				return;
			}

			pSrcData = gdi->bitmap_buffer;
		}
		else
		{
			pDstData = gdi->bitmap_buffer;
			SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE);

			status = freerdp_image_copy(pDstData, gdi->format, -1, 0, 0,
						nWidth, nHeight, pSrcData, SrcFormat, -1, 0, 0, gdi->palette);

			pSrcData = gdi->bitmap_buffer;
		}

		nSrcStep = nWidth * gdi->bytesPerPixel;

		pDstData = gdi->primary_buffer;
		nDstStep = gdi->width * gdi->bytesPerPixel;

		nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */
		nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */

		status = freerdp_image_copy(pDstData, gdi->format, nDstStep, nXDst, nYDst,
				nWidth, nHeight, pSrcData, gdi->format, nSrcStep, nXSrc, nYSrc, gdi->palette);

		gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, nWidth, nHeight);
	}
}
Beispiel #14
0
static BOOL xf_gdi_surface_bits(rdpContext* context,
                                const SURFACE_BITS_COMMAND* cmd)
{
	BYTE* pSrcData;
	xfContext* xfc = (xfContext*) context;
	BOOL ret = FALSE;
	DWORD format;
	rdpGdi* gdi;
	REGION16 region;
	RECTANGLE_16 cmdRect;

	if (!context || !cmd || !context->gdi)
		return FALSE;

	region16_init(&region);
	cmdRect.left = cmd->destLeft;
	cmdRect.top = cmd->destTop;
	cmdRect.right = cmdRect.left + cmd->width;
	cmdRect.bottom = cmdRect.top + cmd->height;


	gdi = context->gdi;

	xf_lock_x11(xfc, FALSE);

	switch (cmd->codecID)
	{
		case RDP_CODEC_ID_REMOTEFX:
			if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData,
			                         cmd->bitmapDataLength, cmd->destLeft, cmd->destTop,
			                         gdi->primary_buffer, gdi->dstFormat, gdi->stride,
			                         gdi->height, &region))
				goto fail;

			break;

		case RDP_CODEC_ID_NSCODEC:
			if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width,
			                         cmd->height, cmd->bitmapData, cmd->bitmapDataLength,
			                         gdi->primary_buffer, gdi->dstFormat, gdi->stride,
			                         0, 0, cmd->width, cmd->height, FREERDP_FLIP_VERTICAL))
				goto fail;

			region16_union_rect(&region, &region, &cmdRect);
			break;

		case RDP_CODEC_ID_NONE:
			pSrcData = cmd->bitmapData;
			format = gdi_get_pixel_format(cmd->bpp);

			if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride,
			                        0, 0, cmd->width, cmd->height,
			                        pSrcData, format, 0, 0, 0,
			                        &xfc->context.gdi->palette, FREERDP_FLIP_VERTICAL))
				goto fail;

			region16_union_rect(&region, &region, &cmdRect);
			break;

		default:
			WLog_ERR(TAG, "Unsupported codecID %"PRIu32"", cmd->codecID);
			ret = TRUE;
			goto fail;
	}

	ret = xf_gdi_update_screen(xfc, gdi->primary_buffer, gdi->stride, &region);
fail:
	region16_uninit(&region);
	xf_unlock_x11(xfc, FALSE);
	return ret;
}
Beispiel #15
0
static BOOL gdi_surface_bits(rdpContext* context,
                             const SURFACE_BITS_COMMAND* cmd)
{
	BOOL result = FALSE;
	DWORD format;
	rdpGdi* gdi;
	REGION16 region;
	RECTANGLE_16 cmdRect;
	UINT32 i, nbRects;
	const RECTANGLE_16* rects;

	if (!context || !cmd)
		return FALSE;

	gdi = context->gdi;
	WLog_Print(gdi->log, WLOG_DEBUG,
	           "destLeft %"PRIu32" destTop %"PRIu32" destRight %"PRIu32" destBottom %"PRIu32" "
	           "bpp %"PRIu32" codecID %"PRIu32" width %"PRIu32" height %"PRIu32" length %"PRIu32"",
	           cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom,
	           cmd->bpp, cmd->codecID, cmd->width, cmd->height, cmd->bitmapDataLength);

	region16_init(&region);
	cmdRect.left = cmd->destLeft;
	cmdRect.top = cmd->destTop;
	cmdRect.right = cmdRect.left + cmd->width;
	cmdRect.bottom = cmdRect.top + cmd->height;


	switch (cmd->codecID)
	{
		case RDP_CODEC_ID_REMOTEFX:
			if (!rfx_process_message(context->codecs->rfx, cmd->bitmapData,
			                         cmd->bitmapDataLength,
			                         cmd->destLeft, cmd->destTop,
			                         gdi->primary_buffer, gdi->dstFormat,
			                         gdi->stride, gdi->height, &region))
			{
				WLog_ERR(TAG, "Failed to process RemoteFX message");
				goto out;
			}
			break;

		case RDP_CODEC_ID_NSCODEC:
			format = gdi->dstFormat;

			if (!nsc_process_message(context->codecs->nsc, cmd->bpp, cmd->width,
			                         cmd->height, cmd->bitmapData,
			                         cmd->bitmapDataLength, gdi->primary_buffer,
			                         format, gdi->stride, cmd->destLeft, cmd->destTop,
			                         cmd->width, cmd->height, FREERDP_FLIP_VERTICAL))
			{
				WLog_ERR(TAG, "Failed to process NSCodec message");
				goto out;
			}
			region16_union_rect(&region, &region, &cmdRect);
			break;

		case RDP_CODEC_ID_NONE:
			format = gdi_get_pixel_format(cmd->bpp);

			if (!freerdp_image_copy(gdi->primary_buffer, gdi->dstFormat, gdi->stride,
			                        cmd->destLeft, cmd->destTop, cmd->width, cmd->height,
			                        cmd->bitmapData, format, 0, 0, 0,
			                        &gdi->palette, FREERDP_FLIP_VERTICAL))
			{
				WLog_ERR(TAG, "Failed to process nocodec message");
				goto out;
			}
			region16_union_rect(&region, &region, &cmdRect);
			break;

		default:
			WLog_ERR(TAG, "Unsupported codecID %"PRIu32"", cmd->codecID);
			break;
	}

	if (!(rects = region16_rects(&region, &nbRects)))
		goto out;

	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;

		if (!gdi_InvalidateRegion(gdi->primary->hdc, left, top, width, height))
		{
			WLog_ERR(TAG, "Failed to update invalid region");
			goto out;
		}
	}

	result = TRUE;
out:
	region16_uninit(&region);
	return result;
}
Beispiel #16
0
static BOOL gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
{
	HGDI_BRUSH originalBrush;
	rdpGdi* gdi = context->gdi;
	BOOL ret = TRUE;
	const rdpBrush* brush = &mem3blt->brush;
	gdiBitmap* bitmap = (gdiBitmap*) mem3blt->bitmap;
	UINT32 foreColor;
	UINT32 backColor;
	UINT32 originalColor;

	if (!gdi_decode_color(gdi, mem3blt->foreColor, &foreColor, NULL))
		return FALSE;

	if (!gdi_decode_color(gdi, mem3blt->backColor, &backColor, NULL))
		return FALSE;

	originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor);

	switch (brush->style)
	{
		case GDI_BS_SOLID:
			originalBrush = gdi->drawing->hdc->brush;
			gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor);

			if (!gdi->drawing->hdc->brush)
			{
				ret = FALSE;
				goto out_fail;
			}

			ret = gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
			                 mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
			                 mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop),
			                 &gdi->palette);
			gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
			gdi->drawing->hdc->brush = originalBrush;
			break;

		case GDI_BS_PATTERN:
			{
				HGDI_BITMAP hBmp;
				UINT32 brushFormat;
				BYTE* data = (BYTE*) _aligned_malloc(8 * 8 * GetBytesPerPixel(
				        gdi->drawing->hdc->format),
				                                     16);

				if (!data)
				{
					ret = FALSE;
					goto out_fail;
				}

				if (brush->bpp > 1)
				{
					brushFormat = gdi_get_pixel_format(brush->bpp);

					if (!freerdp_image_copy(data, gdi->drawing->hdc->format, 0, 0, 0,
					                        8, 8, brush->data, brushFormat,
					                        0, 0, 0, &gdi->palette, FREERDP_FLIP_NONE))
					{
						ret = FALSE;
						_aligned_free(data);
						goto out_fail;
					}
				}
				else
				{
					if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0,
					                                        0, 8, 8,
					                                        brush->data, backColor, foreColor,
					                                        &gdi->palette))
					{
						ret = FALSE;
						_aligned_free(data);
						goto out_fail;
					}
				}

				hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->format, data);

				if (!hBmp)
				{
					ret = FALSE;
					_aligned_free(data);
					goto out_fail;
				}

				originalBrush = gdi->drawing->hdc->brush;
				gdi->drawing->hdc->brush = gdi_CreatePatternBrush(hBmp);

				if (!gdi->drawing->hdc->brush)
				{
					gdi_DeleteObject((HGDIOBJECT) hBmp);
					goto out_fail;
				}

				gdi->drawing->hdc->brush->nXOrg = brush->x;
				gdi->drawing->hdc->brush->nYOrg = brush->y;
				ret = gdi_BitBlt(gdi->drawing->hdc, mem3blt->nLeftRect, mem3blt->nTopRect,
				                 mem3blt->nWidth, mem3blt->nHeight, bitmap->hdc,
				                 mem3blt->nXSrc, mem3blt->nYSrc, gdi_rop3_code(mem3blt->bRop),
				                 &gdi->palette);
				gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
				gdi->drawing->hdc->brush = originalBrush;
			}
			break;

		default:
			WLog_ERR(TAG,  "Mem3Blt unimplemented brush style:%"PRIu32"", brush->style);
			break;
	}

out_fail:
	gdi_SetTextColor(gdi->drawing->hdc, originalColor);
	return ret;
}
Beispiel #17
0
static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
{
	const rdpBrush* brush = &patblt->brush;
	UINT32 foreColor;
	UINT32 backColor;
	UINT32 originalColor;
	HGDI_BRUSH originalBrush, hbrush = NULL;
	rdpGdi* gdi = context->gdi;
	BOOL ret = FALSE;
	const DWORD rop = gdi_rop3_code(patblt->bRop);
	UINT32 nXSrc = 0;
	UINT32 nYSrc = 0;
	BYTE data[8 * 8 * 4];
	HGDI_BITMAP hBmp = NULL;

	if (!gdi_decode_color(gdi, patblt->foreColor, &foreColor, NULL))
		return FALSE;

	if (!gdi_decode_color(gdi, patblt->backColor, &backColor, NULL))
		return FALSE;

	originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor);
	originalBrush = gdi->drawing->hdc->brush;

	switch (brush->style)
	{
		case GDI_BS_SOLID:
			hbrush = gdi_CreateSolidBrush(foreColor);
			break;

		case GDI_BS_HATCHED:
			{
				const BYTE* hatched;
				hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch);

				if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0,
				                                        0, 8, 8,
				                                        hatched, backColor, foreColor, &gdi->palette))
					goto out_error;

				hBmp = gdi_CreateBitmapEx(8, 8, gdi->drawing->hdc->format, 0, data, NULL);

				if (!hBmp)
					goto out_error;

				hbrush = gdi_CreateHatchBrush(hBmp);
			}
			break;

		case GDI_BS_PATTERN:
			{
				UINT32 brushFormat;

				if (brush->bpp > 1)
				{
					brushFormat = gdi_get_pixel_format(brush->bpp);

					if (!freerdp_image_copy(data, gdi->drawing->hdc->format, 0, 0, 0,
					                        8, 8, brush->data, brushFormat, 0, 0, 0,
					                        &gdi->palette, FREERDP_FLIP_NONE))
						goto out_error;
				}
				else
				{
					if (!freerdp_image_copy_from_monochrome(data, gdi->drawing->hdc->format, 0, 0,
					                                        0, 8, 8,
					                                        brush->data, backColor, foreColor, &gdi->palette))
						goto out_error;
				}

				hBmp = gdi_CreateBitmapEx(8, 8, gdi->drawing->hdc->format, 0, data, NULL);

				if (!hBmp)
					goto out_error;

				hbrush = gdi_CreatePatternBrush(hBmp);
			}
			break;

		default:
			WLog_ERR(TAG,  "unimplemented brush style:%"PRIu32"", brush->style);
			break;
	}

	if (!hbrush)
		gdi_DeleteObject((HGDIOBJECT) hBmp);
	else
	{
		hbrush->nXOrg = brush->x;
		hbrush->nYOrg = brush->y;
		gdi->drawing->hdc->brush = hbrush;
		ret = gdi_BitBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
		                 patblt->nWidth, patblt->nHeight,
		                 gdi->primary->hdc, nXSrc, nYSrc, rop, &gdi->palette);
	}

out_error:
	gdi_DeleteObject((HGDIOBJECT) hbrush);
	gdi->drawing->hdc->brush = originalBrush;
	gdi_SetTextColor(gdi->drawing->hdc, originalColor);
	return ret;
}
Beispiel #18
0
static BOOL gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
{
	BYTE* data;
	rdpBrush* brush;
	UINT32 foreColor;
	UINT32 backColor;
	GDI_COLOR originalColor;
	HGDI_BRUSH originalBrush;
	rdpGdi* gdi = context->gdi;
	BOOL ret = TRUE;

	brush = &patblt->brush;

	foreColor = freerdp_convert_gdi_order_color(patblt->foreColor, gdi->srcBpp, gdi->format, gdi->palette);
	backColor = freerdp_convert_gdi_order_color(patblt->backColor, gdi->srcBpp, gdi->format, gdi->palette);

	originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor);

	if (brush->style == GDI_BS_SOLID)
	{
		originalBrush = gdi->drawing->hdc->brush;

		gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor);
		if (!gdi->drawing->hdc->brush)
		{
			ret = FALSE;
			goto out_error;
		}

		if (gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
				patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)) == 0)
			ret = FALSE;

		gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
		gdi->drawing->hdc->brush = originalBrush;
	}
	else if (brush->style == GDI_BS_HATCHED)
	{
		BYTE* hatched;
		HGDI_BITMAP hBmp;

		data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
		if (!data)
		{
			ret = FALSE;
			goto out_error;
		}

		hatched = GDI_BS_HATCHED_PATTERNS + (8 * brush->hatch);

		freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8,
				hatched, backColor, foreColor, gdi->palette);

		hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
		if (!hBmp)
		{
			_aligned_free(data);
			ret = FALSE;
			goto out_error;
		}

		originalBrush = gdi->drawing->hdc->brush;
		gdi->drawing->hdc->brush = gdi_CreateHatchBrush(hBmp);
		if (!gdi->drawing->hdc->brush)
		{
			_aligned_free(data);
			ret = FALSE;
			goto out_error;
		}

		if (gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
		patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)) == 0)
			ret = FALSE;

		gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
		gdi->drawing->hdc->brush = originalBrush;
	}
	else if (brush->style == GDI_BS_PATTERN)
	{
		HGDI_BITMAP hBmp;
		UINT32 brushFormat;

		if (brush->bpp > 1)
		{
			brushFormat = gdi_get_pixel_format(brush->bpp, FALSE);

			data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
			if (!data)
			{
				ret = FALSE;
				goto out_error;
			}

			freerdp_image_copy(data, gdi->format, -1, 0, 0,
					8, 8, brush->data, brushFormat, -1, 0, 0, gdi->palette);
		}
		else
		{
			data = (BYTE*) _aligned_malloc(8 * 8 * gdi->bytesPerPixel, 16);
			if (!data)
			{
				ret = FALSE;
				goto out_error;
			}

			freerdp_image_copy_from_monochrome(data, gdi->format, -1, 0, 0, 8, 8,
					brush->data, backColor, foreColor, gdi->palette);
		}

		hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data);
		if (!hBmp)
		{
			_aligned_free(data);
			ret = FALSE;
			goto out_error;
		}

		originalBrush = gdi->drawing->hdc->brush;
		gdi->drawing->hdc->brush = gdi_CreatePatternBrush(hBmp);
		if (!gdi->drawing->hdc->brush)
		{
			_aligned_free(data);
			ret = FALSE;
			goto out_error;
		}

		if (gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect,
				patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)) == 0)
			ret = FALSE;

		gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush);
		gdi->drawing->hdc->brush = originalBrush;
	}
	else
	{
		WLog_ERR(TAG,  "unimplemented brush style:%d", brush->style);
	}

out_error:
	gdi_SetTextColor(gdi->drawing->hdc, originalColor);
	return ret;
}