static int test_empty_rectangle(void) { REGION16 region, intersection; int retCode = -1; int i; RECTANGLE_16 emptyRectangles[3] = { { 0, 0, 0, 0}, { 10, 10, 10, 11}, { 10, 10, 11, 10} }; RECTANGLE_16 firstRect = { 0, 0, 100, 100 }; RECTANGLE_16 anotherRect = { 100, 100, 200, 200 }; RECTANGLE_16 expected_inter_extents = { 0, 0, 0, 0 }; region16_init(®ion); region16_init(&intersection); /* Check for empty rectangles */ for (i = 0; i < 3; i++) { if (!rectangle_is_empty(&emptyRectangles[i])) goto out; } /* Check for non-empty rectangles */ if (rectangle_is_empty(&firstRect)) goto out; /* Intersect 2 non-intersect rectangle, result should be empty */ if (!region16_union_rect(®ion, ®ion, &firstRect)) goto out; if (!region16_intersect_rect(®ion, ®ion, &anotherRect)) goto out; if (!compareRectangles(region16_extents(®ion), &expected_inter_extents, 1)) goto out; if (!region16_is_empty(®ion)) goto out; if (!rectangle_is_empty(region16_extents(&intersection))) goto out; retCode = 0; out: region16_uninit(&intersection); region16_uninit(®ion); return retCode; }
static int test_r1_r3_inter_r11(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 r11 = {170, 151, 600, 301}; RECTANGLE_16 r1_r3_inter_r11[] = { {170, 151, 250, 251}, }; region16_init(®ion); region16_init(&intersection); /* * +=============================================================== * | * |+-----+ * || | * || +------+ * || r1+r3 | (r1+r3) & r11 * || +----------------+ +--------+ * |+---+ | | | ====> | | * | | | | | | | * | | | | | | | * | +-|------+ | +--------+ * | | r11 | * | +----------------+ * * * R1+R3 is made of 3 bands, R11 overlap the second and the third band. The * intersection is made of two band that must be reassembled to give only * one */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r3)) goto out; if (!region16_intersects_rect(®ion, &r11)) goto out; if (!region16_intersect_rect(&intersection, ®ion, &r11)) goto out; rects = region16_rects(&intersection, &nbRects); if (!rects || nbRects != 1 || !compareRectangles(rects, r1_r3_inter_r11, nbRects)) goto out; retCode = 0; out: region16_uninit(&intersection); region16_uninit(®ion); return retCode; }
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx) { region16_uninit(&(xfc->invalidRegion)); gfx->custom = NULL; xfc->gfx = NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { rdpCodecs* codecs = NULL; xfGfxSurface* surface = NULL; surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); if (surface) { XFree(surface->image); _aligned_free(surface->data); _aligned_free(surface->stage); region16_uninit(&surface->invalidRegion); codecs = surface->codecs; free(surface); } context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); if (codecs && codecs->progressive) progressive_delete_surface_context(codecs->progressive, deleteSurface->surfaceId); codecs_free(codecs); return CHANNEL_RC_OK; }
void gdi_graphics_pipeline_uninit(rdpGdi* gdi, RdpgfxClientContext* gfx) { region16_uninit(&(gdi->invalidRegion)); gdi->gfx = NULL; gfx->custom = NULL; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_DeleteSurface(RdpgfxClientContext* context, const RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { rdpCodecs* codecs = NULL; xfGfxSurface* surface = NULL; UINT status; EnterCriticalSection(&context->mux); surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); if (surface) { #ifdef WITH_GFX_H264 h264_context_free(surface->gdi.h264); #endif surface->image->data = NULL; XDestroyImage(surface->image); _aligned_free(surface->gdi.data); _aligned_free(surface->stage); region16_uninit(&surface->gdi.invalidRegion); codecs = surface->gdi.codecs; free(surface); } status = context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); if (codecs && codecs->progressive) progressive_delete_surface_context(codecs->progressive, deleteSurface->surfaceId); LeaveCriticalSection(&context->mux); return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT gdi_DeleteSurface(RdpgfxClientContext* context, const RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { rdpCodecs* codecs = NULL; gdiGfxSurface* surface = NULL; surface = (gdiGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); if (surface) { #ifdef WITH_GFX_H264 h264_context_free(surface->h264); #endif region16_uninit(&surface->invalidRegion); codecs = surface->codecs; _aligned_free(surface->data); free(surface); } context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); if (codecs && codecs->progressive) progressive_delete_surface_context(codecs->progressive, deleteSurface->surfaceId); return CHANNEL_RC_OK; }
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_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; }
static int test_from_weston(void) { /* * 0: 0,0 -> 640,32 (w=640 h=32) * 1: 236,169 -> 268,201 (w=32 h=32) * 2: 246,258 -> 278,290 (w=32 h=32) */ REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 0, 640, 32}; RECTANGLE_16 r2 = {236, 169, 268, 201}; RECTANGLE_16 r3 = {246, 258, 278, 290}; RECTANGLE_16 r1_r2_r3[] = { { 0, 0, 640, 32}, {236, 169, 268, 201}, {246, 258, 278, 290} }; region16_init(®ion); /* * +=============================================================== * |+-------------------------------------------------------------+ * || r1 | * |+-------------------------------------------------------------+ * | * | +---------------+ * | | r2 | * | +---------------+ * | * | +---------------+ * | | r3 | * | +---------------+ * | */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r2)) goto out; if (!region16_union_rect(®ion, ®ion, &r3)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
static int test_r1_r2_r4(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; RECTANGLE_16 r4 = {150, 251, 250, 301}; RECTANGLE_16 r1_r2_r4[] = { { 0, 101, 200, 201}, {150, 251, 250, 401} }; /* * +=============================================================== * | * |+-----+ +-----+ * || r1 | | | * || | | | * || | | | * |+-----+ ====> +-----+ * | * | +--------+ +--------+ * | | r4 | | | * | +--------+ | | * | | r2 | | | * | | | | | * | +--------+ +--------+ * */ region16_init(®ion); if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r2)) goto out; if (!region16_union_rect(®ion, ®ion, &r4)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2_r4, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
static int test_r1_r3() { REGION16 region; int retCode = -1; const RECTANGLE_16 *rects; int nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r3 = {150, 151, 250, 251}; RECTANGLE_16 r1_r3[] = { { 0, 101, 200, 151}, { 0, 151, 250, 201}, {150, 201, 250, 251} }; region16_init(®ion); /* * +=============================================================== * | * |+-----+ +-----+ * || r1 | | | * || +-+------+ +-----+--------+ * || | r3 | | | * |+---+ | ====> +-----+--------+ * | | | | | * | +--------+ +--------+ */ /* R1 + R3 */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r3)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) goto out; /* R3 + R1 */ region16_clear(®ion); if (!region16_union_rect(®ion, ®ion, &r3)) goto out; if (!region16_union_rect(®ion, ®ion, &r1)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
void shadow_surface_free(rdpShadowSurface* surface) { if (!surface) return; free(surface->data); DeleteCriticalSection(&(surface->lock)); region16_uninit(&(surface->invalidRegion)); free(surface); }
int xf_ResetGraphics(RdpgfxClientContext* context, RDPGFX_RESET_GRAPHICS_PDU* resetGraphics) { xfContext* xfc = (xfContext*) context->custom; freerdp_client_codecs_reset(xfc->codecs, FREERDP_CODEC_ALL); region16_uninit(&(xfc->invalidRegion)); region16_init(&(xfc->invalidRegion)); xfc->graphicsReset = TRUE; return 1; }
void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion) { int index; int count; RECTANGLE_16 updateRect; RECTANGLE_16 windowRect; ULONG_PTR* pKeys = NULL; xfAppWindow* appWindow; const RECTANGLE_16* extents; REGION16 windowInvalidRegion; region16_init(&windowInvalidRegion); count = HashTable_GetKeys(xfc->railWindows, &pKeys); for (index = 0; index < count; index++) { appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]); if (appWindow) { windowRect.left = MAX(appWindow->x, 0); windowRect.top = MAX(appWindow->y, 0); windowRect.right = MAX(appWindow->x + appWindow->width, 0); windowRect.bottom = MAX(appWindow->y + appWindow->height, 0); region16_clear(&windowInvalidRegion); region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect); if (!region16_is_empty(&windowInvalidRegion)) { extents = region16_extents(&windowInvalidRegion); updateRect.left = extents->left - appWindow->x; updateRect.top = extents->top - appWindow->y; updateRect.right = extents->right - appWindow->x; updateRect.bottom = extents->bottom - appWindow->y; if (appWindow) { xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top, updateRect.right - updateRect.left, updateRect.bottom - updateRect.top); } } } } region16_uninit(&windowInvalidRegion); }
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); }
BOOL wf_sw_end_paint(wfContext* wfc) { int i; rdpGdi* gdi; int ninvalid; RECT updateRect; HGDI_RGN cinvalid; REGION16 invalidRegion; RECTANGLE_16 invalidRect; const RECTANGLE_16* extents; rdpContext* context = (rdpContext*) wfc; gdi = context->gdi; ninvalid = gdi->primary->hdc->hwnd->ninvalid; cinvalid = gdi->primary->hdc->hwnd->cinvalid; if (ninvalid < 1) return TRUE; region16_init(&invalidRegion); for (i = 0; i < ninvalid; i++) { invalidRect.left = cinvalid[i].x; invalidRect.top = cinvalid[i].y; invalidRect.right = cinvalid[i].x + cinvalid[i].w; invalidRect.bottom = cinvalid[i].y + cinvalid[i].h; region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect); } if (!region16_is_empty(&invalidRegion)) { extents = region16_extents(&invalidRegion); updateRect.left = extents->left; updateRect.top = extents->top; updateRect.right = extents->right; updateRect.bottom = extents->bottom; InvalidateRect(wfc->hwnd, &updateRect, FALSE); if (wfc->rail) wf_rail_invalidate_region(wfc, &invalidRegion); } region16_uninit(&invalidRegion); return TRUE; }
void shadow_screen_free(rdpShadowScreen* screen) { if (!screen) return; DeleteCriticalSection(&(screen->lock)); region16_uninit(&(screen->invalidRegion)); if (screen->primary) { shadow_surface_free(screen->primary); screen->primary = NULL; } free(screen); }
static int test_basic(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; /* R1 + R2 ==> disjointed rects */ RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r2 = {150, 301, 250, 401}; RECTANGLE_16 r1_r2[] = { {0, 101, 200, 201}, {150, 301, 250, 401} }; /* r1 */ region16_init(®ion); if (!region16_union_rect(®ion, ®ion, &r1)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16))) goto out; /* r1 + r2 */ if (!region16_union_rect(®ion, ®ion, &r2)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects)) goto out; /* clear region */ region16_clear(®ion); region16_rects(®ion, &nbRects); if (nbRects) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
static int test_r9_r10(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; /* * +=============================================================== * | * | +---+ +---+ * |+--|r10|-+ +--+---+-+ * ||r9| | | | | * || | | | | | * || | | | =====> | | * || | | | | | * || | | | | | * |+--| |-+ +--+---+-+ * | +---+ +---+ */ RECTANGLE_16 r9 = { 0, 100, 400, 200}; RECTANGLE_16 r10 = {200, 0, 300, 300}; RECTANGLE_16 r9_r10[] = { {200, 0, 300, 100}, { 0, 100, 400, 200}, {200, 200, 300, 300}, }; region16_init(®ion); if (!region16_union_rect(®ion, ®ion, &r9)) goto out; if (!region16_union_rect(®ion, ®ion, &r10)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r9_r10, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
static int test_r1_r5(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 nbRects; RECTANGLE_16 r1 = { 0, 101, 200, 201}; RECTANGLE_16 r5 = {150, 121, 300, 131}; RECTANGLE_16 r1_r5[] = { { 0, 101, 200, 121}, { 0, 121, 300, 131}, { 0, 131, 200, 201} }; region16_init(®ion); /* * +=============================================================== * | * |+--------+ +--------+ * || r1 | | | * || +--+----+ +--------+----+ * || | r5 | =====> | | * || +-------+ +--------+----+ * || | | | * |+--------+ +--------+ * | * */ if (!region16_union_rect(®ion, ®ion, &r1)) goto out; if (!region16_union_rect(®ion, ®ion, &r5)) goto out; rects = region16_rects(®ion, &nbRects); if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects)) goto out; retCode = 0; out: region16_uninit(®ion); return retCode; }
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion) { int index; int count; RECT updateRect; RECTANGLE_16 windowRect; ULONG_PTR* pKeys = NULL; wfRailWindow* railWindow; const RECTANGLE_16* extents; REGION16 windowInvalidRegion; region16_init(&windowInvalidRegion); count = HashTable_GetKeys(wfc->railWindows, &pKeys); for (index = 0; index < count; index++) { railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows, (void*) pKeys[index]); if (railWindow) { windowRect.left = railWindow->x; windowRect.top = railWindow->y; windowRect.right = railWindow->x + railWindow->width; windowRect.bottom = railWindow->y + railWindow->height; region16_clear(&windowInvalidRegion); region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect); if (!region16_is_empty(&windowInvalidRegion)) { extents = region16_extents(&windowInvalidRegion); updateRect.left = extents->left - railWindow->x; updateRect.top = extents->top - railWindow->y; updateRect.right = extents->right - railWindow->x; updateRect.bottom = extents->bottom - railWindow->y; InvalidateRect(railWindow->hWnd, &updateRect, FALSE); } } } region16_uninit(&windowInvalidRegion); }
void UwacWindowDestroyBuffers(UwacWindow* w) { int i; for (i = 0; i < w->nbuffers; i++) { UwacBuffer* buffer = &w->buffers[i]; #ifdef HAVE_PIXMAN_REGION pixman_region32_fini(&buffer->damage); #else region16_uninit(&buffer->damage); #endif wl_buffer_destroy(buffer->wayland_buffer); } w->nbuffers = 0; free(w->buffers); w->buffers = NULL; }
void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client) { rdpShadowServer* server = client->server; ArrayList_Remove(server->clients, (void*) client); DeleteCriticalSection(&(client->lock)); region16_uninit(&(client->invalidRegion)); WTSCloseServer((HANDLE) client->vcm); /* Clear queued messages and free resource */ MessageQueue_Clear(client->MsgQueue); MessageQueue_Free(client->MsgQueue); if (client->encoder) { shadow_encoder_free(client->encoder); client->encoder = NULL; } }
static int test_r1_r6(void) { REGION16 region; int retCode = -1; const RECTANGLE_16* rects; UINT32 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; }
int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface) { xfGfxSurface* surface = NULL; xfContext* xfc = (xfContext*) context->custom; surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId); if (surface) { XFree(surface->image); _aligned_free(surface->data); _aligned_free(surface->stage); region16_uninit(&surface->invalidRegion); free(surface); } context->SetSurfaceData(context, deleteSurface->surfaceId, NULL); if (xfc->codecs->progressive) progressive_delete_surface_context(xfc->codecs->progressive, deleteSurface->surfaceId); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int i, j; int status; BYTE* DstData; RFX_RECT* rect; int nXDst, nYDst; int nXSrc, nYSrc; int nWidth, nHeight; int nbUpdateRects; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; RFX_PROGRESSIVE_TILE* tile; PROGRESSIVE_BLOCK_REGION* region; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_PROGRESSIVE, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId, surface->width, surface->height); DstData = surface->data; status = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, &DstData, surface->format, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId); if (status < 0) { WLog_ERR(TAG, "progressive_decompress failure: %d", status); return ERROR_INTERNAL_ERROR; } region = &(surface->codecs->progressive->region); region16_init(&clippingRects); for (i = 0; i < region->numRects; i++) { rect = &(region->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < region->numTiles; i++) { tile = region->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; nXSrc = nXDst - (cmd->left + tile->x); nYSrc = nYDst - (cmd->top + tile->y); freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_SurfaceCommand_RemoteFX(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; xfGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return ERROR_INTERNAL_ERROR; if (!freerdp_client_codecs_prepare(surface->codecs, FREERDP_CODEC_REMOTEFX, surface->width, surface->height)) return ERROR_INTERNAL_ERROR; if (!(message = rfx_process_message(surface->codecs->rfx, cmd->data, cmd->length))) { WLog_ERR(TAG, "Failed to process RemoteFX message"); return ERROR_INTERNAL_ERROR; } region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&surface->invalidRegion, &surface->invalidRegion, &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(surface->codecs->rfx, message); region16_uninit(&clippingRects); if (!xfc->inGfxFrame) xf_UpdateSurfaces(xfc); return CHANNEL_RC_OK; }
int gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd) { int j; UINT16 i; RFX_RECT* rect; RFX_TILE* tile; int nXDst, nYDst; int nWidth, nHeight; int nbUpdateRects; RFX_MESSAGE* message; gdiGfxSurface* surface; REGION16 updateRegion; RECTANGLE_16 updateRect; RECTANGLE_16* updateRects; REGION16 clippingRects; RECTANGLE_16 clippingRect; freerdp_client_codecs_prepare(gdi->codecs, FREERDP_CODEC_REMOTEFX); surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId); if (!surface) return -1; message = rfx_process_message(gdi->codecs->rfx, cmd->data, cmd->length); if (!message) return -1; region16_init(&clippingRects); for (i = 0; i < message->numRects; i++) { rect = &(message->rects[i]); clippingRect.left = cmd->left + rect->x; clippingRect.top = cmd->top + rect->y; clippingRect.right = clippingRect.left + rect->width; clippingRect.bottom = clippingRect.top + rect->height; region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; updateRect.left = cmd->left + tile->x; updateRect.top = cmd->top + tile->y; updateRect.right = updateRect.left + 64; updateRect.bottom = updateRect.top + 64; region16_init(&updateRegion); region16_intersect_rect(&updateRegion, &clippingRects, &updateRect); updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects); for (j = 0; j < nbUpdateRects; j++) { nXDst = updateRects[j].left; nYDst = updateRects[j].top; nWidth = updateRects[j].right - updateRects[j].left; nHeight = updateRects[j].bottom - updateRects[j].top; freerdp_image_copy(surface->data, surface->format, surface->scanline, nXDst, nYDst, nWidth, nHeight, tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0, NULL); region16_union_rect(&(gdi->invalidRegion), &(gdi->invalidRegion), &updateRects[j]); } region16_uninit(&updateRegion); } rfx_message_free(gdi->codecs->rfx, message); if (!gdi->inGfxFrame) gdi_OutputUpdate(gdi); return 1; }