From 233b0b6ef42ed98455719c716c2dde8a8b560a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 12 Feb 2012 19:41:39 -0500 Subject: [PATCH] libfreerdp-gdi: add mem3blt support --- client/X11/xf_gdi.c | 9 ++++- client/X11/xfreerdp.c | 2 +- libfreerdp-core/capabilities.c | 6 ++++ libfreerdp-gdi/16bpp.c | 58 ++++++++++++++++++++++++++++++ libfreerdp-gdi/32bpp.c | 58 ++++++++++++++++++++++++++++++ libfreerdp-gdi/8bpp.c | 64 ++++++++++++++++++++++++++++++++++ libfreerdp-gdi/gdi.c | 30 +++++++++++++++- 7 files changed, 224 insertions(+), 3 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 7a574bc3e..8d0f337d8 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -495,6 +495,11 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult } } +void xf_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid) +{ + printf("DrawNineGrid\n"); +} + void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) { uint32 color; @@ -662,9 +667,11 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) } else if (brush->style == GDI_BS_SOLID) { + XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, backColor); XSetBackground(xfi->display, xfi->gc, foreColor); - XSetFillStyle(xfi->display, xfi->gc, FillStippled); + + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); } else { diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index db17a8eb7..999dc09fd 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -496,7 +496,7 @@ boolean xf_pre_connect(freerdp* instance) settings->order_support[NEG_POLYLINE_INDEX] = true; settings->order_support[NEG_MEMBLT_INDEX] = bitmap_cache; - settings->order_support[NEG_MEM3BLT_INDEX] = (settings->sw_gdi) ? false : true; + settings->order_support[NEG_MEM3BLT_INDEX] = (settings->sw_gdi) ? true : false; settings->order_support[NEG_MEMBLT_V2_INDEX] = bitmap_cache; settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index 510a3b135..5d2d72565 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -2026,6 +2026,12 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) rdp_write_offscreen_bitmap_cache_capability_set(s, settings); } + if (settings->draw_nine_grid) + { + numberCapabilities++; + rdp_write_draw_nine_grid_cache_capability_set(s, settings); + } + if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER]) { if (settings->large_pointer) diff --git a/libfreerdp-gdi/16bpp.c b/libfreerdp-gdi/16bpp.c index 2b6bf746c..22b00091e 100644 --- a/libfreerdp-gdi/16bpp.c +++ b/libfreerdp-gdi/16bpp.c @@ -407,6 +407,60 @@ static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi return 0; } +static int BitBlt_PSDPxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + uint16* patp; + uint16 color16; + + /* D = (S & D) | (~S & P) */ + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color); + patp = (uint16*) &color16; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = (*srcp & *dstp) | (~(*srcp) & *patp); + srcp++; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = (*srcp & *dstp) | (~(*srcp) & *patp); + srcp++; + dstp++; + } + } + } + } + + return 0; +} + static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) { int x, y; @@ -721,6 +775,10 @@ int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh return BitBlt_DSPDxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); break; + case GDI_PSDPxax: + return BitBlt_PSDPxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + case GDI_NOTSRCCOPY: return BitBlt_NOTSRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); break; diff --git a/libfreerdp-gdi/32bpp.c b/libfreerdp-gdi/32bpp.c index fda67901d..6c5dcafd9 100644 --- a/libfreerdp-gdi/32bpp.c +++ b/libfreerdp-gdi/32bpp.c @@ -434,6 +434,60 @@ static int BitBlt_DSPDxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWi return 0; } +static int BitBlt_PSDPxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + uint32* patp; + uint32 color32; + + /* D = (S & D) | (~S & P) */ + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color); + patp = (uint32*) &color32; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = (*srcp & *dstp) | (~(*srcp) & *patp); + srcp++; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = (*srcp & *dstp) | (~(*srcp) & *patp); + srcp++; + dstp++; + } + } + } + } + + return 0; +} + static int BitBlt_SPna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) { int x, y; @@ -750,6 +804,10 @@ int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeigh return BitBlt_DSPDxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); break; + case GDI_PSDPxax: + return BitBlt_PSDPxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + case GDI_NOTSRCCOPY: return BitBlt_NOTSRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); break; diff --git a/libfreerdp-gdi/8bpp.c b/libfreerdp-gdi/8bpp.c index 40f1e740f..e10dde4d8 100644 --- a/libfreerdp-gdi/8bpp.c +++ b/libfreerdp-gdi/8bpp.c @@ -33,6 +33,12 @@ #include +uint8 gdi_get_color_8bpp(HGDI_DC hdc, GDI_COLOR color) +{ + /* TODO: Implement 8bpp gdi_get_color_8bpp() */ + return 0; +} + int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr) { /* TODO: Implement 8bpp FillRect() */ @@ -310,6 +316,60 @@ static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWid return 0; } +static int BitBlt_PSDPxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + uint8* patp; + uint8 color8; + + /* D = (S & D) | (~S & P) */ + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color8 = gdi_get_color_8bpp(hdcDest, hdcDest->brush->color); + patp = (uint8*) &color8; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint8*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = (*srcp & *dstp) | (~(*srcp) & *patp); + srcp++; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint8*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint8*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = (*srcp & *dstp) | (~(*srcp) & *patp); + srcp++; + dstp++; + } + } + } + } + + return 0; +} + static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) { int x, y; @@ -631,6 +691,10 @@ int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight return BitBlt_DSPDxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); break; + case GDI_PSDPxax: + return BitBlt_PSDPxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + case GDI_NOTSRCCOPY: return BitBlt_NOTSRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); break; diff --git a/libfreerdp-gdi/gdi.c b/libfreerdp-gdi/gdi.c index ebdf4cffd..c8f1ebf9c 100644 --- a/libfreerdp-gdi/gdi.c +++ b/libfreerdp-gdi/gdi.c @@ -628,7 +628,35 @@ void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { - printf("Mem3Blt\n"); + rdpBrush* brush; + uint32 foreColor; + uint32 backColor; + gdiBitmap* bitmap; + HGDI_BRUSH originalBrush; + rdpGdi* gdi = context->gdi; + + brush = &mem3blt->brush; + bitmap = (gdiBitmap*) mem3blt->bitmap; + + foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 32, gdi->clrconv); + backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 32, gdi->clrconv); + + 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 + { + printf("Mem3Blt unimplemented brush style:%d\n", brush->style); + } } void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)