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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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); } }
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); } }
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(®ion); 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, ®ion)) 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(®ion, ®ion, &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(®ion, ®ion, &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, ®ion); fail: region16_uninit(®ion); xf_unlock_x11(xfc, FALSE); return ret; }
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(®ion); 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, ®ion)) { 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(®ion, ®ion, &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(®ion, ®ion, &cmdRect); break; default: WLog_ERR(TAG, "Unsupported codecID %"PRIu32"", cmd->codecID); break; } if (!(rects = region16_rects(®ion, &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(®ion); return result; }
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; }
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; }
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; }