From f7a71079dd3f96dddd217d3bd45c2bdbad6ed0b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 12 Feb 2012 17:14:59 -0500 Subject: [PATCH 1/6] xfreerdp: reintroduce Polygon drawing --- client/X11/xf_gdi.c | 176 +++++++++++++++++++++++++++++++++- client/X11/xfreerdp.c | 6 +- cunit/test_orders.c | 2 +- include/freerdp/cache/brush.h | 4 +- include/freerdp/primary.h | 12 ++- libfreerdp-cache/brush.c | 28 ++++++ libfreerdp-core/orders.c | 23 ++++- 7 files changed, 235 insertions(+), 16 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 0b20d0c75..3cea767a4 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -620,7 +620,175 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { + printf("Mem3Blt\n"); +} +void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) +{ + int i, npoints; + XPoint* points; + uint32 brush_color; + xfInfo* xfi = ((xfContext*) context)->xfi; + + printf("PolygonSC\n"); + + xf_set_rop2(xfi, polygon_sc->bRop2); + brush_color = freerdp_color_convert_rgb(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv); + + npoints = polygon_sc->numPoints + 1; + points = xmalloc(sizeof(XPoint) * npoints); + + points[0].x = polygon_sc->xStart; + points[0].y = polygon_sc->yStart; + + for (i = 0; i < polygon_sc->numPoints; i++) + { + points[i + 1].x = polygon_sc->points[i].x; + points[i + 1].y = polygon_sc->points[i].y; + } + + switch (polygon_sc->fillMode) + { + case 1: /* alternate */ + XSetFillRule(xfi->display, xfi->gc, EvenOddRule); + break; + + case 2: /* winding */ + XSetFillRule(xfi->display, xfi->gc, WindingRule); + break; + + default: + printf("PolygonSC unknown fillMode: %d\n", polygon_sc->fillMode); + break; + } + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, brush_color); + + XFillPolygon(xfi->display, xfi->drawing, xfi->gc, + points, npoints, Complex, CoordModePrevious); + + if (xfi->drawing == xfi->primary) + { + XFillPolygon(xfi->display, xfi->drawable, xfi->gc, + points, npoints, Complex, CoordModePrevious); + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); + xfree(points); +} + +void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) +{ + int i, npoints; + XPoint* points; + Pixmap pattern; + rdpBrush* brush; + uint32 foreColor; + uint32 backColor; + xfInfo* xfi = ((xfContext*) context)->xfi; + + brush = &(polygon_cb->brush); + xf_set_rop2(xfi, polygon_cb->bRop2); + foreColor = freerdp_color_convert_rgb(polygon_cb->foreColor, xfi->srcBpp, 32, xfi->clrconv); + backColor = freerdp_color_convert_rgb(polygon_cb->backColor, xfi->srcBpp, 32, xfi->clrconv); + + npoints = polygon_cb->numPoints + 1; + points = xmalloc(sizeof(XPoint) * npoints); + + points[0].x = polygon_cb->xStart; + points[0].y = polygon_cb->yStart; + + for (i = 0; i < polygon_cb->numPoints; i++) + { + points[i + 1].x = polygon_cb->points[i].x; + points[i + 1].y = polygon_cb->points[i].y; + } + + switch (polygon_cb->fillMode) + { + case 1: /* alternate */ + XSetFillRule(xfi->display, xfi->gc, EvenOddRule); + break; + + case 2: /* winding */ + XSetFillRule(xfi->display, xfi->gc, WindingRule); + break; + + default: + printf("PolygonCB unknown fillMode: %d\n", polygon_cb->fillMode); + break; + } + + if (brush->style == GDI_BS_PATTERN) + { + if (brush->bpp > 1) + { + pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data); + + XSetFillStyle(xfi->display, xfi->gc, FillTiled); + XSetTile(xfi->display, xfi->gc, pattern); + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); + + XFillPolygon(xfi->display, xfi->drawing, xfi->gc, + points, npoints, Complex, CoordModePrevious); + + if (xfi->drawing == xfi->primary) + { + XFillPolygon(xfi->display, xfi->drawable, xfi->gc, + points, npoints, Complex, CoordModePrevious); + } + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetTSOrigin(xfi->display, xfi->gc, 0, 0); + XFreePixmap(xfi->display, pattern); + } + else + { + pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data); + + XSetForeground(xfi->display, xfi->gc, backColor); + XSetBackground(xfi->display, xfi->gc, foreColor); + + if (polygon_cb->backMode == BACKMODE_TRANSPARENT) + XSetFillStyle(xfi->display, xfi->gc, FillStippled); + else if (polygon_cb->backMode == BACKMODE_OPAQUE) + XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled); + + XSetStipple(xfi->display, xfi->gc, pattern); + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); + + XFillPolygon(xfi->display, xfi->drawing, xfi->gc, + points, npoints, Complex, CoordModePrevious); + + if (xfi->drawing == xfi->primary) + { + XFillPolygon(xfi->display, xfi->drawable, xfi->gc, + points, npoints, Complex, CoordModePrevious); + } + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetTSOrigin(xfi->display, xfi->gc, 0, 0); + XFreePixmap(xfi->display, pattern); + } + } + else + { + printf("unimplemented brush style:%d\n", brush->style); + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); + xfree(points); +} + +void xf_gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc) +{ + printf("EllipseSC\n"); +} + +void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) +{ + printf("EllipseCB\n"); } void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) @@ -777,10 +945,10 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update) primary->GlyphIndex = NULL; primary->FastIndex = NULL; primary->FastGlyph = NULL; - primary->PolygonSC = NULL; - primary->PolygonCB = NULL; - primary->EllipseSC = NULL; - primary->EllipseCB = NULL; + primary->PolygonSC = xf_gdi_polygon_sc; + primary->PolygonCB = xf_gdi_polygon_cb; + primary->EllipseSC = xf_gdi_ellipse_sc; + primary->EllipseCB = xf_gdi_ellipse_cb; update->SurfaceBits = xf_gdi_surface_bits; update->SurfaceFrameMarker = xf_gdi_surface_frame_marker; diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index e1c312b27..8f42438ec 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -502,8 +502,10 @@ boolean xf_pre_connect(freerdp* instance) settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; settings->order_support[NEG_FAST_INDEX_INDEX] = true; settings->order_support[NEG_FAST_GLYPH_INDEX] = true; - settings->order_support[NEG_POLYGON_SC_INDEX] = false; - settings->order_support[NEG_POLYGON_CB_INDEX] = false; + + settings->order_support[NEG_POLYGON_SC_INDEX] = (settings->sw_gdi) ? false : true; + settings->order_support[NEG_POLYGON_CB_INDEX] = (settings->sw_gdi) ? false : true; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; diff --git a/cunit/test_orders.c b/cunit/test_orders.c index 6ae8bfd4b..41e3f1b8a 100644 --- a/cunit/test_orders.c +++ b/cunit/test_orders.c @@ -517,7 +517,7 @@ void test_read_polygon_cb_order(void) CU_ASSERT(polygon_cb.brush.x == 4); CU_ASSERT(polygon_cb.brush.y == 3); CU_ASSERT(polygon_cb.brush.style == 0x81); - CU_ASSERT(polygon_cb.nDeltaEntries == 3); + CU_ASSERT(polygon_cb.numPoints == 3); CU_ASSERT(polygon_cb.cbData == 5); CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1)); diff --git a/include/freerdp/cache/brush.h b/include/freerdp/cache/brush.h index ad1d547ae..8349d11b2 100644 --- a/include/freerdp/cache/brush.h +++ b/include/freerdp/cache/brush.h @@ -41,7 +41,9 @@ struct rdp_brush_cache { pPatBlt PatBlt; /* 0 */ pCacheBrush CacheBrush; /* 1 */ - uint32 paddingA[16 - 2]; /* 2 */ + pPolygonSC PolygonSC; /* 2 */ + pPolygonCB PolygonCB; /* 3 */ + uint32 paddingA[16 - 4]; /* 4 */ uint32 maxEntries; /* 16 */ uint32 maxMonoEntries; /* 17 */ diff --git a/include/freerdp/primary.h b/include/freerdp/primary.h index d3b74888d..903b9319d 100644 --- a/include/freerdp/primary.h +++ b/include/freerdp/primary.h @@ -22,6 +22,9 @@ #include +#define BACKMODE_TRANSPARENT 0x0001 +#define BACKMODE_OPAQUE 0x0002 + struct rdp_bounds { sint32 left; @@ -365,9 +368,9 @@ struct _POLYGON_SC_ORDER uint32 bRop2; uint32 fillMode; uint32 brushColor; - uint32 nDeltaEntries; + uint32 numPoints; uint32 cbData; - uint8* codeDeltaList; + DELTA_POINT* points; }; typedef struct _POLYGON_SC_ORDER POLYGON_SC_ORDER; @@ -376,13 +379,14 @@ struct _POLYGON_CB_ORDER sint32 xStart; sint32 yStart; uint32 bRop2; + uint32 backMode; uint32 fillMode; uint32 backColor; uint32 foreColor; rdpBrush brush; - uint32 nDeltaEntries; + uint32 numPoints; uint32 cbData; - uint8* codeDeltaList; + DELTA_POINT* points; }; typedef struct _POLYGON_CB_ORDER POLYGON_CB_ORDER; diff --git a/libfreerdp-cache/brush.c b/libfreerdp-cache/brush.c index 2aabfe83b..590807d69 100644 --- a/libfreerdp-cache/brush.c +++ b/libfreerdp-cache/brush.c @@ -42,6 +42,30 @@ void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) brush->style = style; } +void update_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) +{ + rdpCache* cache = context->cache; + IFCALL(cache->brush->PolygonSC, context, polygon_sc); +} + +void update_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) +{ + uint8 style; + rdpBrush* brush = &polygon_cb->brush; + rdpCache* cache = context->cache; + + style = brush->style; + + if (brush->style & CACHED_BRUSH) + { + brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp); + brush->style = 0x03; + } + + IFCALL(cache->brush->PolygonCB, context, polygon_cb); + brush->style = style; +} + void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush) { rdpCache* cache = context->cache; @@ -127,8 +151,12 @@ void brush_cache_register_callbacks(rdpUpdate* update) rdpCache* cache = update->context->cache; cache->brush->PatBlt = update->primary->PatBlt; + cache->brush->PolygonSC = update->primary->PolygonSC; + cache->brush->PolygonCB = update->primary->PolygonCB; update->primary->PatBlt = update_gdi_patblt; + update->primary->PolygonSC = update_gdi_polygon_sc; + update->primary->PolygonCB = update_gdi_polygon_cb; update->secondary->CacheBrush = update_gdi_cache_brush; } diff --git a/libfreerdp-core/orders.c b/libfreerdp-core/orders.c index 46477295e..493fba80a 100644 --- a/libfreerdp-core/orders.c +++ b/libfreerdp-core/orders.c @@ -1086,12 +1086,18 @@ void update_read_polygon_sc_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_SC_O update_read_color(s, &polygon_sc->brushColor); if (orderInfo->fieldFlags & ORDER_FIELD_06) - stream_read_uint8(s, polygon_sc->nDeltaEntries); + stream_read_uint8(s, polygon_sc->numPoints); if (orderInfo->fieldFlags & ORDER_FIELD_07) { stream_read_uint8(s, polygon_sc->cbData); - stream_seek(s, polygon_sc->cbData); + + if (polygon_sc->points == NULL) + polygon_sc->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_sc->numPoints); + else + polygon_sc->points = (DELTA_POINT*) xrealloc(polygon_sc->points, sizeof(DELTA_POINT) * polygon_sc->numPoints); + + update_read_delta_points(s, polygon_sc->points, polygon_sc->numPoints, polygon_sc->xStart, polygon_sc->yStart); } } @@ -1118,13 +1124,22 @@ void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_O update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6); if (orderInfo->fieldFlags & ORDER_FIELD_12) - stream_read_uint8(s, polygon_cb->nDeltaEntries); + stream_read_uint8(s, polygon_cb->numPoints); if (orderInfo->fieldFlags & ORDER_FIELD_13) { stream_read_uint8(s, polygon_cb->cbData); - stream_seek(s, polygon_cb->cbData); + + if (polygon_cb->points == NULL) + polygon_cb->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polygon_cb->numPoints); + else + polygon_cb->points = (DELTA_POINT*) xrealloc(polygon_cb->points, sizeof(DELTA_POINT) * polygon_cb->numPoints); + + update_read_delta_points(s, polygon_cb->points, polygon_cb->numPoints, polygon_cb->xStart, polygon_cb->yStart); } + + polygon_cb->backMode = (polygon_cb->bRop2 & 0x80) ? BACKMODE_TRANSPARENT : BACKMODE_OPAQUE; + polygon_cb->bRop2 = (polygon_cb->bRop2 & 0x1F); } void update_read_ellipse_sc_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc) From 46e9eeb695a4f1f010bfea6f07517d593faec90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 12 Feb 2012 18:12:28 -0500 Subject: [PATCH 2/6] xfreerdp: added support for Mem3Blt --- client/X11/xf_gdi.c | 109 +++++++++++++++++++++++++++++++------- client/X11/xfreerdp.c | 4 +- include/freerdp/gdi/gdi.h | 15 ++++++ libfreerdp-cache/bitmap.c | 11 ++++ 4 files changed, 119 insertions(+), 20 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 3cea767a4..7a574bc3e 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -73,15 +73,15 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXclear; break; - case 0x000500A9: + case GDI_DPon: function = GXnor; break; - case 0x000A0329: + case GDI_DPna: function = GXandInverted; break; - case 0x000F0001: + case GDI_Pn: function = GXcopyInverted; break; @@ -101,7 +101,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXandReverse; break; - case 0x00500325: + case GDI_PDna: function = GXandReverse; break; @@ -113,7 +113,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXxor; break; - case 0x005F00E9: + case GDI_DPan: function = GXnand; break; @@ -121,7 +121,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXxor; break; - case 0x007700E6: + case GDI_DSan: function = GXnand; break; @@ -129,11 +129,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXand; break; - case 0x00990066: + case GDI_DSxn: function = GXequiv; break; - case 0x00A000C9: + case GDI_DPa: function = GXand; break; @@ -141,11 +141,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXequiv; break; - case 0x00AA0029: + case GDI_D: function = GXnoop; break; - case 0x00AF0229: + case GDI_DPno: function = GXorInverted; break; @@ -157,7 +157,7 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXcopy; break; - case 0x00DD0228: + case GDI_SDno: function = GXorReverse; break; @@ -169,11 +169,11 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXcopy; break; - case 0x00F50225: + case GDI_PDno: function = GXorReverse; break; - case 0x00FA0089: + case GDI_DPo: function = GXor; break; @@ -181,6 +181,10 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3) function = GXset; break; + case GDI_PSDPxax: + function = GXand; + break; + default: break; } @@ -205,17 +209,19 @@ Pixmap xf_brush_new(xfInfo* xfi, int width, int height, int bpp, uint8* data) bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, xfi->depth); - if(data != NULL) + if (data != NULL) { - GC gc; // FIXME, should cache + GC gc; cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv); + image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0, (char*) cdata, width, height, xfi->scanline_pad, 0); gc = XCreateGC(xfi->display, xfi->drawable, 0, NULL); XPutImage(xfi->display, bitmap, gc, image, 0, 0, 0, 0, width, height); XFree(image); + if (cdata != data) xfree(cdata); @@ -620,7 +626,74 @@ void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { - printf("Mem3Blt\n"); + rdpBrush* brush; + xfBitmap* bitmap; + uint32 foreColor; + uint32 backColor; + Pixmap pattern = 0; + xfInfo* xfi = ((xfContext*) context)->xfi; + + brush = &mem3blt->brush; + bitmap = (xfBitmap*) mem3blt->bitmap; + xf_set_rop3(xfi, gdi_rop3_code(mem3blt->bRop)); + foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, xfi->srcBpp, 32, xfi->clrconv); + backColor = freerdp_color_convert_rgb(mem3blt->backColor, xfi->srcBpp, 32, xfi->clrconv); + + if (brush->style == GDI_BS_PATTERN) + { + if (brush->bpp > 1) + { + pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data); + + XSetFillStyle(xfi->display, xfi->gc, FillTiled); + XSetTile(xfi->display, xfi->gc, pattern); + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); + } + else + { + pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data); + + XSetForeground(xfi->display, xfi->gc, backColor); + XSetBackground(xfi->display, xfi->gc, foreColor); + XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled); + XSetStipple(xfi->display, xfi->gc, pattern); + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); + } + } + else if (brush->style == GDI_BS_SOLID) + { + XSetForeground(xfi->display, xfi->gc, backColor); + XSetBackground(xfi->display, xfi->gc, foreColor); + XSetFillStyle(xfi->display, xfi->gc, FillStippled); + } + else + { + printf("Mem3Blt unimplemented brush style:%d\n", brush->style); + } + + XCopyArea(xfi->display, bitmap->pixmap, xfi->drawing, xfi->gc, + mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight, + mem3blt->nLeftRect, mem3blt->nTopRect); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, bitmap->pixmap, xfi->drawable, xfi->gc, + mem3blt->nXSrc, mem3blt->nYSrc, mem3blt->nWidth, mem3blt->nHeight, + mem3blt->nLeftRect, mem3blt->nTopRect); + } + + gdi_InvalidateRegion(xfi->hdc, mem3blt->nLeftRect, mem3blt->nTopRect, mem3blt->nWidth, mem3blt->nHeight); + } + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetTSOrigin(xfi->display, xfi->gc, 0, 0); + + if (pattern != 0) + XFreePixmap(xfi->display, pattern); + + XSetFunction(xfi->display, xfi->gc, GXcopy); } void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) @@ -630,8 +703,6 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) uint32 brush_color; xfInfo* xfi = ((xfContext*) context)->xfi; - printf("PolygonSC\n"); - xf_set_rop2(xfi, polygon_sc->bRop2); brush_color = freerdp_color_convert_rgb(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv); @@ -774,7 +845,7 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) } else { - printf("unimplemented brush style:%d\n", brush->style); + printf("PolygonCB unimplemented brush style:%d\n", brush->style); } XSetFunction(xfi->display, xfi->gc, GXcopy); diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 8f42438ec..db17a8eb7 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -495,7 +495,9 @@ boolean xf_pre_connect(freerdp* instance) settings->order_support[NEG_LINETO_INDEX] = true; settings->order_support[NEG_POLYLINE_INDEX] = true; settings->order_support[NEG_MEMBLT_INDEX] = bitmap_cache; - settings->order_support[NEG_MEM3BLT_INDEX] = false; + + settings->order_support[NEG_MEM3BLT_INDEX] = (settings->sw_gdi) ? false : true; + settings->order_support[NEG_MEMBLT_V2_INDEX] = bitmap_cache; settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; settings->order_support[NEG_SAVEBITMAP_INDEX] = false; diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index d1b36cbf7..03acd9052 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -63,11 +63,26 @@ #define GDI_BLACKNESS 0x00000042 /* D = 0 */ #define GDI_WHITENESS 0x00FF0062 /* D = 1 */ #define GDI_DSPDxax 0x00E20746 /* D = (S & P) | (~S & D) */ +#define GDI_PSDPxax 0x00B8074A /* D = (S & D) | (~S & P) */ #define GDI_SPna 0x000C0324 /* D = S & ~P */ #define GDI_DSna 0x00220326 /* D = D & ~S */ #define GDI_DPa 0x00A000C9 /* D = D & P */ #define GDI_PDxn 0x00A50065 /* D = D ^ ~P */ +#define GDI_DPon 0x000500A9 +#define GDI_DPna 0x000A0329 +#define GDI_Pn 0x000F0001 +#define GDI_PDna 0x00500325 +#define GDI_DPan 0x005F00E9 +#define GDI_DSan 0x007700E6 +#define GDI_DSxn 0x00990066 +#define GDI_DPa 0x00A000C9 +#define GDI_D 0x00AA0029 +#define GDI_DPno 0x00AF0229 +#define GDI_SDno 0x00DD0228 +#define GDI_PDno 0x00F50225 +#define GDI_DPo 0x00FA0089 + /* Brush Styles */ #define GDI_BS_SOLID 0x00 #define GDI_BS_NULL 0x01 diff --git a/libfreerdp-cache/bitmap.c b/libfreerdp-cache/bitmap.c index 652a39189..99c100531 100644 --- a/libfreerdp-cache/bitmap.c +++ b/libfreerdp-cache/bitmap.c @@ -39,16 +39,27 @@ void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { + uint8 style; rdpBitmap* bitmap; rdpCache* cache = context->cache; + rdpBrush* brush = &mem3blt->brush; if (mem3blt->cacheId == 0xFF) bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex); else bitmap = bitmap_cache_get(cache->bitmap, (uint8) mem3blt->cacheId, mem3blt->cacheIndex); + style = brush->style; + + if (brush->style & CACHED_BRUSH) + { + brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp); + brush->style = 0x03; + } + mem3blt->bitmap = bitmap; IFCALL(cache->bitmap->Mem3Blt, context, mem3blt); + brush->style = style; } void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap) 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 3/6] 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) From e22023cc7680bd385c35c2fc372ab489eeba7eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sun, 12 Feb 2012 20:29:33 -0500 Subject: [PATCH 4/6] libfreerdp-cache: start NineGrid cache --- include/freerdp/cache/cache.h | 2 + include/freerdp/cache/nine_grid.h | 63 +++++++++++++++ libfreerdp-cache/CMakeLists.txt | 1 + libfreerdp-cache/cache.c | 2 + libfreerdp-cache/nine_grid.c | 130 ++++++++++++++++++++++++++++++ libfreerdp-core/capabilities.c | 2 +- 6 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 include/freerdp/cache/nine_grid.h create mode 100644 libfreerdp-cache/nine_grid.c diff --git a/include/freerdp/cache/cache.h b/include/freerdp/cache/cache.h index aea19a1ce..6aa436032 100644 --- a/include/freerdp/cache/cache.h +++ b/include/freerdp/cache/cache.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,7 @@ struct rdp_cache rdpBitmapCache* bitmap; /* 3 */ rdpOffscreenCache* offscreen; /* 4 */ rdpPaletteCache* palette; /* 5 */ + rdpNineGridCache* nine_grid; /* 6 */ /* internal */ diff --git a/include/freerdp/cache/nine_grid.h b/include/freerdp/cache/nine_grid.h new file mode 100644 index 000000000..55d2a2b13 --- /dev/null +++ b/include/freerdp/cache/nine_grid.h @@ -0,0 +1,63 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * NineGrid Cache + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NINE_GRID_CACHE_H +#define __NINE_GRID_CACHE_H + +#include +#include +#include +#include +#include + +typedef struct _NINE_GRID_ENTRY NINE_GRID_ENTRY; +typedef struct rdp_nine_grid_cache rdpNineGridCache; + +#include + +struct _NINE_GRID_ENTRY +{ + void* entry; +}; + +struct rdp_nine_grid_cache +{ + pDrawNineGrid DrawNineGrid; /* 0 */ + pMultiDrawNineGrid MultiDrawNineGrid; /* 1 */ + uint32 paddingA[16 - 2]; /* 2 */ + + uint32 maxEntries; /* 16 */ + uint32 maxSize; /* 17 */ + NINE_GRID_ENTRY* entries; /* 18 */ + uint32 paddingB[32 - 19]; /* 19 */ + + /* internal */ + + rdpSettings* settings; +}; + +FREERDP_API void* nine_grid_cache_get(rdpNineGridCache* nine_grid, uint32 index); +FREERDP_API void nine_grid_cache_put(rdpNineGridCache* nine_grid, uint32 index, void* entry); + +FREERDP_API void nine_grid_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings); +FREERDP_API void nine_grid_cache_free(rdpNineGridCache* nine_grid); + +#endif /* __NINE_GRID_CACHE_H */ diff --git a/libfreerdp-cache/CMakeLists.txt b/libfreerdp-cache/CMakeLists.txt index 17769e3ef..25e0b7727 100644 --- a/libfreerdp-cache/CMakeLists.txt +++ b/libfreerdp-cache/CMakeLists.txt @@ -21,6 +21,7 @@ set(FREERDP_CACHE_SRCS brush.c pointer.c bitmap.c + nine_grid.c offscreen.c palette.c glyph.c diff --git a/libfreerdp-cache/cache.c b/libfreerdp-cache/cache.c index 375676548..a3462526a 100644 --- a/libfreerdp-cache/cache.c +++ b/libfreerdp-cache/cache.c @@ -37,6 +37,7 @@ rdpCache* cache_new(rdpSettings* settings) cache->bitmap = bitmap_cache_new(settings); cache->offscreen = offscreen_cache_new(settings); cache->palette = palette_cache_new(settings); + cache->nine_grid = nine_grid_cache_new(settings); } return cache; @@ -52,6 +53,7 @@ void cache_free(rdpCache* cache) bitmap_cache_free(cache->bitmap); offscreen_cache_free(cache->offscreen); palette_cache_free(cache->palette); + nine_grid_cache_free(cache->nine_grid); xfree(cache); } } diff --git a/libfreerdp-cache/nine_grid.c b/libfreerdp-cache/nine_grid.c new file mode 100644 index 000000000..177041ced --- /dev/null +++ b/libfreerdp-cache/nine_grid.c @@ -0,0 +1,130 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * NineGrid Cache + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +void update_gdi_draw_nine_grid(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid) +{ + rdpCache* cache = context->cache; + IFCALL(cache->nine_grid->DrawNineGrid, context, draw_nine_grid); +} + +void update_gdi_multi_draw_nine_grid(rdpContext* context, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid) +{ + rdpCache* cache = context->cache; + IFCALL(cache->nine_grid->MultiDrawNineGrid, context, multi_draw_nine_grid); +} + +void nine_grid_cache_register_callbacks(rdpUpdate* update) +{ + rdpCache* cache = update->context->cache; + + cache->nine_grid->DrawNineGrid = update->primary->DrawNineGrid; + cache->nine_grid->MultiDrawNineGrid = update->primary->MultiDrawNineGrid; + + update->primary->DrawNineGrid = update_gdi_draw_nine_grid; + update->primary->MultiDrawNineGrid = update_gdi_multi_draw_nine_grid; +} + +void* nine_grid_cache_get(rdpNineGridCache* nine_grid, uint32 index) +{ + void* entry; + + if (index > nine_grid->maxEntries) + { + printf("invalid NineGrid index: 0x%04X\n", index); + return NULL; + } + + entry = nine_grid->entries[index].entry; + + if (entry == NULL) + { + printf("invalid NineGrid at index: 0x%04X\n", index); + return NULL; + } + + return entry; +} + +void nine_grid_cache_put(rdpNineGridCache* nine_grid, uint32 index, void* entry) +{ + void* prevEntry; + + if (index > nine_grid->maxEntries) + { + printf("invalid NineGrid index: 0x%04X\n", index); + return; + } + + prevEntry = nine_grid->entries[index].entry; + + if (prevEntry != NULL) + xfree(prevEntry); + + nine_grid->entries[index].entry = entry; +} + +rdpNineGridCache* nine_grid_cache_new(rdpSettings* settings) +{ + rdpNineGridCache* nine_grid; + + nine_grid = (rdpNineGridCache*) xzalloc(sizeof(rdpNineGridCache)); + + if (nine_grid != NULL) + { + nine_grid->settings = settings; + + nine_grid->maxSize = 2560; + nine_grid->maxEntries = 256; + + nine_grid->settings->draw_nine_grid_cache_size = nine_grid->maxSize; + nine_grid->settings->draw_nine_grid_cache_entries = nine_grid->maxEntries; + + nine_grid->entries = (NINE_GRID_ENTRY*) xzalloc(sizeof(NINE_GRID_ENTRY) * nine_grid->maxEntries); + } + + return nine_grid; +} + +void nine_grid_cache_free(rdpNineGridCache* nine_grid) +{ + int i; + + if (nine_grid != NULL) + { + if (nine_grid->entries != NULL) + { + for (i = 0; i < (int) nine_grid->maxEntries; i++) + { + if (nine_grid->entries[i].entry != NULL) + xfree(nine_grid->entries[i].entry); + } + + xfree(nine_grid->entries); + } + + xfree(nine_grid); + } +} diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index 5d2d72565..146b7e15c 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -1110,7 +1110,7 @@ void rdp_write_draw_nine_grid_cache_capability_set(STREAM* s, rdpSettings* setti header = rdp_capability_set_start(s); - drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED : DRAW_NINEGRID_NO_SUPPORT; + drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT; stream_write_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ stream_write_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */ From 36dab06a926c1a7e5cc9995c76d34588580db965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 13 Feb 2012 01:40:30 -0500 Subject: [PATCH 5/6] libfreerdp-gdi: implement non-monochrome DSPDxax BitBlt --- libfreerdp-gdi/32bpp.c | 65 +++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/libfreerdp-gdi/32bpp.c b/libfreerdp-gdi/32bpp.c index 6c5dcafd9..8ed8553a9 100644 --- a/libfreerdp-gdi/32bpp.c +++ b/libfreerdp-gdi/32bpp.c @@ -385,48 +385,61 @@ static int BitBlt_SRCPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nW static int BitBlt_DSPDxax_32bpp(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; + uint32* srcp; + uint32* dstp; + uint32* patp; + uint8* srcp8; + uint32 src32; uint32 color32; HGDI_BITMAP hSrcBmp; /* D = (S & P) | (~S & D) */ - /* DSPDxax, used to draw glyphs */ color32 = gdi_get_color_32bpp(hdcDest, hdcDest->textColor); + patp = (uint32*) &color32; hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject; - srcp = hSrcBmp->data; - if (hdcSrc->bytesPerPixel != 1) + if (hdcSrc->bytesPerPixel == 1) { - printf("BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel); - return 0; - } - - for (y = 0; y < nHeight; y++) - { - srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); - dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + /* DSPDxax, used to draw glyphs */ - if (dstp != 0) + srcp = (uint32*) & src32; + + for (y = 0; y < nHeight; y++) { - for (x = 0; x < nWidth; x++) + srcp8 = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) { - patp = (uint8*) &color32; + for (x = 0; x < nWidth; x++) + { + *srcp = ((*srcp8) | (*srcp8 << 8) | (*srcp8 << 16) | (*srcp8 << 24)); - *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); - dstp++; - patp++; + *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); + dstp++; - *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); - dstp++; - patp++; + srcp8++; + } + } + } + } + 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); - *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); - dstp += 2; - srcp++; + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); + srcp++; + dstp++; + } } } } From 38c85de539ecb4b0b8689e2ae8d68185a7c0cbfd Mon Sep 17 00:00:00 2001 From: Christian Nilsson Date: Mon, 13 Feb 2012 22:07:20 +0100 Subject: [PATCH 6/6] fix known swaped b<>r colors in polygon drawings. --- client/X11/xf_gdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 8d0f337d8..ebdcfe735 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -553,7 +553,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) xfInfo* xfi = ((xfContext*) context)->xfi; xf_set_rop2(xfi, polyline->bRop2); - color = freerdp_color_convert_rgb(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv); + color = freerdp_color_convert_var(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv); XSetFillStyle(xfi->display, xfi->gc, FillSolid); XSetForeground(xfi->display, xfi->gc, color); @@ -711,7 +711,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) xfInfo* xfi = ((xfContext*) context)->xfi; xf_set_rop2(xfi, polygon_sc->bRop2); - brush_color = freerdp_color_convert_rgb(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv); + brush_color = freerdp_color_convert_var(polygon_sc->brushColor, xfi->srcBpp, 32, xfi->clrconv); npoints = polygon_sc->numPoints + 1; points = xmalloc(sizeof(XPoint) * npoints);