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; invalidRect.bottom = y + height; region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); xf_OutputUpdate(xfc); return 1; }
static int test_r1_r6() { REGION16 region; int retCode = -1; const RECTANGLE_16 *rects; int nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r6 = {150, 121, 170, 131}; region16_init(®ion); /* * +=============================================================== * | * |+--------+ +--------+ * || r1 | | | * || +--+ | | | * || |r6| | =====> | | * || +--+ | | | * || | | | * |+--------+ +--------+ * | */ region16_clear(®ion); if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r6)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 1 || !compareRectangles(rects, &r1, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_AVC420(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; UINT32 i; xfGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_AVC420_BITMAP_STREAM* bs; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_AVC420, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; bs = (RDPGFX_AVC420_BITMAP_STREAM*) cmd->extra; if (!bs) return ERROR_INTERNAL_ERROR; meta = &(bs->meta); status = avc420_decompress(surface->codecs->h264, bs->data, bs->length, surface->data, surface->format, surface->scanline , surface->width, surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { WLog_WARN(TAG, "avc420_decompress failure: %d, ignoring update.", status); return CHANNEL_RC_OK; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &(meta->regionRects[i])); } if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int x11_shadow_invalidate_region(x11ShadowSubsystem* subsystem, int x, int y, int width, int height) { rdpShadowServer* server; RECTANGLE_16 invalidRect; server = subsystem->server; invalidRect.left = x; invalidRect.top = y; invalidRect.right = x + width; invalidRect.bottom = y + height; region16_union_rect(&(subsystem->invalidRegion), &(subsystem->invalidRegion), &invalidRect); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_AVC420(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { INT32 rc; UINT status = CHANNEL_RC_OK; UINT32 i; gdiGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_AVC420_BITMAP_STREAM* bs; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; bs = (RDPGFX_AVC420_BITMAP_STREAM*) cmd->extra; if (!bs) return ERROR_INTERNAL_ERROR; meta = &(bs->meta); rc = avc420_decompress(surface->codecs->h264, bs->data, bs->length, surface->data, surface->format, surface->scanline, surface->width, surface->height, meta->regionRects, meta->numRegionRects); if (rc < 0) { WLog_WARN(TAG, "avc420_decompress failure: %d, ignoring update.", status); return CHANNEL_RC_OK; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), (RECTANGLE_16*) & (meta->regionRects[i])); } if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y, UINT32 width, UINT32 height) { UINT16 count; UINT32 index; UINT status = CHANNEL_RC_OK; xfGfxSurface* surface; RECTANGLE_16 invalidRect; RECTANGLE_16 surfaceRect; RECTANGLE_16 intersection; UINT16* pSurfaceIds = NULL; RdpgfxClientContext* context = xfc->gfx; invalidRect.left = x; invalidRect.top = y; invalidRect.right = x + width; invalidRect.bottom = y + height; context->GetSurfaceIds(context, &pSurfaceIds, &count); for (index = 0; index < count; index++) { surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]); if (!surface || !surface->gdi.outputMapped) continue; surfaceRect.left = surface->gdi.outputOriginX; surfaceRect.top = surface->gdi.outputOriginY; surfaceRect.right = surface->gdi.outputOriginX + surface->gdi.width; surfaceRect.bottom = surface->gdi.outputOriginY + surface->gdi.height; if (rectangles_intersection(&invalidRect, &surfaceRect, &intersection)) { /* Invalid rects are specified relative to surface origin */ intersection.left -= surfaceRect.left; intersection.top -= surfaceRect.top; intersection.right -= surfaceRect.left; intersection.bottom -= surfaceRect.top; region16_union_rect(&surface->gdi.invalidRegion, &surface->gdi.invalidRegion, &intersection); } } free(pSurfaceIds); IFCALLRET(context->UpdateSurfaces, status, context); return status; }
int xf_SurfaceCommand_H264(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; UINT32 i; BYTE* DstData = NULL; H264_CONTEXT* h264; xfGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_H264); h264 = xfc->codecs->h264; bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; if (!bs) return -1; meta = &(bs->meta); surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = h264_decompress(xfc->codecs->h264, bs->data, bs->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline , surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { printf("h264_decompress failure: %d\n",status); return -1; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), (RECTANGLE_16*) &(meta->regionRects[i])); } if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT gdi_SurfaceCommand_H264(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; UINT32 i; BYTE* DstData = NULL; gdiGfxSurface* surface; RDPGFX_H264_METABLOCK* meta; RDPGFX_H264_BITMAP_STREAM* bs; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_H264)) return ERROR_INTERNAL_ERROR; bs = (RDPGFX_H264_BITMAP_STREAM*) cmd->extra; if (!bs) return ERROR_INTERNAL_ERROR; meta = &(bs->meta); DstData = surface->data; status = h264_decompress(surface->codecs->h264, bs->data, bs->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, surface->width, surface->height, meta->regionRects, meta->numRegionRects); if (status < 0) { WLog_WARN(TAG, "h264_decompress failure: %d, ignoring update.", status); return CHANNEL_RC_OK; } for (i = 0; i < meta->numRegionRects; i++) { region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), (RECTANGLE_16*) &(meta->regionRects[i])); } if (!gdi->inGfxFrame) gdi_UpdateSurfaces(gdi); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SolidFill(RdpgfxClientContext* context, RDPGFX_SOLID_FILL_PDU* solidFill) { UINT16 index; UINT32 color; BYTE a, r, g, b; int nWidth, nHeight; RECTANGLE_16* rect; xfGfxSurface* surface; RECTANGLE_16 invalidRect; xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) context->GetSurfaceData(context, solidFill->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; b = solidFill->fillPixel.B; g = solidFill->fillPixel.G; r = solidFill->fillPixel.R; a = solidFill->fillPixel.XA; color = ARGB32(a, r, g, b); for (index = 0; index < solidFill->fillRectCount; index++) { rect = &(solidFill->fillRects[index]); nWidth = rect->right - rect->left; nHeight = rect->bottom - rect->top; invalidRect.left = rect->left; invalidRect.top = rect->top; invalidRect.right = rect->right; invalidRect.bottom = rect->bottom; freerdp_image_fill(surface->data, surface->format, surface->scanline, rect->left, rect->top, nWidth, nHeight, color); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); } if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom) { REGION16 invalidRegion; RECTANGLE_16 invalidRect; invalidRect.left = uleft; invalidRect.top = utop; invalidRect.right = uright; invalidRect.bottom = ubottom; region16_init(&invalidRegion); region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect); xf_rail_invalidate_region(xfc, &invalidRegion); region16_uninit(&invalidRegion); }
static int test_r1_inter_r3(void) { REGION16 region, intersection; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; RECTANGLE_16 r1_inter_r3[] = { {150, 151, 200, 201}, }; region16_init(®ion); region16_init(&intersection); /* * +=============================================================== * | * |+-----+ * || r1 | * || +-+------+ +-+ * || | r3 | r1&r3 | | * |+---+ | ====> +-+ * | | | * | +--------+ */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_intersects_rect(®ion, &r3)) goto out; if (!region16_intersect_rect(&intersection, ®ion, &r3)) goto out; rects = region16_rects(&intersection, &nbRects); if (!rects || nbRects != 1 || !compareRectangles(rects, r1_inter_r3, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); region16_uninit(&intersection); return retCode; }
static int test_norbert_case() { REGION16 region, intersection; int retCode = -1; const RECTANGLE_16 *rects; int nbRects, i; RECTANGLE_16 inRectangles[5] = { {1680, 0, 1920, 242}, { 294, 242, 971, 776}, {1680, 242, 1920, 776}, {1680, 776, 1920, 1036}, { 2, 1040, 53, 1078} }; RECTANGLE_16 screenRect = { 0, 0, 1920, 1080 }; RECTANGLE_16 expected_inter_extents = { 0, 0, 1920, 1078 }; region16_init(®ion); region16_init(&intersection); for (i = 0; i < 5; i++) { if (!region16_union_rect(®ion, ®ion, &inRectangles[i])) goto out; } if (!region16_intersect_rect(&intersection, ®ion, &screenRect)) goto out; rects = region16_rects(&intersection, &nbRects); if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects)) goto out; if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1) ) goto out; retCode = 0; out: region16_uninit(&intersection); region16_uninit(®ion); return retCode; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { INT32 rc; UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } rc = clear_decompress(surface->codecs->clear, cmd->data, cmd->length, cmd->width, cmd->height, surface->data, surface->format, surface->scanline, cmd->left, cmd->top, surface->width, surface->height, &gdi->palette); if (rc < 0) { WLog_ERR(TAG, "clear_decompress failure: %"PRId32"", rc); return ERROR_INTERNAL_ERROR; } invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, 1, &invalidRect); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; REGION16 invalidRegion; const RECTANGLE_16* rects; UINT32 nrRects, x; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } rfx_context_set_pixel_format(surface->codecs->rfx, cmd->format); region16_init(&invalidRegion); if (!rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length, cmd->left, cmd->top, surface->data, surface->format, surface->scanline, surface->height, &invalidRegion)) { WLog_ERR(TAG, "Failed to process RemoteFX message"); region16_uninit(&invalidRegion); return ERROR_INTERNAL_ERROR; } rects = region16_rects(&invalidRegion, &nrRects); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, nrRects, rects); for (x=0; x<nrRects; x++) region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &rects[x]); region16_uninit(&invalidRegion); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
int win_shadow_invalidate_region(winShadowSubsystem* subsystem, int x, int y, int width, int height) { rdpShadowServer* server; rdpShadowSurface* surface; RECTANGLE_16 invalidRect; server = subsystem->server; surface = server->surface; invalidRect.left = x; invalidRect.top = y; invalidRect.right = x + width; invalidRect.bottom = y + height; EnterCriticalSection(&(surface->lock)); region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); LeaveCriticalSection(&(surface->lock)); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_CacheToSurface(RdpgfxClientContext* context, const RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface) { UINT status = CHANNEL_RC_OK; UINT16 index; RDPGFX_POINT16* destPt; gdiGfxSurface* surface; gdiGfxCacheEntry* cacheEntry; RECTANGLE_16 invalidRect; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId); cacheEntry = (gdiGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot); if (!surface || !cacheEntry) return ERROR_INTERNAL_ERROR; for (index = 0; index < cacheToSurface->destPtsCount; index++) { destPt = &cacheToSurface->destPts[index]; if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, destPt->x, destPt->y, cacheEntry->width, cacheEntry->height, cacheEntry->data, cacheEntry->format, cacheEntry->scanline, 0, 0, NULL, FREERDP_FLIP_NONE)) return ERROR_INTERNAL_ERROR; invalidRect.left = destPt->x; invalidRect.top = destPt->y; invalidRect.right = destPt->x + cacheEntry->width; invalidRect.bottom = destPt->y + cacheEntry->height; region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, 1, &invalidRect); } if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
int shadow_client_surface_update(rdpShadowClient* client, REGION16* region) { int index; int numRects = 0; const RECTANGLE_16* rects; EnterCriticalSection(&(client->lock)); rects = region16_rects(region, &numRects); for (index = 0; index < numRects; index++) { region16_union_rect(&(client->invalidRegion), &(client->invalidRegion), &rects[index]); } LeaveCriticalSection(&(client->lock)); return 1; }
static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region, int width, int height) { int i; const RFX_RECT *rect = rects; const RECTANGLE_16 mainRect = { 0, 0, width, height }; for(i = 0; i < numRects; i++, rect++) { RECTANGLE_16 rect16; rect16.left = rect->x; rect16.top = rect->y; rect16.right = rect->x + rect->width; rect16.bottom = rect->y + rect->height; if (!region16_union_rect(region, region, &rect16)) return FALSE; } return region16_intersect_rect(region, region, &mainRect); }
int shadow_client_init_lobby(rdpShadowClient* client) { int width; int height; rdtkEngine* engine; rdtkSurface* surface; RECTANGLE_16 invalidRect; rdpShadowSurface* lobby; rdpContext* context = (rdpContext*) client; rdpSettings* settings = context->settings; width = settings->DesktopWidth; height = settings->DesktopHeight; lobby = client->lobby = shadow_surface_new(client->server, 0, 0, width, height); if (!client->lobby) return -1; engine = rdtk_engine_new(); surface = rdtk_surface_new(engine, lobby->data, lobby->width, lobby->height, lobby->scanline); rdtk_surface_fill(surface, 0, 0, width, height, 0x3BB9FF); //rdtk_label_draw(surface, 16, 16, 128, 32, NULL, "label", 0, 0); //rdtk_button_draw(surface, 16, 64, 128, 32, NULL, "button"); //rdtk_text_field_draw(surface, 16, 128, 128, 32, NULL, "text field"); rdtk_surface_free(surface); rdtk_engine_free(engine); invalidRect.left = 0; invalidRect.top = 0; invalidRect.right = width; invalidRect.bottom = height; region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect); return 1; }
UwacReturnCode UwacWindowAddDamage(UwacWindow* window, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { #ifdef HAVE_PIXMAN_REGION if (!pixman_region32_union_rect(&window->drawingBuffer->damage, &window->drawingBuffer->damage, x, y, width, height)) #else RECTANGLE_16 box; box.left = x; box.top = y; box.right = x + width; box.bottom = y + height; if (!region16_union_rect(&window->drawingBuffer->damage, &window->drawingBuffer->damage, &box)) #endif return UWAC_ERROR_INTERNAL; return UWAC_SUCCESS; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { UINT status = CHANNEL_RC_OK; UINT32 color; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } WLog_WARN(TAG, "TODO gdi_SurfaceCommand_Alpha: status: %"PRIu32"", status); /* fill with green for now to distinguish from the rest */ color = GetColor(surface->format, 0x00, 0xFF, 0x00, 0xFF); if (!freerdp_image_fill(surface->data, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, color)) return ERROR_INTERNAL_ERROR; invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, 1, &invalidRect); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC, xfc->settings->DesktopWidth, xfc->settings->DesktopHeight)) return ERROR_INTERNAL_ERROR; DstData = surface->data; status = clear_decompress(xfc->codecs->clear, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); if (status < 0) { WLog_ERR(TAG, "clear_decompress failure: %d", status); return ERROR_INTERNAL_ERROR; } invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int xf_SurfaceCommand_ClearCodec(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; xfGfxSurface* surface; RECTANGLE_16 invalidRect; freerdp_client_codecs_prepare(xfc->codecs, FREERDP_CODEC_CLEARCODEC); surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = clear_decompress(xfc->codecs->clear, cmd->data, cmd->length, &DstData, PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); if (status < 0) { printf("clear_decompress failure: %d\n", status); return -1; } invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); return 1; }
int gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int status; BYTE* DstData = NULL; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_CLEARCODEC); surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; DstData = surface->data; status = clear_decompress(gdi->codecs->clear, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height); if (status < 0) { WLog_ERR(TAG, "clear_decompress failure: %d", status); return -1; } invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect); if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { UINT status = CHANNEL_RC_OK; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) { WLog_ERR(TAG, "%s: unable to retrieve surfaceData for surfaceId=%"PRIu32"", __FUNCTION__, cmd->surfaceId); return ERROR_NOT_FOUND; } if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->data, cmd->format, 0, 0, 0, NULL, FREERDP_FLIP_NONE)) return ERROR_INTERNAL_ERROR; invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); IFCALL(context->UpdateSurfaceArea, context, surface->surfaceId, 1, &invalidRect); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface) { UINT16 index; RDPGFX_POINT16* destPt; xfGfxSurface* surface; xfGfxCacheEntry* cacheEntry; RECTANGLE_16 invalidRect; xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId); cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot); if (!surface || !cacheEntry) return ERROR_INTERNAL_ERROR; for (index = 0; index < cacheToSurface->destPtsCount; index++) { destPt = &cacheToSurface->destPts[index]; freerdp_image_copy(surface->data, surface->format, surface->scanline, destPt->x, destPt->y, cacheEntry->width, cacheEntry->height, cacheEntry->data, cacheEntry->format, cacheEntry->scanline, 0, 0, NULL); invalidRect.left = destPt->x; invalidRect.top = destPt->y; invalidRect.right = destPt->x + cacheEntry->width - 1; invalidRect.bottom = destPt->y + cacheEntry->height - 1; region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &invalidRect); } if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int xf_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface) { UINT16 index; RDPGFX_POINT16* destPt; xfGfxSurface* surface; xfGfxCacheEntry* cacheEntry; RECTANGLE_16 invalidRect; xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId); cacheEntry = (xfGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot); if (!surface || !cacheEntry) return -1; for (index = 0; index < cacheToSurface->destPtsCount; index++) { destPt = &cacheToSurface->destPts[index]; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, destPt->x, destPt->y, cacheEntry->width, cacheEntry->height, cacheEntry->data, PIXEL_FORMAT_XRGB32, cacheEntry->scanline, 0, 0); invalidRect.left = destPt->x; invalidRect.top = destPt->y; invalidRect.right = destPt->x + cacheEntry->width - 1; invalidRect.bottom = destPt->y + cacheEntry->height - 1; region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect); } if (!xfc->inGfxFrame) xf_OutputUpdate(xfc); return 1; }
int gdi_CacheToSurface(RdpgfxClientContext* context, RDPGFX_CACHE_TO_SURFACE_PDU* cacheToSurface) { UINT16 index; RDPGFX_POINT16* destPt; gdiGfxSurface* surface; gdiGfxCacheEntry* cacheEntry; RECTANGLE_16 invalidRect; rdpGdi* gdi = (rdpGdi*) context->custom; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cacheToSurface->surfaceId); cacheEntry = (gdiGfxCacheEntry*) context->GetCacheSlotData(context, cacheToSurface->cacheSlot); if (!surface || !cacheEntry) return -1; for (index = 0; index < cacheToSurface->destPtsCount; index++) { destPt = &cacheToSurface->destPts[index]; freerdp_image_copy(surface->data, surface->format, surface->scanline, destPt->x, destPt->y, cacheEntry->width, cacheEntry->height, cacheEntry->data, cacheEntry->format, cacheEntry->scanline, 0, 0, NULL); invalidRect.left = destPt->x; invalidRect.top = destPt->y; invalidRect.right = destPt->x + cacheEntry->width - 1; invalidRect.bottom = destPt->y + cacheEntry->height - 1; region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &invalidRect); } if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context, const RDPGFX_SURFACE_COMMAND* cmd) { UINT status = CHANNEL_RC_OK; BYTE* DstData = NULL; gdiGfxSurface* surface; RECTANGLE_16 invalidRect; surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; DstData = surface->data; if (!planar_decompress(surface->codecs->planar, cmd->data, cmd->length, cmd->width, cmd->height, DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, FALSE)) return ERROR_INTERNAL_ERROR; invalidRect.left = cmd->left; invalidRect.top = cmd->top; invalidRect.right = cmd->right; invalidRect.bottom = cmd->bottom; region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); if (!gdi->inGfxFrame) { status = CHANNEL_RC_NOT_INITIALIZED; IFCALLRET(context->UpdateSurfaces, status, context); } return status; }
int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem) { int count; int status; int x, y; int width, height; XImage* image; rdpShadowScreen* screen; rdpShadowServer* server; rdpShadowSurface* surface; RECTANGLE_16 invalidRect; RECTANGLE_16 surfaceRect; const RECTANGLE_16 *extents; server = subsystem->server; surface = server->surface; screen = server->screen; count = ArrayList_Count(server->clients); if (count < 1) return 1; surfaceRect.left = 0; surfaceRect.top = 0; surfaceRect.right = surface->width; surfaceRect.bottom = surface->height; XLockDisplay(subsystem->display); /* * Ignore BadMatch error during image capture. The screen size may be * changed outside. We will resize to correct resolution at next frame */ XSetErrorHandler(x11_shadow_error_handler_for_capture); if (subsystem->use_xshm) { image = subsystem->fb_image; XCopyArea(subsystem->display, subsystem->root_window, subsystem->fb_pixmap, subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0); status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) &(image->data[surface->width * 4]), image->bytes_per_line, &invalidRect); } else { image = XGetImage(subsystem->display, subsystem->root_window, surface->x, surface->y, surface->width, surface->height, AllPlanes, ZPixmap); if (!image) { /* * BadMatch error happened. The size may have been changed again. * Give up this frame and we will resize again in next frame */ goto fail_capture; } status = shadow_capture_compare(surface->data, surface->scanline, surface->width, surface->height, (BYTE*) image->data, image->bytes_per_line, &invalidRect); } /* Restore the default error handler */ XSetErrorHandler(NULL); XSync(subsystem->display, False); XUnlockDisplay(subsystem->display); region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect); region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect); if (!region16_is_empty(&(surface->invalidRegion))) { extents = region16_extents(&(surface->invalidRegion)); x = extents->left; y = extents->top; width = extents->right - extents->left; height = extents->bottom - extents->top; freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, x, y, width, height, (BYTE*) image->data, PIXEL_FORMAT_XRGB32, image->bytes_per_line, x, y, NULL); //x11_shadow_blend_cursor(subsystem); count = ArrayList_Count(server->clients); shadow_subsystem_frame_update((rdpShadowSubsystem *)subsystem); if (count == 1) { rdpShadowClient* client; client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0); if (client) { subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder); } } region16_clear(&(surface->invalidRegion)); } if (!subsystem->use_xshm) XDestroyImage(image); return 1; fail_capture: XSetErrorHandler(NULL); XSync(subsystem->display, False); XUnlockDisplay(subsystem->display); return 0; }