xfreerdp: added support for Mem3Blt

This commit is contained in:
Marc-André Moreau
2012-02-12 18:12:28 -05:00
parent f7a71079dd
commit 46e9eeb695
4 changed files with 119 additions and 20 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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)