diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 169a31126..a4692fe3a 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -30,6 +30,7 @@ #include "xf_window.h" #include "xf_cliprdr.h" #include "xf_input.h" +#include "xf_gfx.h" #include "xf_event.h" #include "xf_input.h" @@ -190,6 +191,12 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app) w = event->xexpose.width; h = event->xexpose.height; + if (xfc->gfx) + { + xf_OutputExpose(xfc, x, y, w, h); + return TRUE; + } + if (!app) { if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) diff --git a/client/X11/xf_gfx.c b/client/X11/xf_gfx.c index 8cea5027e..0d20244b3 100644 --- a/client/X11/xf_gfx.c +++ b/client/X11/xf_gfx.c @@ -56,15 +56,26 @@ int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* re region16_init(&(xfc->invalidRegion)); + xfc->graphicsReset = TRUE; + return 1; } -int xf_SurfaceUpdate(xfContext* xfc) +int xf_OutputUpdate(xfContext* xfc) { UINT16 width, height; + xfGfxSurface* surface; RECTANGLE_16 surfaceRect; const RECTANGLE_16* extents; + if (!xfc->graphicsReset) + return 1; + + surface = (xfGfxSurface*) xfc->gfx->GetSurfaceData(xfc->gfx, xfc->outputSurfaceId); + + if (!surface) + return -1; + surfaceRect.left = 0; surfaceRect.top = 0; surfaceRect.right = xfc->width - 1; @@ -72,6 +83,10 @@ int xf_SurfaceUpdate(xfContext* xfc) region16_intersect_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &surfaceRect); + XSetClipMask(xfc->display, xfc->gc, None); + XSetFunction(xfc->display, xfc->gc, GXcopy); + XSetFillStyle(xfc->display, xfc->gc, FillSolid); + if (!region16_is_empty(&(xfc->invalidRegion))) { extents = region16_extents(&(xfc->invalidRegion)); @@ -85,27 +100,39 @@ int xf_SurfaceUpdate(xfContext* xfc) if (height > xfc->height) height = xfc->height; - printf("xf_SurfaceUpdate: x: %d y: %d width: %d height: %d\n", + XPutImage(xfc->display, xfc->drawable, xfc->gc, surface->image, + extents->left, extents->top, extents->left, extents->top, width, height); } - else - { - printf("xf_SurfaceUpdate: null region\n"); - } region16_clear(&(xfc->invalidRegion)); + XSetClipMask(xfc->display, xfc->gc, None); XSync(xfc->display, True); return 1; } +int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height) +{ + RECTANGLE_16 invalidRect; + + invalidRect.left = x; + invalidRect.top = y; + invalidRect.right = x + width - 1; + invalidRect.bottom = y + height - 1; + + region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); + + xf_OutputUpdate(xfc); + + return 1; +} + int xf_StartFrame(RdpgfxClientContext* context, RDPGFX_START_FRAME_PDU* startFrame) { xfContext* xfc = (xfContext*) context->custom; - printf("xf_StartFrame: %d\n", startFrame->frameId); - xfc->inGfxFrame = TRUE; return 1; @@ -115,9 +142,7 @@ int xf_EndFrame(RdpgfxClientContext* context, RDPGFX_END_FRAME_PDU* endFrame) { xfContext* xfc = (xfContext*) context->custom; - printf("xf_EndFrame: %d\n", endFrame->frameId); - - xf_SurfaceUpdate(xfc); + xf_OutputUpdate(xfc); xfc->inGfxFrame = FALSE; @@ -126,26 +151,20 @@ int xf_EndFrame(RdpgfxClientContext* context, RDPGFX_END_FRAME_PDU* endFrame) int xf_SurfaceCommand_Uncompressed(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { - BYTE* data; - XImage* image; + xfGfxSurface* surface; RECTANGLE_16 invalidRect; printf("xf_SurfaceCommand_Uncompressed\n"); - XSetFunction(xfc->display, xfc->gc, GXcopy); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); + surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); - data = (BYTE*) malloc(cmd->width * cmd->height * 4); + if (!surface) + return -1; - freerdp_image_flip(cmd->data, data, cmd->width, cmd->height, 32); + /* TODO: bitmap flipping in freerdp_image_copy */ - image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0, (char*) data, cmd->width, cmd->height, 32, 0); - - XPutImage(xfc->display, xfc->drawing, xfc->gc, image, 0, 0, cmd->left, cmd->top, cmd->width, cmd->height); - - XFree(image); - - free(data); + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, + cmd->width, cmd->height, cmd->data, PIXEL_FORMAT_XRGB32_VF, cmd->width * 4, 0, 0); invalidRect.left = cmd->left; invalidRect.top = cmd->top; @@ -154,10 +173,8 @@ int xf_SurfaceCommand_Uncompressed(xfContext* xfc, RdpgfxClientContext* context, region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); - XSetClipMask(xfc->display, xfc->gc, None); - if (!xfc->inGfxFrame) - xf_SurfaceUpdate(xfc); + xf_OutputUpdate(xfc); return 1; } @@ -165,15 +182,19 @@ int xf_SurfaceCommand_Uncompressed(xfContext* xfc, RdpgfxClientContext* context, int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { UINT16 index; - XImage* image; RFX_RECT* rect; RFX_TILE* tile; - XRectangle* xrects; + int nXDst, nYDst; + int nWidth, nHeight; RFX_MESSAGE* message; + xfGfxSurface* surface; RECTANGLE_16 invalidRect; RECTANGLE_16 surfaceRect; - printf("xf_SurfaceCommand_RemoteFX\n"); + surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); + + if (!surface) + return -1; surfaceRect.left = 0; surfaceRect.top = 0; @@ -185,20 +206,10 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP if (!message) return -1; - xrects = (XRectangle*) malloc(message->numRects * sizeof(XRectangle)); - - if (!xrects) - return -1; - for (index = 0; index < message->numRects; index++) { rect = &(message->rects[index]); - xrects[index].x = cmd->left + rect->x; - xrects[index].y = cmd->top + rect->y; - xrects[index].width = rect->width; - xrects[index].height = rect->height; - invalidRect.left = cmd->left + rect->x; invalidRect.top = cmd->top + rect->y; invalidRect.right = invalidRect.left + rect->width - 1; @@ -207,51 +218,47 @@ int xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDP region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); } - XSetFunction(xfc->display, xfc->gc, GXcopy); - XSetFillStyle(xfc->display, xfc->gc, FillSolid); - - XSetClipRectangles(xfc->display, xfc->gc, cmd->left, cmd->top, xrects, message->numRects, YXBanded); - for (index = 0; index < message->numTiles; index++) { tile = message->tiles[index]; - image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0, - (char*) tile->data, 64, 64, 32, 0); + nWidth = nHeight = 64; + nXDst = cmd->left + tile->x; + nYDst = cmd->top + tile->y; - XPutImage(xfc->display, xfc->drawable, xfc->gc, image, 0, 0, - cmd->left + tile->x, cmd->top + tile->y, 64, 64); + if ((nXDst + nWidth) > surface->width) + nWidth = surface->width - nXDst; - XFree(image); + if (nYDst + nHeight > surface->height) + nHeight = surface->height - nYDst; + + /* TODO: properly handle RemoteFX tile clipping */ + + freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, + nXDst, nYDst, nWidth, nHeight, + tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0); } - XSetClipMask(xfc->display, xfc->gc, None); - rfx_message_free(xfc->rfx, message); - free(xrects); if (!xfc->inGfxFrame) - xf_SurfaceUpdate(xfc); + xf_OutputUpdate(xfc); return 1; } int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { - printf("xf_SurfaceCommand_ClearCodec\n"); - if (!xfc->inGfxFrame) - xf_SurfaceUpdate(xfc); + xf_OutputUpdate(xfc); return 1; } int xf_SurfaceCommand_Planar(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { - printf("xf_SurfaceCommand_Planar\n"); - if (!xfc->inGfxFrame) - xf_SurfaceUpdate(xfc); + xf_OutputUpdate(xfc); return 1; } @@ -272,10 +279,12 @@ int xf_SurfaceCommand(RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) break; case RDPGFX_CODECID_CLEARCODEC: + printf("xf_SurfaceCommand_ClearCodec\n"); status = xf_SurfaceCommand_ClearCodec(xfc, context, cmd); break; case RDPGFX_CODECID_PLANAR: + printf("xf_SurfaceCommand_Planar\n"); status = xf_SurfaceCommand_Planar(xfc, context, cmd); break; @@ -301,6 +310,8 @@ int xf_SurfaceCommand(RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) int xf_DeleteEncodingContext(RdpgfxClientContext* context, RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext) { + printf("xf_DeleteEncodingContext\n"); + return 1; } @@ -322,7 +333,8 @@ int xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* cr surface->height = (UINT32) createSurface->height; surface->alpha = (createSurface->pixelFormat == PIXEL_FORMAT_ARGB_8888) ? TRUE : FALSE; - surface->data = (BYTE*) calloc(1, surface->width * surface->height * 4); + surface->scanline = surface->width * 4; + surface->data = (BYTE*) calloc(1, surface->scanline * surface->height); if (!surface->data) return -1; @@ -405,23 +417,78 @@ int xf_SolidFill(RdpgfxClientContext* context, RDPGFX_SOLID_FILL_PDU* solidFill) free(xrects); if (!xfc->inGfxFrame) - xf_SurfaceUpdate(xfc); + xf_OutputUpdate(xfc); return 1; } int xf_SurfaceToSurface(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_SURFACE_PDU* surfaceToSurface) { + UINT16 index; + int nWidth, nHeight; + RDPGFX_RECT16* rectSrc; + RDPGFX_POINT16* destPt; + RECTANGLE_16 invalidRect; + xfGfxSurface* surfaceSrc; + xfGfxSurface* surfaceDst; + xfContext* xfc = (xfContext*) context->custom; + + rectSrc = &(surfaceToSurface->rectSrc); + destPt = &surfaceToSurface->destPts[0]; + + printf("xf_SurfaceToSurface: srcId: %d dstId: %d rect: x: %d y: %d w: %d h: %d ptsCount: %d x: %d y: %d\n", + (int) surfaceToSurface->surfaceIdSrc, (int) surfaceToSurface->surfaceIdDest, + rectSrc->left, rectSrc->top, rectSrc->right - rectSrc->left, + rectSrc->bottom - rectSrc->top, (int) surfaceToSurface->destPtsCount, + destPt->x, destPt->y); + + surfaceSrc = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdSrc); + + if (surfaceToSurface->surfaceIdSrc != surfaceToSurface->surfaceIdDest) + surfaceDst = (xfGfxSurface*) context->GetSurfaceData(context, surfaceToSurface->surfaceIdDest); + else + surfaceDst = surfaceSrc; + + if (!surfaceSrc || !surfaceDst) + return -1; + + nWidth = rectSrc->right - rectSrc->left + 1; + nHeight = rectSrc->bottom - rectSrc->top + 1; + + for (index = 0; index < surfaceToSurface->destPtsCount; index++) + { + destPt = &surfaceToSurface->destPts[index]; + + /* TODO: copy overlap handling in freerdp_image_copy */ + + freerdp_image_copy(surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceDst->scanline, destPt->x, destPt->y, + nWidth, nHeight, surfaceDst->data, PIXEL_FORMAT_XRGB32, surfaceSrc->scanline, 0, 0); + + invalidRect.left = destPt->x; + invalidRect.top = destPt->y; + invalidRect.right = destPt->x + nWidth - 1; + invalidRect.bottom = destPt->y + nHeight - 1; + + region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); + } + + if (!xfc->inGfxFrame) + xf_OutputUpdate(xfc); + return 1; } int xf_SurfaceToCache(RdpgfxClientContext* context, RDPGFX_SURFACE_TO_CACHE_PDU* surfaceToCache) { + printf("xf_SurfaceToCache\n"); + return 1; } int xf_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface) { + printf("xf_CacheToSurface\n"); + return 1; } @@ -432,11 +499,20 @@ int xf_CacheImportReply(RdpgfxClientContext* context, RDPGFX_CACHE_IMPORT_REPLY_ int xf_EvictCacheEntry(RdpgfxClientContext* context, RDPGFX_EVICT_CACHE_ENTRY_PDU* evictCacheEntry) { + printf("xf_EvictCacheEntry\n"); + return 1; } int xf_MapSurfaceToOutput(RdpgfxClientContext* context, RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput) { + xfContext* xfc = (xfContext*) context->custom; + + printf("xf_MapSurfaceToOutput: surfaceId: %d outputOriginX: %d outputOriginY: %d\n", + surfaceToOutput->surfaceId, surfaceToOutput->outputOriginX, surfaceToOutput->outputOriginY); + + xfc->outputSurfaceId = surfaceToOutput->surfaceId; + return 1; } @@ -465,4 +541,6 @@ void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx) gfx->EvictCacheEntry = xf_EvictCacheEntry; gfx->MapSurfaceToOutput = xf_MapSurfaceToOutput; gfx->MapSurfaceToWindow = xf_MapSurfaceToWindow; + + region16_init(&(xfc->invalidRegion)); } diff --git a/client/X11/xf_gfx.h b/client/X11/xf_gfx.h index efc7c46dd..623df31b0 100644 --- a/client/X11/xf_gfx.h +++ b/client/X11/xf_gfx.h @@ -31,9 +31,12 @@ struct xf_gfx_surface BOOL alpha; BYTE* data; XImage* image; + int scanline; }; typedef struct xf_gfx_surface xfGfxSurface; +int xf_OutputExpose(xfContext* xfc, int x, int y, int width, int height); + void xf_register_graphics_pipeline(xfContext* xfc, RdpgfxClientContext* gfx); #endif /* __XF_GRAPHICS_PIPELINE_H */ diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 6f4394014..347d7c62f 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -113,6 +113,8 @@ struct xf_context BYTE* primary_buffer; REGION16 invalidRegion; BOOL inGfxFrame; + BOOL graphicsReset; + UINT16 outputSurfaceId; BOOL frame_begin; UINT16 frame_x1; diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index fc14f1518..489aab960 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -33,8 +33,8 @@ #define FREERDP_PIXEL_FLIP_VERTICAL 1 #define FREERDP_PIXEL_FLIP_HORIZONTAL 2 -#define FREERDP_PIXEL_FORMAT(_bpp, _type, _a, _r, _g, _b) \ - ((_bpp << 24) | (_type << 16) | (_a << 12) | (_r << 8) | (_g << 4) | (_b)) +#define FREERDP_PIXEL_FORMAT(_flip, _bpp, _type, _a, _r, _g, _b) \ + ((_flip << 30) | (_bpp << 24) | (_type << 16) | (_a << 12) | (_r << 8) | (_g << 4) | (_b)) #define FREERDP_PIXEL_FORMAT_FLIP(_format) (((_format) >> 30) & 0x02) #define FREERDP_PIXEL_FORMAT_BPP(_format) (((_format) >> 24) & 0x3F) @@ -54,84 +54,110 @@ /* 32bpp formats */ -#define PIXEL_FORMAT_A8R8G8B8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 8, 8, 8, 8) -#define PIXEL_FORMAT_ARGB32 PIXEL_FORMAT_A8R8G8B8 +#define PIXEL_FORMAT_A8R8G8B8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 8, 8, 8, 8) +#define PIXEL_FORMAT_A8R8G8B8 PIXEL_FORMAT_A8R8G8B8_F(0) +#define PIXEL_FORMAT_ARGB32 PIXEL_FORMAT_A8R8G8B8 +#define PIXEL_FORMAT_A8R8G8B8_VF PIXEL_FORMAT_A8R8G8B8_F(1) +#define PIXEL_FORMAT_ARGB32_VF PIXEL_FORMAT_A8R8G8B8_VF -#define PIXEL_FORMAT_X8R8G8B8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8) -#define PIXEL_FORMAT_XRGB32 PIXEL_FORMAT_X8R8G8B8 -#define PIXEL_FORMAT_RGB32 PIXEL_FORMAT_XRGB32 +#define PIXEL_FORMAT_X8R8G8B8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8) +#define PIXEL_FORMAT_X8R8G8B8 PIXEL_FORMAT_X8R8G8B8_F(0) +#define PIXEL_FORMAT_XRGB32 PIXEL_FORMAT_X8R8G8B8 +#define PIXEL_FORMAT_RGB32 PIXEL_FORMAT_XRGB32 +#define PIXEL_FORMAT_X8R8G8B8_VF PIXEL_FORMAT_X8R8G8B8_F(1) +#define PIXEL_FORMAT_XRGB32_VF PIXEL_FORMAT_X8R8G8B8_VF +#define PIXEL_FORMAT_RGB32_VF PIXEL_FORMAT_XRGB32_VF -#define PIXEL_FORMAT_A8B8G8R8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 8, 8, 8, 8) -#define PIXEL_FORMAT_ABGR32 PIXEL_FORMAT_A8B8G8R8 +#define PIXEL_FORMAT_A8B8G8R8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 8, 8, 8, 8) +#define PIXEL_FORMAT_A8B8G8R8 PIXEL_FORMAT_A8B8G8R8_F(0) +#define PIXEL_FORMAT_ABGR32 PIXEL_FORMAT_A8B8G8R8 +#define PIXEL_FORMAT_A8B8G8R8_VF PIXEL_FORMAT_A8B8G8R8_F(1) +#define PIXEL_FORMAT_ABGR32_VF PIXEL_FORMAT_A8B8G8R8_VF -#define PIXEL_FORMAT_X8B8G8R8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8) -#define PIXEL_FORMAT_XBGR32 PIXEL_FORMAT_X8B8G8R8 -#define PIXEL_FORMAT_BGR32 PIXEL_FORMAT_XBGR32 +#define PIXEL_FORMAT_X8B8G8R8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8) +#define PIXEL_FORMAT_X8B8G8R8 PIXEL_FORMAT_X8B8G8R8_F(0) +#define PIXEL_FORMAT_XBGR32 PIXEL_FORMAT_X8B8G8R8 +#define PIXEL_FORMAT_BGR32 PIXEL_FORMAT_XBGR32 +#define PIXEL_FORMAT_X8B8G8R8_VF PIXEL_FORMAT_X8B8G8R8_F(1) +#define PIXEL_FORMAT_XBGR32_VF PIXEL_FORMAT_X8B8G8R8_VF +#define PIXEL_FORMAT_BGR32_VF PIXEL_FORMAT_XBGR32_VF -#define PIXEL_FORMAT_B8G8R8A8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_BGRA, 8, 8, 8, 8) -#define PIXEL_FORMAT_BGRA32 PIXEL_FORMAT_B8G8R8A8 +#define PIXEL_FORMAT_B8G8R8A8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_BGRA, 8, 8, 8, 8) +#define PIXEL_FORMAT_B8G8R8A8 PIXEL_FORMAT_B8G8R8A8_F(0) +#define PIXEL_FORMAT_BGRA32 PIXEL_FORMAT_B8G8R8A8 +#define PIXEL_FORMAT_B8G8R8A8_VF PIXEL_FORMAT_B8G8R8A8_F(1) +#define PIXEL_FORMAT_BGRA32_VF PIXEL_FORMAT_B8G8R8A8_VF -#define PIXEL_FORMAT_B8G8R8X8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_BGRA, 0, 8, 8, 8) -#define PIXEL_FORMAT_BGRX32 PIXEL_FORMAT_B8G8R8X8 +#define PIXEL_FORMAT_B8G8R8X8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_BGRA, 0, 8, 8, 8) +#define PIXEL_FORMAT_B8G8R8X8 PIXEL_FORMAT_B8G8R8X8_F(0) +#define PIXEL_FORMAT_BGRX32 PIXEL_FORMAT_B8G8R8X8 +#define PIXEL_FORMAT_B8G8R8X8_VF PIXEL_FORMAT_B8G8R8X8_F(1) +#define PIXEL_FORMAT_BGRX32_VF PIXEL_FORMAT_B8G8R8X8_VF -#define PIXEL_FORMAT_R8G8B8A8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_RGBA, 8, 8, 8, 8) -#define PIXEL_FORMAT_RGBA32 PIXEL_FORMAT_R8G8B8A8 +#define PIXEL_FORMAT_R8G8B8A8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_RGBA, 8, 8, 8, 8) +#define PIXEL_FORMAT_R8G8B8A8 PIXEL_FORMAT_R8G8B8A8_F(0) +#define PIXEL_FORMAT_RGBA32 PIXEL_FORMAT_R8G8B8A8 +#define PIXEL_FORMAT_R8G8B8A8_VF PIXEL_FORMAT_R8G8B8A8_F(1) +#define PIXEL_FORMAT_RGBA32_VF PIXEL_FORMAT_R8G8B8A8_VF -#define PIXEL_FORMAT_R8G8B8X8 FREERDP_PIXEL_FORMAT(32, FREERDP_PIXEL_FORMAT_TYPE_RGBA, 0, 8, 8, 8) -#define PIXEL_FORMAT_RGBX32 PIXEL_FORMAT_R8G8B8X8 +#define PIXEL_FORMAT_R8G8B8X8_F(_flip) FREERDP_PIXEL_FORMAT(_flip, 32, FREERDP_PIXEL_FORMAT_TYPE_RGBA, 0, 8, 8, 8) +#define PIXEL_FORMAT_R8G8B8X8 PIXEL_FORMAT_R8G8B8X8_F(0) +#define PIXEL_FORMAT_RGBX32 PIXEL_FORMAT_R8G8B8X8 +#define PIXEL_FORMAT_R8G8B8X8_VF PIXEL_FORMAT_R8G8B8X8_F(1) +#define PIXEL_FORMAT_RGBX32_VF PIXEL_FORMAT_R8G8B8X8_VF /* 24bpp formats */ -#define PIXEL_FORMAT_R8G8B8 FREERDP_PIXEL_FORMAT(24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8) -#define PIXEL_FORMAT_RGB24 PIXEL_FORMAT_R8G8B8 +#define PIXEL_FORMAT_R8G8B8 FREERDP_PIXEL_FORMAT(0, 24, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 8, 8, 8) +#define PIXEL_FORMAT_RGB24 PIXEL_FORMAT_R8G8B8 -#define PIXEL_FORMAT_B8G8R8 FREERDP_PIXEL_FORMAT(24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8) -#define PIXEL_FORMAT_BGR24 PIXEL_FORMAT_B8G8R8 +#define PIXEL_FORMAT_B8G8R8 FREERDP_PIXEL_FORMAT(0, 24, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 8, 8, 8) +#define PIXEL_FORMAT_BGR24 PIXEL_FORMAT_B8G8R8 /* 16bpp formats */ -#define PIXEL_FORMAT_R5G6B5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5) -#define PIXEL_FORMAT_RGB565 PIXEL_FORMAT_R5G6B5 -#define PIXEL_FORMAT_RGB16 PIXEL_FORMAT_R5G6B5 +#define PIXEL_FORMAT_R5G6B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 6, 5) +#define PIXEL_FORMAT_RGB565 PIXEL_FORMAT_R5G6B5 +#define PIXEL_FORMAT_RGB16 PIXEL_FORMAT_R5G6B5 -#define PIXEL_FORMAT_B5G6R5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5) -#define PIXEL_FORMAT_BGR565 PIXEL_FORMAT_B5G6R5 -#define PIXEL_FORMAT_BGR16 PIXEL_FORMAT_B5G6R5 +#define PIXEL_FORMAT_B5G6R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 6, 5) +#define PIXEL_FORMAT_BGR565 PIXEL_FORMAT_B5G6R5 +#define PIXEL_FORMAT_BGR16 PIXEL_FORMAT_B5G6R5 -#define PIXEL_FORMAT_A1R5G5B5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5) -#define PIXEL_FORMAT_ARGB555 PIXEL_FORMAT_A1R5G5B5 -#define PIXEL_FORMAT_ARGB15 PIXEL_FORMAT_A1R5G5B5 +#define PIXEL_FORMAT_A1R5G5B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 1, 5, 5, 5) +#define PIXEL_FORMAT_ARGB555 PIXEL_FORMAT_A1R5G5B5 +#define PIXEL_FORMAT_ARGB15 PIXEL_FORMAT_A1R5G5B5 -#define PIXEL_FORMAT_X1R5G5B5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5) -#define PIXEL_FORMAT_XRGB555 PIXEL_FORMAT_X1R5G5B5 -#define PIXEL_FORMAT_RGB555 PIXEL_FORMAT_X1R5G5B5 -#define PIXEL_FORMAT_RGB15 PIXEL_FORMAT_X1R5G5B5 +#define PIXEL_FORMAT_X1R5G5B5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ARGB, 0, 5, 5, 5) +#define PIXEL_FORMAT_XRGB555 PIXEL_FORMAT_X1R5G5B5 +#define PIXEL_FORMAT_RGB555 PIXEL_FORMAT_X1R5G5B5 +#define PIXEL_FORMAT_RGB15 PIXEL_FORMAT_X1R5G5B5 -#define PIXEL_FORMAT_A1B5G5R5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5) -#define PIXEL_FORMAT_ABGR555 PIXEL_FORMAT_A1B5G5R5 -#define PIXEL_FORMAT_ABGR15 PIXEL_FORMAT_A1B5G5R5 +#define PIXEL_FORMAT_A1B5G5R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 1, 5, 5, 5) +#define PIXEL_FORMAT_ABGR555 PIXEL_FORMAT_A1B5G5R5 +#define PIXEL_FORMAT_ABGR15 PIXEL_FORMAT_A1B5G5R5 -#define PIXEL_FORMAT_X1B5G5R5 FREERDP_PIXEL_FORMAT(16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5) -#define PIXEL_FORMAT_XBGR555 PIXEL_FORMAT_X1B5G5R5 -#define PIXEL_FORMAT_BGR555 PIXEL_FORMAT_X1B5G5R5 -#define PIXEL_FORMAT_BGR15 PIXEL_FORMAT_X1B5G5R5 +#define PIXEL_FORMAT_X1B5G5R5 FREERDP_PIXEL_FORMAT(0, 16, FREERDP_PIXEL_FORMAT_TYPE_ABGR, 0, 5, 5, 5) +#define PIXEL_FORMAT_XBGR555 PIXEL_FORMAT_X1B5G5R5 +#define PIXEL_FORMAT_BGR555 PIXEL_FORMAT_X1B5G5R5 +#define PIXEL_FORMAT_BGR15 PIXEL_FORMAT_X1B5G5R5 /* 8bpp formats */ -#define PIXEL_FORMAT_A8 FREERDP_PIXEL_FORMAT(8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0) -#define PIXEL_FORMAT_8BPP PIXEL_FORMAT_A8 -#define PIXEL_FORMAT_256 PIXEL_FORMAT_A8 +#define PIXEL_FORMAT_A8 FREERDP_PIXEL_FORMAT(0, 8, FREERDP_PIXEL_FORMAT_TYPE_A, 8, 0, 0, 0) +#define PIXEL_FORMAT_8BPP PIXEL_FORMAT_A8 +#define PIXEL_FORMAT_256 PIXEL_FORMAT_A8 /* 4 bpp formats */ -#define PIXEL_FORMAT_A4 FREERDP_PIXEL_FORMAT(4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0) -#define PIXEL_FORMAT_4BPP PIXEL_FORMAT_A4 +#define PIXEL_FORMAT_A4 FREERDP_PIXEL_FORMAT(0, 4, FREERDP_PIXEL_FORMAT_TYPE_A, 4, 0, 0, 0) +#define PIXEL_FORMAT_4BPP PIXEL_FORMAT_A4 /* 1bpp formats */ -#define PIXEL_FORMAT_A1 FREERDP_PIXEL_FORMAT(1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0) -#define PIXEL_FORMAT_1BPP PIXEL_FORMAT_A1 -#define PIXEL_FORMAT_MONO PIXEL_FORMAT_A1 +#define PIXEL_FORMAT_A1 FREERDP_PIXEL_FORMAT(0, 1, FREERDP_PIXEL_FORMAT_TYPE_A, 1, 0, 0, 0) +#define PIXEL_FORMAT_1BPP PIXEL_FORMAT_A1 +#define PIXEL_FORMAT_MONO PIXEL_FORMAT_A1 #ifdef __cplusplus extern "C" { diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 69a871c84..2f2c88b02 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -1181,6 +1181,7 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs int srcBytesPerPixel; int dstBitsPerPixel; int dstBytesPerPixel; + BOOL overlap = FALSE; srcBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(dwSrcFormat); srcBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(dwSrcFormat) / 8); @@ -1188,6 +1189,12 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs dstBitsPerPixel = FREERDP_PIXEL_FORMAT_DEPTH(dwDstFormat); dstBytesPerPixel = (FREERDP_PIXEL_FORMAT_BPP(dwDstFormat) / 8); + if (pDstData == pSrcData) + { + overlap = (((nXDst + nWidth) > nXSrc) && (nXDst < (nXSrc + nWidth)) && + ((nYDst + nHeight) > nYSrc) && (nYDst < (nYSrc + nHeight))) ? TRUE : FALSE; + } + if (srcBytesPerPixel == 4) { if (nSrcStep < 0) @@ -1195,7 +1202,7 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs if (srcBitsPerPixel == 24) { - if (dstBytesPerPixel == 4) + if (dstBytesPerPixel == 4) /* srcBytesPerPixel == dstBytesPerPixel */ { if (dstBitsPerPixel == 32) { @@ -1223,7 +1230,7 @@ int freerdp_image_copy(BYTE* pDstData, DWORD dwDstFormat, int nDstStep, int nXDs pDstPixel = (UINT32*) &((BYTE*) pDstPixel)[(nDstStep - (nWidth * dstBytesPerPixel))]; } } - else if (dstBitsPerPixel == 24) + else if (dstBitsPerPixel == 24) /* srcBitsPerPixel == dstBitsPerPixel */ { UINT32* pSrcPixel; UINT32* pDstPixel;